【问题标题】:CUDA: Host memory pointers not copied to device memoryCUDA:主机内存指针未复制到设备内存
【发布时间】:2011-11-16 04:09:54
【问题描述】:

我们定义了以下结构

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 代码验证的那样,数据已正确编组。

但是,由于内核中的行 purchaseorders[i].SetValue3(j,1.0) 使应用程序崩溃,Value3(双精度数组)似乎没有复制到设备内存中。

我应该怎么做才能解决它?

当应用程序崩溃时,控制台窗口刚刚关闭。我可以使用什么调试技术来获取一些有意义的消息?

【问题讨论】:

    标签: cuda


    【解决方案1】:

    Value1Value3 是指针。在引用主机数据的hostPurchaseOrders 中,这些指针指向主机内存中的位置。

    当您使用cudaMallocdevPurchaseOrders 分配设备内存时,内存仅分配给结构和其中的指针。当您将hostPurchaseOrders 复制到devPurchaseOrders 时,您只复制了Value1 和Value3 字段中的内存地址。由于它们指向主机内存中的某个位置,因此无法从设备成功访问该位置。

    主机内存指针不能像上面那样直接复制到设备内存。您需要为每个主机指针手动分配一个设备位置,将值从主机复制到设备,然后在设备结构的Value1Value3 指针中设置此位置。

    这非常混乱。考虑重组您的主机数据,以便您可以以简单的方式从主机复制到设备。

    【讨论】:

      猜你喜欢
      • 2015-03-11
      • 2014-08-30
      • 2012-11-04
      • 1970-01-01
      • 2016-07-25
      • 2017-03-23
      • 2013-06-06
      • 1970-01-01
      • 2014-12-07
      相关资源
      最近更新 更多