gpt4 book ai didi

c - 传递带有指向 CUDA 设备内存的指针的表 init

转载 作者:行者123 更新时间:2023-11-30 17:52:24 32 4
gpt4 key购买 nike

在这个简短的示例中,我尝试传递一个带有 struct init 的表,其中包含 cuda 设备内存中的指针。复制到主机 -> 设备,设备 -> 主机似乎有效,但在`_global_函数中没有任何作用。 dA` 的值为 null,我无法更改它们。

我不知道如何将值从 A 复制到 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!");
}

最佳答案

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

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

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

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

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

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

关于c - 传递带有指向 CUDA 设备内存的指针的表 init,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16233566/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com