2016-06-20 60 views
0

我在.CU文件如何用结构来工作的内部结构CUDA中

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对象没有一个固定的数。

+5

这个话题已经覆盖了很多次,这就是所谓的深拷贝,例如看看[这里](http://stackoverflow.com/questions/16024087/copy-an-object-to-device/16024373# 16024373) –

+0

@RobertCrovella感谢您的链接。我试过了,但是现在我的程序在帖子建议添加的第一个cudaMemcpy上崩溃了。我用添加的代码修改了我的问题。你能告诉我我做错了什么吗?谢谢。 –

回答

1

您分配了CudaPortfolio结构,它有一个int和一个CudaLeg指针的空间。但是你不分配的什么CudaLeg点。所以,当您尝试访问它,它崩溃的空间。

如何解决它:如果你是o只要有1个CudaLeg,你可以放下指针,然后在CudaPortfolio中放置CudaLeg腿。如果你将有固定数量的CudaLeg对象,你可以在CudaPortfolio里面有例如“CudaLeg [5]腿”。如果您没有固定数量的CudaLeg对象,并且希望保持它现在的状态,那么您需要针对多条腿进行额外的malloc并将其分配给每个组合。查看Robert Crovella在评论中发布的链接,了解它是如何完成的。

0

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