如何在Cuda中使用struct inside struct

时间:2016-06-20 11:30:03

标签: c++ c struct cuda

我的.cu文件中有以下(简化)代码

typedef struct
{
    int leg_id;
    int contract_id;
} CudaLeg;

typedef struct
{
    CudaLeg* legs;
    int no_legs;
} CudaPortfolio;

extern "C"
__global__ void kernel(CudaPortfolio* o_portfolios_cuda, const int no_portfolios)
{
//    fill o_portfolios_cuda with data
}

void cudaFunction(CudaPortfolio* o_portfolios, unsigned long long no_portfolios)
{
    CudaPortfolio* o_portfolios_cuda;
    cudaMalloc((void **)& o_portfolios_cuda, sizeof(CudaPortfolio) * no_portfolios);

    kernel<<<32, 32>>>(o_portfolios_cuda, no_portfolios);

    cudaMemcpy(o_portfolios, o_portfolios_cuda, sizeof(CudaPortfolio) * no_portfolios, cudaMemcpyDeviceToHost);

    //printf below works
    printf("CPU no legs strike output portfolio: %d\n", o_portfolios[0].no_legs);
    //printf below crashes the program
    printf("CPU Leg 1 multiplier output portfolio: %d\n", o_portfolios[0].legs[0].multiplier);

    cudaFree(o_portfolios_cuda);
}

GPU是GTX580,sm2.0。 GPU可以与o_portfolios_cuda一起使用,并用数据填充并使用它进行计算。 o_portfolios [0] .no_legs的第一个printf返回正确的函数。但是当我尝试访问某些组合段(o_portfolios [0] .legs [0] .multiplier)时,程序崩溃了。我有什么想法可以解决这个问题吗?谢谢。

@Robert Crovella我已经尝试过类似的东西,但它没有用。我再次尝试并添加了

    CudaLeg* o_portfolios_legs_cuda;
    cudaMalloc((void **)& o_portfolios_legs_cuda, sizeof(CudaLeg));
    cudaMemcpy(o_portfolios_legs_cuda, o_portfolios->legs, sizeof(CudaLeg), cudaMemcpyHostToDevice);
    cudaMemcpy(&(o_portfolios_cuda->legs), &o_portfolios_legs_cuda, sizeof(CudaLeg *), cudaMemcpyHostToDevice);

但是现在程序在我刚添加的第3行崩溃了(cudaMemcpy(o_portfolios_legs_cuda,...)

@MarkoR CudaLeg对象没有固定的数字。

2 个答案:

答案 0 :(得分:1)

您正在为CudaPortfolio结构分配空间,该结构有一个int和一个CudaLeg指针。但是你没有为CudaLeg指出的空间分配空间。因此,当您尝试访问它时,它会崩溃。

如何修复它:如果你只有1个CudaLeg,你可以放下指针,只在CudaPortfolio中有CudaLeg腿。如果你将拥有固定数量的CudaLeg对象,你可以拥有例如&#34; CudaLeg [5] leg&#34;在CudaPortfolio里面。如果您没有固定数量的CudaLeg对象,并希望保持现在的状态,则需要为腿数做额外的malloc并将其分配给每个组合。请参阅评论中Robert Crovella发布的链接,了解其完成情况。

答案 1 :(得分:0)

当您指向某个设备内存地址指针legs到主机内存时,您还需要将指针更改为主机地址,该地址存储原始设备数据的主机副本。