lambda - CUDA Thrust shortcut math functions -
is there way automatically wrap cuda math function in functor 1 can apply thrust::transform without having write functor manually? functionality (i gather) std::function provides?
thrust::placeholders doesn't seem math functions. std::function doesn't seem available.
example code:
#include <thrust/transform.h> #include <thrust/device_vector.h> #include <iostream> #include <functional> #include <math.h> struct myfunc{ __device__ double operator()(double x,double y){ return hypot(x,y); } }; int main(){ double x0[10] = {3.,0.,1.,2.,3.,4.,5.,6.,7.,8.}; double y0[10] = {4.,0.,1.,2.,3.,4.,5.,6.,7.,8.}; thrust::device_vector<double> x(x0,x0+10); thrust::device_vector<double> y(y0,y0+10); thrust::device_vector<double> r(10); (int i=0;i<10;i++) std::cout << x0[i] <<" "; std::cout<<std::endl; (int i=0;i<10;i++) std::cout << y0[i] <<" "; std::cout<<std::endl; // works: thrust::transform(x.begin(),x.end(),y.begin(),r.begin(), myfunc()); // doesn't compile: using namespace thrust::placeholders; thrust::transform(x.begin(),x.end(),y.begin(),r.begin(), hypot(_1,_2)); // nor this: thrust::transform(x.begin(),x.end(),y.begin(),r.begin(), std::function<double(double,double)>(hypot)); (int i=0;i<10;i++) std::cout << r[i] <<" "; std::cout<<std::endl; }
converting comment answer:
as @jaredhoberock stated, there no automatic way achieve want. there syntactic / typing overhead.
one way reduce overhead of writing separate functor (as did my_func) use lambdas. since cuda 7.5 there experimental device lambda feature allows folllowing:
auto h = []__device__(double x, double y){return hypot(x,y);}; thrust::transform(x.begin(),x.end(),y.begin(),r.begin(), h); you need add following nvcc compiler switch compile this:
nvcc --expt-extended-lambda ... another approach convert function functor using following wrapper:
template<typename sig, sig& s> struct wrapper; template<typename r, typename... t, r(&function)(t...)> struct wrapper<r(t...), function> { __device__ r operator() (t&... a) { return function(a...); } }; you use this:
thrust::transform(x.begin(),x.end(),y.begin(),r.begin(), wrapper<double(double,double), hypot>());
Comments
Post a Comment