RcppParallel no matching function for call to 'transform' - c++

I have a package posted on CRAN which uses multiple cores through the RcppParallel framework. It has the problem being installed on r-devel-linux-x86_64-fedora-clang and r-patched-solaris-x86. I get the following error messages (there are couple of similar messages related to std::transform so I present just one of them for brevity):
1.For the 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.For the 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)
^
Here is the code for the function where std::tansform and std::exp functions have been called:
// 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);
}
My descriptions file includes SystemRequirements: GNU make
My makevars file has the following flags
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()")
Please help me to figure out how to resolve the error. Will be very great full for help!

I have found a strange solution. The idea is to make the following wrapper function:
double exp_parallel(double x)
{
return std::exp(x);
}
Then I substitute exp with exp_parallel yielding:
// 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);
}
};
Maybe the reason is that some systems can't distinguish between std::exp and Rcpp::exp functions.

Related

thread not working for function with template arguments

I am trying to implement multithreaded merge sort, but my attempt is fails to compile. Here is my code :
template <class RandomAccessIterator>
void merge_sort (RandomAccessIterator begin,RandomAccessIterator end)
{
int N = end - begin;
int N1,N2;
if (N == 1)
return;
RandomAccessIterator mid = begin + (end-begin)/2;
// merge_sort (begin,mid); // this is OK
// merge_sort (mid,end); // this is OK
thread t1 (merge_sort,begin,mid); // error
thread t2 (merge_sort,mid,end); // error
t1.join ();
t2.join ();
N1 = mid - begin;
N2 = end - mid;
merge (begin,N1,mid,N2);
}
Errors Messages from gcc (g++ -std=c++11 merge-multithread.cpp):
merge-multithread.cpp: In instantiation of ‘void merge_sort(RandomAccessIterator, RandomAccessIterator) [with RandomAccessIterator = int*]’:
merge-multithread.cpp:76:25: required from here
merge-multithread.cpp:60:33: error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, int*&, int*&)’
thread t1 (merge_sort,begin,mid);
^
In file included from merge-multithread.cpp:4:0:
/usr/include/c++/5.2.0/thread:133:7: note: candidate: template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...)
thread(_Callable&& __f, _Args&&... __args)
^
/usr/include/c++/5.2.0/thread:133:7: note: template argument deduction/substitution failed:
merge-multithread.cpp:60:33: note: couldn't deduce template parameter ‘_Callable’
thread t1 (merge_sort,begin,mid);
^
In file included from merge-multithread.cpp:4:0:
/usr/include/c++/5.2.0/thread:128:5: note: candidate: std::thread::thread(std::thread&&)
thread(thread&& __t) noexcept
^
/usr/include/c++/5.2.0/thread:128:5: note: candidate expects 1 argument, 3 provided
/usr/include/c++/5.2.0/thread:122:5: note: candidate: std::thread::thread()
thread() noexcept = default;
merge_sort itself is a function template; to get the address of one of the instantiated functions you need to specify all template arguments:
thread t1 (&merge_sort<RandomAccessIterator>,begin,mid);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
or use a static cast:
thread t1 (static_cast<void(*)(RandomAccessIterator,RandomAccessIterator)>(&merge_sort),begin,mid);
...or use a lambda expression and let the compiler automatically deduce the types of arguments:
thread t1 ([begin,mid]{merge_sort(begin, mid);});

call of overloaded 'swap(char&, char&)' is ambiguous

I can't figure out what is ambiguous about swap(arr[i++],arr[n--]); below. Please educate me on my wrongful ways.
#include <iostream>
#include <string>
template <typename T> void swap ( T & a, T & b )
{
T temp = b;
b = a;
a = temp;
}
template <typename T> void reverse_array ( T * arr, size_t n )
{
size_t i = 0;
while (i < n) swap(arr[i++],arr[n--]); // problem line
}
int main ()
{
char mystr [] = "Obama smokes";
reverse_array(mystr, sizeof(mystr)/sizeof(char));
return 0;
}
codepad has an implicit using namespace std;, which is a really bad idea and makes your swap conflict with std::swap. You can use ::swap instead, but not before fixing your bounds problem by passing sizeof mystr - 2 instead of sizeof(mystr)/sizeof(char).
As #minitech mentions in his answer, the problem is because of the implicit namespace declaration, e.g. using namespace std;
With that I get the following error, which shows that the conflict is with std::swap:
100%] Building CXX object CMakeFiles/csi_projects.dir/main.cpp.o
/home/vsnyc/ClionProjects/main.cpp: In instantiation of ‘void reverse_array(T*, size_t) [with T = char; size_t = long unsigned int]’:
/home/vsnyc/ClionProjects/main.cpp:151:52: required from here
/home/vsnyc/ClionProjects/main.cpp:144:43: error: call of overloaded ‘swap(char&, char&)’ is ambiguous
while (i < n) { swap(arr[i++],arr[n--]); } // problem line
^
/home/vsnyc/ClionProjects/main.cpp:144:43: note: candidates are:
/home/vsnyc/ClionProjects/main.cpp:134:28: note: void swap(T&, T&) [with T = char]
template <typename T> void swap ( T & a, T & b )
^
In file included from /usr/include/c++/4.8/bits/stl_pair.h:59:0,
from /usr/include/c++/4.8/bits/stl_algobase.h:64,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from /home/vsnyc/ClionProjects/main.cpp:1:
/usr/include/c++/4.8/bits/move.h:166:5: note: void std::swap(_Tp&, _Tp&) [with _Tp = char]
swap(_Tp& __a, _Tp& __b)
^

C++ source code compilation error in MinGW with std::copy function

I'm trying to compile the following C++ code and getting some errors. Am I missing some libraries? I'm using MinGW on Windows 7 64 bit.
//ch 18
#include <algorithm>
class vector{
int sz;
double* elem;
public:
vector(const vector&);
};
vector:: vector(const vector& arg)
:sz{arg.sz}, elem{new double[arg.sz]}
{
std::copy(arg,arg.sz,elem);
}
Here is the error messages.
$ g++ ch18copy.cpp -std=c++11 -o ch18copy
ch18copy.cpp: In copy constructor 'vector::vector(const vector&)':
ch18copy.cpp:15:28: error: no matching function for call to 'copy(const vector&,
const int&, double*&)'
std::copy(arg,arg.sz,elem);
^
ch18copy.cpp:15:28: note: candidate is:
In file included from c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\algorithm:61:0,
from ch18copy.cpp:3:
c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_algobase.h:450:5: note: temp
late<class _II, class _OI> _OI std::copy(_II, _II, _OI)
copy(_II __first, _II __last, _OI __result)
^
c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_algobase.h:450:5: note: te
mplate argument deduction/substitution failed:
ch18copy.cpp:15:28: note: deduced conflicting types for parameter '_II' ('vect
or' and 'int')
std::copy(arg,arg.sz,elem);
^
It looks like you aren't using the right parameters for std::copy.
From http://www.cplusplus.com/reference/algorithm/copy/:
template <class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);
From their example:
int myints[]={10,20,30,40,50,60,70};
std::vector<int> myvector (7);
std::copy ( myints, myints+7, myvector.begin() );
So the first two parameters are the start and end of the range you want to copy, and the third parameter is where you want to copy to.
In your case, this would look something like this (disclaimer: didn't test this):
std::copy(arg.elem, arg.elem + arg.sz, elem);

using std::async with template functions

How can I, or, can I, pass a template function to async?
Here is the code:
//main.cpp
#include <future>
#include <vector>
#include <iostream>
#include <numeric>
int
main
()
{
std::vector<double> v(16,1);
auto r0 = std::async(std::launch::async,std::accumulate,v.begin(),v.end(),double(0.0));
std::cout << r0.get() << std::endl;
return 0;
}
Here are the error messages:
^
a.cpp:13:88: note: candidates are:
In file included from a.cpp:1:0:
/usr/include/c++/4.8/future:1523:5: note: template std::future::type> std::async(std::launch, _Fn&&, _Args&& ...)
async(launch __policy, _Fn&& __fn, _Args&&... __args)
^
/usr/include/c++/4.8/future:1523:5: note: template argument deduction/substitution failed:
a.cpp:13:88: note: couldn't deduce template parameter ‘_Fn’
auto r0 = std::async(std::launch::async,std::accumulate,v.begin(),v.end(),double(0.0));
^
In file included from a.cpp:1:0:
/usr/include/c++/4.8/future:1543:5: note: template std::future::type> std::async(_Fn&&, _Args&& ...)
async(_Fn&& __fn, _Args&&... __args)
^
/usr/include/c++/4.8/future:1543:5: note: template argument deduction/substitution failed:
/usr/include/c++/4.8/future: In substitution of ‘template std::future::type> std::async(_Fn&&, _Args&& ...) [with _Fn = std::launch; _Args = {}]’:
a.cpp:13:88: required from here
/usr/include/c++/4.8/future:1543:5: error: no type named ‘type’ in ‘class std::result_of’
The problem is that to pass the second argument to std::async the compiler has to turn the expression &std::accumulate into a function pointer, but it doesn't know which specialization of the function template you want. To a human it's obvious you want the one that can be called with the remaining arguments to async, but the compiler doesn't know that and has to evaluate each argument separately.
As PiotrS.'s answer says, you can tell the compiler which std::accumulate you want with an explicit template argument list or by using a cast, or alternatively you can just use a lambda expression instead:
std::async(std::launch::async,[&] { return std::accumulate(v.begin(), v.end(), 0.0); });
Inside the body of the lambda the compiler performs overload resolution for the call to std::accumulate and so it works out which std::accumulate to use.
You have to disambiguate between possible instantiations by either explicitly passing the template arguments or using static_cast, so:
auto r0 = std::async(std::launch::async
, &std::accumulate<decltype(v.begin()), double>
, v.begin()
, v.end()
, 0.0);
or:
auto r0 = std::async(std::launch::async
, static_cast<double(*)(decltype(v.begin()), decltype(v.end()), double)>(&std::accumulate)
, v.begin()
, v.end()
, 0.0);

Loki's Functor with variadic templates

I have a question about the Functor implementation of the library Loki.
I am doing some changes in order to make it work with variadic templates instead of having lines and lines of template specialization. The problem is that I am trying to use typedef for variadic template and I do not understand my error, that is why I could use some help from experts...
Here is the header file.
I tested it with a simple example:
static void foo()
{
std::cout << "foo !!!" << std::endl;
}
int
main( int argc, const char** argv )
{
Functor<void, void> static_func(foo);
static_func();
}
Which gives me this error
/home/test/src/EntryPoint.cpp:237:17: error: no match for call to ‘(Functor<void, void>) ()’
In file included from /home/test/src/EntryPoint.cpp:231:0:
/home/test/include/FunctorTest.h:217:7: note: candidate is:
/home/test/include/FunctorTest.h:292:16: note: Functor<R, TList>::ResultType Functor<R, TList>::operator()(Functor<R, TList>::MyList&&) const [with R = void; TList = {void}; Functor<R, TList>::ResultType = void; Functor<R, TList>::MyList = variadic_typedef<void>]
/home/test/include/FunctorTest.h:292:16: note: candidate expects 1 argument, 0 provided
/home/test/src/EntryPoint.cpp: At global scope:
/home/test/src/EntryPoint.cpp:234:1: warning: unused parameter ‘argc’ [-Wunused-parameter]
/home/test/src/EntryPoint.cpp:234:1: warning: unused parameter ‘argv’ [-Wunused-parameter]
In file included from /home/test/src/EntryPoint.cpp:231:0:
/home/test/include/FunctorTest.h: In instantiation of ‘FunctorHandler<ParentFunctor, Fun>::ResultType FunctorHandler<ParentFunctor, Fun>::operator()(FunctorHandler<ParentFunctor, Fun>::MyList&&) [with ParentFunctor = Functor<void, void>; Fun = void (*)(); FunctorHandler<ParentFunctor, Fun>::ResultType = void; FunctorHandler<ParentFunctor, Fun>::MyList = variadic_typedef<void>]’:
/home/test/src/EntryPoint.cpp:247:1: required from here
/home/test/include/FunctorTest.h:159:49: error: no matching function for call to ‘forward(FunctorHandler<Functor<void, void>, void (*)()>::MyList&)’
/home/test/include/FunctorTest.h:159:49: note: candidates are:
In file included from /usr/include/c++/4.7/bits/stl_pair.h:61:0,
from /usr/include/c++/4.7/utility:72,
from /home/jean/Lib/vitals/include/CLPair.h:28,
from /home/jean/Lib/vitals/include/CLMap.h:27,
from /home/jean/Lib/vitals/include/HTCmdLineParser.h:27,
from /home/test/include/EntryPoint.h:23,
from /home/test/src/EntryPoint.cpp:22:
/usr/include/c++/4.7/bits/move.h:77:5: note: template<class _Tp> constexpr _Tp&& std::forward(typename std::remove_reference<_From>::type&)
/usr/include/c++/4.7/bits/move.h:77:5: note: template argument deduction/substitution failed:
In file included from /home/test/src/EntryPoint.cpp:231:0:
/home/test/include/FunctorTest.h:159:49: note: cannot convert ‘parms’ (type ‘FunctorHandler<Functor<void, void>, void (*)()>::MyList {aka variadic_typedef<void>}’) to type ‘std::remove_reference<convert_in_tuple<variadic_typedef<void> > >::type& {aka convert_in_tuple<variadic_typedef<void> >&}’