【问题标题】:Passing class object to __global__ kernel将类对象传递给 __global__ 内核
【发布时间】:2013-01-14 17:52:09
【问题描述】:

我想将一个类对象传递给全局内核并在其中执行其成员函数。到目前为止,我所有的努力都没有成功。下面我将详细描述我正在尝试做的事情。

我有像这样实现的 PDE_Parabolic_Num_GPU 类:

class PDE_Parabolic_Num_GPU: public PDE_Parabolic_GPU
 {
  public:
   __host__ __device__ PDE_Parabolic_Num_GPU();
   __host__ __device__ ~PDE_Parabolic_Num_GPU();
   __host__ __device__ Solve();
   __host__ __device__ Setup();
   ...

  //data
  gdd_real*   an;
  gdd_real*   bn;
  gdd_real*   cn;
}

gdd_real 在哪里

struct gdd_real 
{
    double2 val;
        __host__  __device__ gdd_real(double hi, double lo) {val.x = hi; val.y = lo;}
    __host__  __device__ gdd_real(double h){val.x = h; val.y = 0.;}
    __host__  __device__ gdd_real(){};
};

在我的 main() 中,我正在执行通常的 cudaMalloc 和 cudaMemcpy 以便将我的类对象传递给全局内核:

PDE_Parabolic_Num_GPU pdes_host;
PDE_Parabolic_Num_GPU *pdes_dev;
cudaError_t cudaStatus;
cudaStatus = cudaMalloc((void**)&pdes_dev, 1 * sizeof(PDE_Parabolic_Num_GPU));
cudaStatus = cudaMemcpy(pdes_dev, &pdes_host, sizeof(PDE_Parabolic_Num_GPU), cudaMemcpyHostToDevice);
pdegpu<<<1,1>>>(pdes_dev);
cudaStatus = cudaThreadSynchronize();
cudaStatus = cudaMemcpy(&pdes_host, pdes_dev, sizeof(PDE_Parabolic_Num_GPU), cudaMemcpyDeviceToHost);
cudaStatus = cudaThreadExit();
system("pause");

pdegpu内核如下:

__global__ void pdegpu(PDE_Parabolic_Num_GPU *pdes)
{
  pdes->Setup(); //initializes class members an, bn, cn using "new" 
  pdes->Solve();    
}

我的第一个问题:程序在调试过程中在 pdes->Setup() 崩溃;

第二个问题是:如果我将内核更改为使用以下本地对象,则程序在调试期间在 main() 中的 system("pause") 语句后崩溃。

__global__ void pdegpu()
{
      PDE_Parabolic_Num_GPU pdes;  //using local object
      pdes.Setup(); 
      pdes.Solve(); 
}

这是使用 Nsight 进行调试时程序崩溃的两种情况。但是当我在没有调试的情况下运行程序时,第二个版本的 pdegpu(它使用本地对象)在 pdes.Solve() 处崩溃。 谁能帮我解决这些问题? 谢谢你,

【问题讨论】:

  • 您不能在 GPU 代码中使用 new。您必须通过cudaMalloc 在主机上分配它并传入指针。
  • @lethal-guitar... 谁告诉你的?检查this
  • @lethal-guitar:这已经有近三年的时间了。
  • 好吧...我很确定malloc 仍然不可能,所以我假设这也适用于new/delete..
  • 好吧,原来我也错了..嗯,很高兴知道..

标签: c++ cuda


【解决方案1】:

为什么要存储指向gdd_real 的指针?您可以直接将这种类型的对象放在您的类中。这样,您将避免与内存相关的问题。

那么为什么不直接使用:

    //...
    gdd_real   an;
    gdd_real   bn;
    gdd_real   cn;
}

【讨论】:

  • 因为an、bn、cn是gdd_real的数组。例如,我在 Setup 函数中将其初始化为 = new gdd_real[200]。
猜你喜欢
  • 1970-01-01
  • 2015-10-20
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多