gpt4 book ai didi

c++ - 在 CUDA 中将动态分配的二维数组从主机复制到设备

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:55:08 39 4
gpt4 key购买 nike

我想将动态分配的二维数组从主机复制到设备以获取其离散傅里叶变换。

我正在使用下面的代码将数组复制到设备

cudaMalloc((void**)&array_d, sizeof(cufftComplex)*NX*(NY/2+1));
cudaMemcpy(array_d, array_h, sizeof(float)*NX*NY, cudaMemcpyHostToDevice);

这适用于静态数组,我从我的 fft 得到了预期的输出。但它不适用于动态数组。经过一番搜索后,我了解到我无法将这样的动态数组从主机复制到设备。所以我找到了这个解决方案。

cudaMalloc((void**)&array_d, sizeof(cufftComplex)*NX*(NY/2+1));
for(int i=0; i<NX; ++i){
cudaMemcpy(array_d+ i*NY, array_h[i], sizeof(float)*NY, cudaMemcpyHostToDevice);
}

但它也没有正确完成任务,因为我从我的 fft 中得到了错误的值。

下面是我的 fft 代码。

cufftPlanMany(&plan, NRANK, n,NULL, 1, 0,NULL, 1, 0,CUFFT_R2C,BATCH);
cufftSetCompatibilityMode(plan, CUFFT_COMPATIBILITY_NATIVE);
cufftExecR2C(plan, (cufftReal*)data, data);
cudaThreadSynchronize();
cudaMemcpy(c, data, sizeof(float)*NX*NY, cudaMemcpyDeviceToHost);

我怎样才能克服这个问题?

编辑

下面是代码

#define NX 4
#define NY 5
#define NRANK 2
#define BATCH 10

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <cufft.h>
#include <stdio.h>
#include <iostream>

int check();

int main()
{


// static array
float b[NX][NY] ={
{0.7943 , 0.6020 , 0.7482 , 0.9133 , 0.9961},
{0.3112 , 0.2630 , 0.4505 , 0.1524 , 0.0782},
{0.5285 , 0.6541 , 0.0838 , 0.8258 , 0.4427},
{0.1656 , 0.6892 , 0.2290 , 0.5383 , 0.1067}
};

// dynamic array
float **a = new float*[NX];
for (int r = 0; r < NX; ++r)
{
a[r] = new float[NY];
for (int c = 0; c < NY; ++c)
{
a[r][c] = b[r][c];
}
}

// arrray to store the results - host side
float c[NX][NY] = { 0 };

cufftHandle plan;
cufftComplex *data;
int n[NRANK] = {NX, NY};

cudaMalloc((void**)&data, sizeof(cufftComplex)*NX*(NY/2+1));
cudaMemcpy(data, b, sizeof(float)*NX*NY, cudaMemcpyHostToDevice);

/* Create a 2D FFT plan. */
cufftPlanMany(&plan, NRANK, n,NULL, 1, 0,NULL, 1, 0,CUFFT_R2C,BATCH);
cufftSetCompatibilityMode(plan, CUFFT_COMPATIBILITY_NATIVE);
cufftExecR2C(plan, (cufftReal*)data, data);
cudaThreadSynchronize();
cudaMemcpy(c, data, sizeof(float)*NX*NY, cudaMemcpyDeviceToHost);

cufftDestroy(plan);
cudaFree(data);

return 0;
}

最佳答案

data 属于 cufftComplex 类型,它是一系列最终生成 float2 的 typedef。这意味着 data + n 会将 data 推进 n 类型 float2 的对象,或 2 * n float 类型的对象。这使您的“动态数组”复制不正确;你必须将 data 的增量减半。

编辑

查看 cufftExecR2C() 的参数类型,我认为这应该可行:

for(int i=0; i<NX; ++i){
cudaMemcpy(reinterpret_cast<float*>(data) + i*NY, a[i], sizeof(float)*NY, cudaMemcpyHostToDevice);
}

旁注:您实际上没有动态二维数组(即 new float[NX * NY])。您拥有的是指向动态 float 组的指针的动态数组。我相信您改用真正的二维数组会更有意义,这样您也可以保留静态大小写复制代码。

既然你已经标记了这个 C++,你应该认真考虑使用 std::vector 而不是手动管理你的动态内存。也就是说,像这样更改 a:

std::vector<float> a(NX * NY);

当您使用它时,我建议将 NXNY 等从宏转换为常量:

const size_t NX = 4;
const size_t NY = 5;

等等

关于c++ - 在 CUDA 中将动态分配的二维数组从主机复制到设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20797779/

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