Cuda 如何将自写类(包括动态内存)发送到内核并返回?

Cuda 如何将自写类(包括动态内存)发送到内核并返回?,cuda,Cuda,我想用CUDA在3D对象中进行光散射模拟,它类似于光线跟踪。所以我需要一个向量类 我试图把一个代表我光子的类带到设备上。此类包括一个动态分配向量类(自写)。它不一定是动态的,但在另一种情况下我也会遇到同样的问题 问题是,如果我试图修改内核中的向量,就会出现未指定的启动失败 我认为这也可能是复制构造函数的问题,或者其他问题。我有一段时间没有编写C++/CUDA 我使用的GTX 480具有计算能力2.0和CUDA 5.0 这是我的主要观点: #include "photon.cuh" #includ

我想用CUDA在3D对象中进行光散射模拟,它类似于光线跟踪。所以我需要一个向量类

我试图把一个代表我光子的类带到设备上。此类包括一个动态分配向量类(自写)。它不一定是动态的,但在另一种情况下我也会遇到同样的问题

问题是,如果我试图修改内核中的向量,就会出现未指定的启动失败

我认为这也可能是复制构造函数的问题,或者其他问题。我有一段时间没有编写C++/CUDA

我使用的GTX 480具有计算能力2.0和CUDA 5.0

这是我的主要观点:

#include "photon.cuh"
#include "Container/vector3f.cu"

// Device code (Kernel, GPU)
__global__ void Sim(photon * l_x){
    l_x->vec->m_x = l_x->vec->m_x +1;
    l_x->vec->m_y = l_x->vec->m_y +1;
    l_x->vec->m_z = l_x->vec->m_z +1;
}

// Host Code (CPU)
int main(int argc, char** argv)
{
    photon *h_x,*d_x,*h_x2;

    h_x = new photon();
    //h_x->vec = new vector3f();
    h_x->vec->m_x = 1;
    h_x->vec->m_y = 2;
    h_x->vec->m_z = 3;

    std::cout << "Malloc" << std::endl;
    h_x2 = (photon*)malloc(sizeof(photon));
    cudaMalloc((void**)&d_x,sizeof(photon));

    std::cout << "Cpy h-d" << std::endl;
    cudaMemcpy(d_x,h_x,sizeof(photon),cudaMemcpyHostToDevice);
    cudaError_t Err = cudaGetLastError();
    if ( cudaSuccess != Err )
        std::cout << cudaGetErrorString (Err) << std::endl;

    std::cout << "Sim" << std::endl;
    Sim<<<1, 1>>>(d_x);
    cudaThreadSynchronize();

    Err = cudaGetLastError();
    if ( cudaSuccess != Err )
        std::cout << cudaGetErrorString (Err) << std::endl;

    std::cout << "CPY back" << std::endl;
    cudaMemcpy(h_x2, d_x, sizeof(photon), cudaMemcpyDeviceToHost);

    std::cout << h_x2->vec->m_x << std::endl;
    std::cout << h_x2->vec->m_y << std::endl;
    std::cout << h_x2->vec->m_z << std::endl;

    cudaFree(d_x);
    return 0;
}
class vector3f {
public:
    float m_x;
    float m_y;
    float m_z;

__host__ __device__ vector3f(float l_x, float l_y, float l_z){
        this->m_x = l_x;
        this->m_y = l_y;
        this->m_z = l_z;}
__host__ __device__ vector3f(const vector3f& l_vector){
        this->m_x = l_vector.m_x;
        this->m_y = l_vector.m_y;
        this->m_z = l_vector.m_z;}
__host__ __device__ vector3f(){
        this->m_x = 0;
        this->m_y = 0;
        this->m_z = 0;}};
(.cu)

最后是向量类:

#include "photon.cuh"
#include "Container/vector3f.cu"

// Device code (Kernel, GPU)
__global__ void Sim(photon * l_x){
    l_x->vec->m_x = l_x->vec->m_x +1;
    l_x->vec->m_y = l_x->vec->m_y +1;
    l_x->vec->m_z = l_x->vec->m_z +1;
}

// Host Code (CPU)
int main(int argc, char** argv)
{
    photon *h_x,*d_x,*h_x2;

    h_x = new photon();
    //h_x->vec = new vector3f();
    h_x->vec->m_x = 1;
    h_x->vec->m_y = 2;
    h_x->vec->m_z = 3;

    std::cout << "Malloc" << std::endl;
    h_x2 = (photon*)malloc(sizeof(photon));
    cudaMalloc((void**)&d_x,sizeof(photon));

    std::cout << "Cpy h-d" << std::endl;
    cudaMemcpy(d_x,h_x,sizeof(photon),cudaMemcpyHostToDevice);
    cudaError_t Err = cudaGetLastError();
    if ( cudaSuccess != Err )
        std::cout << cudaGetErrorString (Err) << std::endl;

    std::cout << "Sim" << std::endl;
    Sim<<<1, 1>>>(d_x);
    cudaThreadSynchronize();

    Err = cudaGetLastError();
    if ( cudaSuccess != Err )
        std::cout << cudaGetErrorString (Err) << std::endl;

    std::cout << "CPY back" << std::endl;
    cudaMemcpy(h_x2, d_x, sizeof(photon), cudaMemcpyDeviceToHost);

    std::cout << h_x2->vec->m_x << std::endl;
    std::cout << h_x2->vec->m_y << std::endl;
    std::cout << h_x2->vec->m_z << std::endl;

    cudaFree(d_x);
    return 0;
}
class vector3f {
public:
    float m_x;
    float m_y;
    float m_z;

__host__ __device__ vector3f(float l_x, float l_y, float l_z){
        this->m_x = l_x;
        this->m_y = l_y;
        this->m_z = l_z;}
__host__ __device__ vector3f(const vector3f& l_vector){
        this->m_x = l_vector.m_x;
        this->m_y = l_vector.m_y;
        this->m_z = l_vector.m_z;}
__host__ __device__ vector3f(){
        this->m_x = 0;
        this->m_y = 0;
        this->m_z = 0;}};

潜在的问题是,您在任何地方实例化
光子
类的唯一时间是在主机上,并且您正在将该主机实例直接复制到设备上。这意味着设备代码正试图取消引用GPU上的主机指针,这是非法的,并且会产生您看到的运行时错误。CUDA API不做任何形式的魔法深度复制,因此您必须自己管理它

显而易见的解决方案是重新设计
photon
类,以便
vec
通过值而不是引用进行存储。然后整个问题就消失了(GPU上的性能会更好,因为在内存访问过程中删除了一级指针间接寻址)

如果您一心想让指针指向
vec
,请重新设计构造函数,使其从内存池中获取指针,并为构造分配设备池。如果将设备指针传递给构造函数,则生成的实例将具有指向有效设备内存的指针