2010-10-05 7 views
1

nous avons le struct suivant définiCUDA: pointeurs de mémoire hôtes non copiées sur un périphérique mémoire

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; } 
}; 

Les données purchaseOrder (groupement de struct) sont formé, de l'application C# dans la fonction dll C suivant

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; 
    } 
} 

Les données sont correctement classées comme vérifiées par le code printf au début.

Cependant, le Value3 (array of double) ne semble pas copié dans la mémoire de l'appareil car les achats en ligne [i] .SetValue3 (j, 1.0) dans le noyau bloquent l'application.

Que dois-je faire pour résoudre le problème?

Lorsque l'application se bloque, les fenêtres de la console se ferment. Quelle technique de débogage pourrais-je utiliser pour obtenir des messages significatifs?

Répondre

2

Value1 et Value3 sont des pointeurs. Dans hostPurchaseOrders, qui fait référence à des données hôte, ces pointeurs pointent vers des emplacements dans la mémoire hôte.

Lorsque vous allouez la mémoire de l'appareil pour devPurchaseOrders en utilisant cudaMalloc, la mémoire n'est allouée que pour les structures et les pointeurs à l'intérieur. Lorsque vous copiez hostPurchaseOrders à devPurchaseOrders, vous avez uniquement copié les adresses de mémoire dans les champs Value1 et Value3. Depuis, ils pointent vers un emplacement dans la mémoire de l'hôte, cet emplacement ne peut pas être accédé avec succès à partir de l'appareil.

Les pointeurs de mémoire hôte ne peuvent pas être copiés directement dans la mémoire de l'appareil comme vous l'avez fait précédemment. Vous devrez allouer manuellement un emplacement de périphérique pour chaque pointeur hôte, y copier les valeurs de l'hôte vers le périphérique, puis définir cet emplacement dans les pointeurs Value1 et Value3 de la structure du périphérique.

Ceci est extrêmement salissant. Envisagez de restructurer les données de votre hôte, de sorte que vous puissiez copier d'un hôte à l'autre d'une manière simple.

Questions connexes