簡體   English   中英

將動態分配的2D陣列從主機復制到CUDA中的設備

[英]Copying a dynamically allocated 2D array from host to device in CUDA

我想將動態分配的2D數組從主機復制到設備,以獲取其離散傅立葉變換。

我正在使用下面的代碼將數組復制到設備

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;
    }

datacufftComplex類型,它是一系列typedef,最終導致float2 這意味着data + n將使data前進float2類型的n對象,或float類型2 * n對象。 這使您的“動態數組”復制不正確; 您必須將data增量減半。

編輯

查看參數cufftExecR2C() ,我認為這應該工作:

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

旁注:您實際上沒有動態2D數組(該數組為new float[NX * NY] )。 您擁有的是一個動態指針數組,該指針指向浮點數的動態數組。 我相信使用真正的2D數組對您來說更有意義,這也使您可以保留靜態大小寫的復制代碼。

並且,由於已經標記了此C ++,因此您應該認真考慮使用std::vector而不是手動管理動態內存。 也就是說,更改a像這樣的:

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

當您使用它時,我建議將NXNY等從宏轉換為常量:

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

等等

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM