2013-04-26 75 views
0

在這個簡短的例子中,我試圖通過一個帶有指針的struct init在cuda設備內存中傳遞一個表。複製到主機 - >設備,設備 - >主機似乎可行,但在`_ global _ function nothing works. Values for dA`爲空,我無法更改它們。傳遞一個指向CUDA設備內存的指針init init

我不知道如何從價值A複製到dA。如果我使用這樣的基本表格​​3210它可以工作,但這裏不是我想要做的。這是代碼:

#include<assert.h> 
#include <cuda.h> 
#include <stdio.h> 
#include <iostream> 
#include <iomanip> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <cuda_runtime.h> 
#include <cuda_runtime_api.h> 

#define N 5// side of matrix containing data 

#define checkCudaErrors(val) check((val), #val, __FILE__, __LINE__) 

typedef struct {float re,im;} fcomplex; 

__global__ void kernel(fcomplex * da) 
{ 
    int x = threadIdx.x; 
    int y = threadIdx.y; 
    int i = (N*y) + x; 
    //da[i].re += 2; 
    printf("%f \n",da[i].re); 
} 

int main(int argc, char * argv[]) 
{ 
fcomplex *dA,**A,**B; 

A= (fcomplex **)malloc(N * sizeof(fcomplex*)); 
B=(fcomplex **)malloc(N * sizeof(fcomplex* )); 

for (int i = 0; i < N; i++){ 
    A[i] = (fcomplex *)malloc(N * sizeof(fcomplex)); 
    B[i] = (fcomplex *)malloc(N * sizeof(fcomplex)); 
} 
for (int i = 0; i < N; i++) 
{ for (int d= 0; d < N; d++) 
    { 
    A[i][d].re = i*d; 
    A[i][d].im = i*d; 
    } 
} 

checkCudaErrors(cudaMalloc((void **)&dA, (size_t)(sizeof(fcomplex)*N*N))); 
checkCudaErrors(cudaMemcpy(dA,A,N*N*sizeof(fcomplex),cudaMemcpyHostToDevice)); 

const dim3 blockSize(N,N); 
const dim3 gridSize(1,1); 

kernel<<<gridSize,blockSize>>>(dA); 

checkCudaErrors(cudaThreadSynchronize()); 
checkCudaErrors(cudaGetLastError()); 

checkCudaErrors(cudaMemcpy(B, dA, sizeof(fcomplex)*N*N, cudaMemcpyDeviceToHost)); 
for (int i = 0; i < N; i++) 
{ for (int d= 0; d < N; d++) 
    { 
    printf("%f-%f\n",A[i][d].re,B[i][d].re); 
    printf("%f-%f\n",A[i][d].im,B[i][d].im); 
    } 
} 
//verify(A,B,N); 

free(A); 
free(B); 
cudaFree(dA); 
//cudaFree(dB); 
} 

void verify(fcomplex ** A, fcomplex ** B, int size) 
{ 
for (int i = 0; i < size; i++) 
{ for (int d= 0; d < size; d++) 
    { 
    assert(A[i][d].re==B[i][d].re); 
    } 
} 
printf("Correct!"); 
} 

回答

0

[爲了簡單起見,我只談論一個,但同樣適用於B]

您所分配的N個指針(A)的陣列的CPU,那麼你爲這些指針中的每一個分配一個N值的數組。在GPU上,您已經分配了一個N * N值的平面陣列。

這意味着你的兩個數據結構是不同的,所以你的cudaMemcpy()正在複製垃圾。你有兩個選擇:

  1. 鏡GPU上的間接數據結構 - 這將意味着你將有一個cudaMalloc()爲指針,然後爲每個指針cudaMalloc()。由於需要將內部指針複製到GPU,因此這會變得有點難看,因此您需要分別爲每個內部指針(即行)調用cudaMemcpy()
  2. 就像在GPU上一樣,在CPU上使用平面數據結構。

在CPU和GPU上使用平面數據結構對於所描述的問題最簡單,如果實際問題更復雜,那麼實現深層副本以允許數據結構中的指針不太困難。

或者,您可以映射內存,以便GPU可以直接訪問CPU內存,但這會影響性能,可能不是您想要的。

+0

完美,非常感謝。 :) – volty41 2013-04-30 11:18:27

相關問題