如何与CUDA中的结构内部结构一起工作

How to work with struct inside struct in Cuda

本文关键字:结构 内部 一起 工作 CUDA      更新时间:2023-10-16

我在.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: %dn", o_portfolios[0].no_legs);
    //printf below crashes the program
    printf("CPU Leg 1 multiplier output portfolio: %dn", o_portfolios[0].legs[0].multiplier);
    cudaFree(o_portfolios_cuda);
}

GPU是GTX580,SM2.0。GPU可以与O_PortFolios_cuda一起使用,并用数据填充并对其进行计算。O_PortFolios [0]的第一个printf。no_legs返回了正确的功能。但是,当我尝试访问一些投资组合腿(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);

但是现在该程序在第三行上崩溃了,我刚刚添加了(cudamemcpy(o_portfolios_legs_cuda,...)

@markor cudaleg对象没有固定的数字。

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

如何修复它:如果您只有1个Cudaleg,则可以放下指针,而CudaportFolio中只有Cudaleg腿。如果您要拥有固定数量的Cudaleg对象,则可以在CudaportFolio内部使用" Cudaleg [5]腿"。如果您没有固定数量的Cudaleg对象,并且希望保持现行状态,则需要对腿部数量进行额外的Malloc并将其分配给每个投资组合。请参阅评论中罗伯特·克罗维拉(Robert Crovella)在评论中发布的链接。

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