2013-04-26 72 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

相关问题