0

在这个简短的示例中,我试图struct在 cuda 设备内存中传递一个带有 init 指针的表。复制到主机-> 设备,设备-> 主机似乎有效,但在`_ global _ function nothing works. Values fordA` 中为空,我无法更改它们。

我不知道如何将值从Ato 复制到dA. 如果我使用这样的基本表, fcomplex A[N][N]它可以工作,但这不是我想要做的。这是代码:

#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!");
}
4

1 回答 1

0

[为简单起见,我只谈论A,但同样适用于B]

在 CPU 上,您分配了一个包含 N 个指针 (A) 的数组,然后为每个指针分配一个包含 N 个值的数组。在 GPU 上,您分配了 N*N 值的平面数组。

这意味着您的两个数据结构不同,因此您cudaMemcpy()正在复制垃圾。你有两个选择:

  1. 镜像 GPU 上的间接数据结构 - 这意味着您将有一个cudaMalloc()用于指针,然后cudaMalloc()每个指针都有一个。这有点难看,因为您需要将内部指针复制到 GPU,并且您需要cudaMemcpy()单独调用每个内部指针(即行)。
  2. 在 CPU 上使用平面数据结构,就像在 GPU 上一样。

对于您描述的问题,在 CPU 和 GPU 上使用平面数据结构将是最简单的,如果您的实际问题更复杂,那么实现深度复制以允许数据结构内的指针并不难。

或者,您可以映射内存,以便 GPU 可以直接访问 CPU 内存,但这会影响性能并且可能不是您想要的。

于 2013-04-26T11:31:25.833 回答