作为推力迭代器CUDA的参数

我正在尝试使用CUDA :: Thurst迭代器来实现在GPU上运行的ODE求解器例程,以解决GPU中的一堆方程,转到细节,这里是一小段代码:

#include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  __host__ __device__ float f(float x, float y) { return cos(y)*sin(x); } struct euler_functor { const float h; euler_functor(float _h) : h(_h) {}; __host__ __device__ float operator()( float(*f)(double,double),const float& x, const float& y) const { y += h * (*f)( x, y ); x += h; } }; int main(void) { // allocate three device_vectors with 10 elements thrust::device_vector X(10); // initilaize to random vaues thrust::generate(X.begin(), X.end(), rand); // apply euler for each element of X thrust::for_each(X.begin(),X.end(),euler_functor(f,0.0,X)); // print the values for(int i = 0; i < 10; i++) std::cout<< X[i]<< std::endl; } 

但是当我编译

nvcc euler.cu -o euler.x -lm发生以下错误:

  lala.cu(29): error: explicit type is missing ("int" assumed) lala.cu(29): error: expected a ";" lala.cu(33): error: expression must be a modifiable lvalue lala.cu(34): error: expression must be a modifiable lvalue lala.cu(35): warning: missing return statement at end of non-void function "euler_functor::operator()" lala.cu(46): error: no suitable constructor exists to convert from "float (float, float)" to "euler_functor" lala.cu(46): error: expected a ")" 

似乎不可能按照我尝试的方式使用函数指针?

更好地实现Euler过程并使用迭代器运行它的sugestions将非常感激。

前一种方法是在兼顾性和性能之间做出了很好的折衷吗?

希望对我来说理想的解决方案是能够定义一个指向以下函数的指针数组:

 typedef int (*foo_ptr_t)( int ); foo_ptr_t foo_ptr_array[2]; int f1( int ); int f2( int ); foo_ptr_array[0] = f1; foo_ptr_array[1] = f2; foo_ptr_array[0]( 1 ); 

将foo_ptr_array作为参数传递给euler仿函数。 可能吗?

谢谢你的回答。

可行的改进:

在我尝试下面的方法时,是否可以将一组耦合微分方程定义为元组上的函数? 我可以从数字方法中获得一些错误信息吗?

这将是

最后,您要求在主机代码中使用__device__函数参数,然后将其作为(函数)指针传递给最终(在引擎盖下)由推力生成的内核参数。

在主机代码中获取__device__函数参数的地址是非法的 ,因此以这种方式将__device__函数指针作为参数传递将不起作用。

可以通过创建额外的__device__变量(指针)来在设备上存储函数指针来解决这个问题。 然后使用cudaGetSymbolAddress构建一个指向函数指针的表。 这将需要运行前驱内核来设置设备上的函数指针。 看起来相当混乱。

参数化仿函数以根据参数选择设备函数可能更简单。 点击这个:

  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  __host__ __device__ float f1(float x) { return sinf(x); } __host__ __device__ float f2(float x) { return cosf(x); } struct euler_functor { unsigned h; euler_functor(unsigned _h) : h(_h) {}; __host__ __device__ void operator()(float &y) const { if (h == 1) y = f1(y); else if (h == 2) y = f2(y); } }; int main(void) { const unsigned N = 8; // allocate three device_vectors with 10 elements thrust::device_vector X(N); // initilaize to random vaues thrust::sequence(X.begin(), X.end(), 0.0f, (float)(6.283/(float)N)); // apply euler for each element of X thrust::for_each(X.begin(),X.end(),euler_functor(1)); // print the values for(int i = 0; i < N; i++) std::cout<< X[i]<< std::endl; std::cout << "******************" << std::endl; thrust::sequence(X.begin(), X.end(), 0.0f, (float)(6.283/(float)N)); // apply euler for each element of X thrust::for_each(X.begin(),X.end(),euler_functor(2)); // print the values for(int i = 0; i < N; i++) std::cout<< X[i]<< std::endl; }