我们有以下结构定义
typedef struct PurchaseOrder
{
char* Value1;
double Value2;
double* Value3;
int Value3Length;
__device__ int GetValue3Length() { return Value3Length; }
__device__ double GetValue3(int i) { return Value3[i]; }
__device__ void SetValue3(int i, double value) { Value3[i] = value; }
};
将PurchaseOrder数据(结构数组)从C#应用程序编组到以下C dll函数中
int RunMonteCarlo(PurchaseOrder *hostPurchaseOrders, int length) {
PurchaseOrder *devPurchaseOrders;
// display the results
for (int i = 0; i < length; i++)
{
//printf("\n\nAddress: %u",hostPurchaseOrders+i);
printf("\n\nIndex: %d", i);
printf("\nValue1: %s",(hostPurchaseOrders+i)->Value1);
printf("\nValue2: %f",(hostPurchaseOrders+i)->Value2);
for(int j = 0; j < (hostPurchaseOrders+i)->Value3Length; j++)
{
printf("\nValue3[%d]: %fl", j, (hostPurchaseOrders+i)->Value3[j]);
}
}
// allocate the memory on the GPU
HANDLE_ERROR( cudaMalloc( (void**)&devPurchaseOrders, length * sizeof(PurchaseOrder) ) );
// copy the array 'PurchaseOrder' to the GPU
HANDLE_ERROR( cudaMemcpy( devPurchaseOrders, hostPurchaseOrders, length * sizeof(PurchaseOrder), cudaMemcpyHostToDevice ) );
// Run the kernel code
MonteCarloKernel<<<60,32>>>( devPurchaseOrders, length);
// copy the array 'PurchaseOrders' back from the GPU to the CPU
HANDLE_ERROR( cudaMemcpy(hostPurchaseOrders, devPurchaseOrders, length * sizeof(PurchaseOrder), cudaMemcpyDeviceToHost ) );
// free the memory allocated on the GPU
HANDLE_ERROR( cudaFree( devPurchaseOrders ) );
return 0;
}
__global__ void MonteCarloKernel(PurchaseOrder *purchaseorders, long length) {
int i = threadIdx.x + blockIdx.x * blockDim.x;
int stride = blockDim.x * gridDim.x;
while (i < length)
{
purchaseorders[i].SetAAUS(1.11);
for (int j=0; j < purchaseorders[i].GetValue3Length(); j++)
{
//purchaseorders[i].SetValue3(j,1.0);
}
i += stride;
}
}
正确编组数据,并在开头用printf代码验证。
但是,Value3(double数组)似乎没有复制到设备内存中,因为内核中的line purchaseorders [i] .SetValue3(j,1.0)崩溃了应用程序。
我该怎么做才能解决它?
当应用程序崩溃时,控制台窗口刚刚关闭。我可以用什么调试技术来获取一些有意义的消息?
答案 0 :(得分:2)
Value1
和Value3
是指针。在引用主机数据的hostPurchaseOrders
中,这些指针指向主机内存中的位置。
使用devPurchaseOrders
为cudaMalloc
分配设备内存时,内存仅分配给结构及其内部的指针。将hostPurchaseOrders
复制到devPurchaseOrders
时,只复制了Value1和Value3字段中的内存地址。由于它们指向主机内存中的某个位置,因此无法从设备成功访问此位置。
主机内存指针不能像上面那样直接复制到设备内存中。您需要为每个主机指针手动分配设备位置,将值从主机复制到设备,然后在设备结构的Value1
和Value3
指针中设置此位置。
这非常凌乱。考虑重构主机数据,以便您可以以简单的方式从主机复制到设备。