CUDA: указатели памяти хоста не скопированы в память устройства - PullRequest
1 голос
/ 06 октября 2010

у нас определена следующая структура

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), похоже, не копируется в память устройства, как покупатель строки [i] .SetValue3 (j, 1.0) в ядревылетает приложение.

Что я должен сделать, чтобы решить его?

При сбое приложения окна консоли просто закрываются.Какую технику отладки я мог бы использовать для получения значимых сообщений?

1 Ответ

2 голосов
/ 17 марта 2011

Value1 и Value3 являются указателями. В hostPurchaseOrders, который относится к данным хоста, эти указатели указывают на места в памяти хоста.

Когда вы выделяете память устройства для devPurchaseOrders, используя cudaMalloc, память выделяется только для структур и указателей внутри них. Когда вы копируете hostPurchaseOrders в devPurchaseOrders, вы копируете только адреса памяти в полях Value1 и Value3. Так как они указывают на какое-то место в памяти хоста, это местоположение не может быть успешно доступно с устройства.

Указатели памяти хоста не могут быть непосредственно скопированы в память устройства, как вы делали выше. Вам нужно будет вручную выделить местоположение устройства для каждого указателя хоста, скопировать значения с хоста на устройство и затем установить это местоположение в указателях Value1 и Value3 структуры устройства.

Это очень грязно. Подумайте о реструктуризации данных вашего хоста, чтобы вы могли скопировать их с хоста на устройство простым способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...