cuda che passa la struttura definita dall’utente a un kernel fallito

Ecco il mio problema Ho la seguente struttura nel mio kernel.h .

 struct __Q_VECTOR__{ double* Data; int Dimension; int Cluster; }; typedef struct __Q_VECTOR__ VQ_VECTOR; 

Nel kernel.cu ho il seguente codice

 int main(void){ int L = 3, //.Data length N = 100; VQ_VECTOR *A, *device_VQ_VECTOR; cudaError_t cudaStatus; A = (VQ_VECTOR*)malloc(N*sizeof(VQ_VECTOR)); for(int i=0; i<N; i++){ VQ_VECTOR a; a.Data = (double*)malloc(L*sizeof(double));; a.Cluster = 1; a.Dimension = L; for(int j=0; j<L; j++) a.Data[j]=i*j; A[i] = a; } //Prinf of all the elements of A for(int i=0; i<2; i++){ printf("\nA[%d]={"); for(int j=0; j<L; j++) printf("%.3f",A[i].Data[j]); printf("}"); } printf("\n\n"); //I Allocate and Copy data from A to device_VQ_VECTORon the GPU memory cudaDeviceReset(); cudaStatus = cudaMalloc((void**)&device_VQ_VECTOR, N*sizeof(VQ_VECTOR)); cudaStatus = cudaMemcpy(device_VQ_VECTOR, A, N*sizeof(VQ_VECTOR), cudaMemcpyHostToDevice); cudaPrintfInit(); testKernel<<>>(device_VQ_VECTOR, N);//to test and see on a sigle thread cudaPrintfDisplay(stdout, true); cudaPrintfEnd(); cudaStatus = cudaGetLastError(); if (cudaStatus != cudaSuccess) { fprintf(stderr, "\n testKernel launch failed: %s\n", cudaGetErrorString(cudaStatus)); return 1; } cudaStatus = cudaMemcpy(A, device_VQ_VECTOR, N*sizeof(VQ_VECTOR), cudaMemcpyDeviceToHost); cudaStatus = cudaGetLastError(); if (cudaStatus != cudaSuccess) { fprintf(stderr, "\n testKernel launch failed: %s\n", cudaGetErrorString(cudaStatus)); return 1; } for(int i=0; i<2; i++){ printf("\nA[%d]={"); for(int j=0; j<L; j++) printf("%.3f",A[i].Data[j]); printf("}"); } cudaFree(device_VQ_VECTOR); return 0; 

}

quando costruisco, a volte non stampa nulla, a volte funziona.
cosa c’è che non va nel mio codice? Può essere causato da

 cudaStatus = cudaMalloc((void**)&device_VQ_VECTOR, N*sizeof(VQ_VECTOR)); cudaStatus = cudaMemcpy(device_VQ_VECTOR, A, N* sizeof(VQ_VECTOR), cudaMemcpyHostToDevice); 

Aiuto per favore!

Questo non può funzionare perché gli array sono allocati separatamente e non copiati nella memoria del dispositivo. È necessario allocarli anche sul dispositivo e fare una copia completa. Per peggiorare le cose, non puoi accedere alla memoria del dispositivo direttamente dal lato host (in modo diverso da cudaMemcpy ), quindi non puoi usare ad esempio cudaMalloc(&device_VQ_VECTOR[i].Data, ...) (si bloccherà).

Ecco un codice di esempio. Per motivi di semplicità, elimina A[i].Data lato host e quindi li ricrea. Non è troppo bello, ma andrà così.

 struct __Q_VECTOR__{ double* Data; int Dimension; int Cluster; }; typedef struct __Q_VECTOR__ VQ_VECTOR; __global__ void testKernel(VQ_VECTOR *X, int N){ int i= blockIdx.x*blockDim.x + threadIdx.x; cuPrintf("\n testKernel entrance by the global threadIdx= %d\n", i); for(int k=0; k>>(device_VQ_VECTOR, N);//to test and see on a sigle thread cudaPrintfDisplay(stdout, true); cudaPrintfEnd(); cudaStatus = cudaGetLastError(); if (cudaStatus != cudaSuccess) { fprintf(stderr, "\n testKernel launch failed: %s\n", cudaGetErrorString(cudaStatus)); return 1; } cudaStatus = cudaMemcpy(A, device_VQ_VECTOR, N*sizeof(VQ_VECTOR), cudaMemcpyDeviceToHost); for(int i = 0; i != N; ++i) { // allocate array, copy data double *array = (double*)malloc(L*sizeof(double)); cudaMemcpy(array, A[i].Data, L*sizeof(double), cudaMemcpyDeviceToHost); // assign new array to A[i] A[i].Data = array; } cudaStatus = cudaGetLastError(); if (cudaStatus != cudaSuccess) { fprintf(stderr, "\n testKernel launch failed: %s\n", cudaGetErrorString(cudaStatus)); return 1; } /* for(int i=0; i<2; i++){ printf("\nA[%d]={", i); for(int j=0; j 

Parte dell'output sarebbe (è enorme, non voglio postare troppo):

 [2, 0]: 3.00, [18, 0]: 19.00, [22, 0]: 23.00, [16, 0]: 17.00, [24, 0]: 25.00, [19, 0]: 20.00, [4, 0]: 5.00, [23, 0]: 24.00, [3, 0]: 4.00, [5, 0]: 6.00, [13, 0]: 14.00, [1, 0]: 2.00, [10, 0]: 11.00, [6, 0]: 7.00, [14, 0]: 15.00, [0, 0]: 1.00, [20, 0]: