我在CRAN上发布了一个软件包,它通过RcppParallel框架使用多个内核。它的问题安装在r-devel-linux-x86_64-fedora-clang和r-patched-solaris-x86上。我收到以下错误消息(有几个与 std::transform 相关的类似消息,因此为了简洁起见,我只提供其中一条(:
1.对于 r-patched-solaris-x86:
ParallelFunctions.cpp: In member function ‘virtual void ParallelVectorExpStruct::operator()(std::size_t, std::size_t)’:
ParallelFunctions.cpp:134:27: error: no matching function for call to ‘transform(RcppParallel::RVector<double>::const_iterator, RcppParallel::RVector<double>::const_iterator, RcppParallel::RVector<double>::iterator, <unresolved overloaded function type>)’
::exp);
^
In file included from /opt/csw/include/c++/5.2.0/algorithm:62:0,
from /home/ripley/R/Lib32/Rcpp/include/RcppCommon.h:63,
from /home/ripley/R/Lib32/RcppArmadillo/include/RcppArmadilloForward.h:26,
from /home/ripley/R/Lib32/RcppArmadillo/include/RcppArmadillo.h:31,
from ParallelFunctions.h:4,
from ParallelFunctions.cpp:1:
/opt/csw/include/c++/5.2.0/bits/stl_algo.h:4164:5: note: candidate: template<class _IIter, class _OIter, class _UnaryOperation> _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation)
transform(_InputIterator __first, _InputIterator __last,
^
/opt/csw/include/c++/5.2.0/bits/stl_algo.h:4164:5: note: template argument deduction/substitution failed:
ParallelFunctions.cpp:134:27: note: couldn't deduce template parameter ‘_UnaryOperation’
::exp);
^
In file included from /opt/csw/include/c++/5.2.0/algorithm:62:0,
from /home/ripley/R/Lib32/Rcpp/include/RcppCommon.h:63,
from /home/ripley/R/Lib32/RcppArmadillo/include/RcppArmadilloForward.h:26,
from /home/ripley/R/Lib32/RcppArmadillo/include/RcppArmadillo.h:31,
from ParallelFunctions.h:4,
from ParallelFunctions.cpp:1:
/opt/csw/include/c++/5.2.0/bits/stl_algo.h:4201:5: note: candidate: template<class _IIter1, class _IIter2, class _OIter, class _BinaryOperation> _OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation)
transform(_InputIterator1 __first1, _InputIterator1 __last1,
^
/opt/csw/include/c++/5.2.0/bits/stl_algo.h:4201:5: note: template argument deduction/substitution failed:
ParallelFunctions.cpp:134:27: note: candidate expects 5 arguments, 4 provided
::exp);
^
2.对于 r-devel-linux-x86_64-fedora-clang:
hpaML.cpp:754:45: warning: explicitly assigning value of variable of type 'Rcpp::NumericVector' (aka 'Vector<14>') to itself [-Wself-assign-overloaded]
mean_ind, sd_ind = sd_ind,
~~~~~~ ^ ~~~~~~
ParallelFunctions.cpp:46:7: error: no matching function for call to 'transform'
std::transform(input.begin() + begin,
^~~~~~~~~~~~~~
/usr/local/bin/../include/c++/v1/algorithm:1955:1: note: candidate template ignored: couldn't infer template argument '_BinaryOperation'
transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
^
/usr/local/bin/../include/c++/v1/algorithm:1945:1: note: candidate function template not viable: requires 4 arguments, but 5 were provided
transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)
^
下面是调用 std::tansform 和 std::exp 函数的函数的代码:
// Parallel exp of vectors
struct ParallelVectorExpStruct : public Worker
{
// source matrix
const RVector<double> input;
// destination matrix
RVector<double> output;
// initialize with source and destination
ParallelVectorExpStruct(const NumericVector input, NumericVector output)
: input(input), output(output) {}
// take the exponents of the range of elements requested
void operator()(std::size_t begin, std::size_t end) {
std::transform(input.begin() + begin,
input.begin() + end,
output.begin() + begin,
::exp);
}
};
// Parallel exponent of vector elements
NumericVector ParallelVectorExp(NumericVector x)
{
// allocate the output matrix
NumericVector output(x.size());
// ParallelVectorPowStruct functor
ParallelVectorExpStruct parallelVectorExpStruct(x, output);
// call parallelFor to do the work
parallelFor(0, x.length(), parallelVectorExpStruct);
// return the output matrix
return (output);
}
我的描述文件包括系统要求:GNU make
我的 makevars 文件具有以下标志
CXX_STD = CXX11
PKG_CXXFLAGS = $(SHLIB_OPENMP_CXXFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
PKG_LIBS += $(shell ${R_HOME}/bin/Rscript -e "RcppParallel::RcppParallelLibs()")
请帮助我弄清楚如何解决错误。将非常非常充分地寻求帮助!
我找到了一个奇怪的解决方案。这个想法是制作以下包装器函数:
double exp_parallel(double x)
{
return std::exp(x);
}
然后我用exp代替exp_parallel得到:
// Parallel exp of vectors
struct ParallelVectorExpStruct : public Worker
{
// source matrix
const RVector<double> input;
// destination matrix
RVector<double> output;
// initialize with source and destination
ParallelVectorExpStruct(const NumericVector input, NumericVector output)
: input(input), output(output) {}
// take the exponents of the range of elements requested
void operator()(std::size_t begin, std::size_t end) {
std::transform(input.begin() + begin,
input.begin() + end,
output.begin() + begin,
::exp_parallel);
}
};
也许原因是某些系统无法区分std::exp和Rcpp::exp函数。