c++ - 用作推力迭代器 CUDA 的参数

标签 c++ c cuda thrust

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

    #include <thrust/device_vector.h>
    #include <thrust/transform.h> 
    #include <thrust/sequence.h>
    #include <thrust/copy.h> 
    #include <thrust/fill.h>
    #include <thrust/replace.h>
    #include <thrust/functional.h>

    #include <thrust/for_each.h>
    #include <thrust/device_vector.h>
    #include <thrust/iterator/zip_iterator.h>


   #include <iostream>
   #include <math.h>


   __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<int> 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 the following errors occurs:

    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 过程并使用迭代器运行它的更好方法的建议将不胜感激。

前一种方法是可分割性和性能之间的良好折衷吗?

最后,希望对我来说理想的解决方案是能够定义一个指向函数的指针数组,例如:

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 作为参数传递给欧拉仿函数。可能吗?

感谢您的回答。

可能的改进:

当我尝试采用以下方法时,是否可以将一组耦合微分方程定义为元组上的仿函数?我能否从解决方案的数值方法中获得一些错误信息?

应该是

最佳答案

最终,您要求在主机代码中获取一个 __device__ 函数参数,然后将其作为(函数)指针传递,最终(在幕后)生成一个内核参数靠推力。

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

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

将仿函数参数化以根据参数选择设备功能可能会更简单。像这样:

   #include <thrust/device_vector.h>
   #include <thrust/transform.h>
   #include <thrust/sequence.h>
   #include <thrust/copy.h>
   #include <thrust/fill.h>
   #include <thrust/replace.h>
   #include <thrust/functional.h>
   #include <thrust/for_each.h>
   #include <thrust/iterator/zip_iterator.h>

   #include <iostream>
   #include <math.h>


   __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<float> 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;

   }

关于c++ - 用作推力迭代器 CUDA 的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21196685/

相关文章:

c++ - 当用户在 C++ 上键入时,如何检查用户的输入?

将 float 数组转换为 char 缓冲区

java - 我应该如何为 JNI 加载 native 库以避免 UnsatisfiedLinkError?

在没有分支的情况下在 CUDA 中进行比较

c++ - gdb/solaris : When attaching to a process, 符号未加载

c++ - 我可以使用 std::vector::operator[] 返回的引用多长时间?

c++ - 从 STL 容器类公开继承时如何使用迭代器类型?

c - 数独:检查 3x3 网格中的重复值

cuda - 如何使用 make_cudaExtent 正确定义 cudaExtent?

c++ - CUDA:Mark Harris 的并行缩减样本不只是对每个线程 block 求和吗?