簡體   English   中英

如何將變量從主機上的自定義類數組復制到CUDA中設備上的浮點數組中

[英]How to copy variables from a custom class array on host into a float array on device in CUDA

我正在使用CUDA。 我在主機上有以下課程:

class Particle{
     public:
     float x;
     float v;
     // several other variables
}

然后我有一個粒子向量

vector <Particle> p_all(512);

在GPU上,我想對所有x的數組(從所有粒子中獲取)進行操作,並希望將數據從“粒子”數組復制到設備上的float數組中。 我有一種可以使用cudaMemcpy的預感,我嘗試了以下代碼,但它給出了無效的音調錯誤。

cudaMalloc( (void**) &pos_dev, sizeof(float)*512);
cudaMemcpy2D( (void*) &pos_dev, sizeof(float), (void*)&p_all[0].x, sizeof(Particle), sizeof(Particle), 512*sizeof(float), cudaMemcpyHostToDevice);

有可能這樣做嗎? 當然,備份解決方案是使用for循環創建x的數組,然后將其復制到設備中。 但我正在尋找一種更有效的解決方案。

謝謝。

完整代碼如下。

#include <cuda_runtime.h>
#include <iostream>
#include <vector>
using namespace std;

// This will output the proper error string when calling cudaGetLastError
void getLastCudaError(string s=""){
    string errMessage = s;
    cudaError_t err = cudaGetLastError();
    if( err != cudaSuccess){
        cerr << __FILE__ << "(" << __LINE__ << ") : Last Cuda Error - " << errMessage 
             << " (" << int(err) << "): " << cudaGetErrorString(err) << ".\n";
        exit(-1);
    }
}

class Particle{
    public:
    float x;
    float v;
    int a;
    char c;
    short b;

    Particle(){
        a=1988; c='a'; v=5.56; x=1810; b=1.66;
    }
};

template <class T>
void printVec(vector <T> &v, string name = "v"){
    cout << name << " = ";
    for (int i=0; i<v.size(); ++i) cout << v[i] << " " ;
    cout << '\n';
}

int main(){

    const int N = 512;
    vector <float> pos(N,5);

    vector <Particle> p_all(N);

    float * pos_dev;
    float * vel_dev;

    cudaMalloc( (void**) &pos_dev, sizeof(float)*N);

    printVec(pos, "pos");

    cudaMemcpy2D( (void*) &pos_dev, sizeof(float), (void*)&(p_all[0].x), sizeof(Particle), sizeof(float), N, cudaMemcpyHostToDevice);
    getLastCudaError("HtoD");

    cudaMemcpy( (void*) &pos[0], (void*)&pos_dev, N*sizeof(float), cudaMemcpyDeviceToHost);
    getLastCudaError("DtoH");

    printVec(pos, "pos_new");

    return 0;

}

您將數據分配為“結構數組”,例如

class Particle{
    public:
        float x;
        float v;
}

Particle foo[N];

由於數據交織,這將導致合並問題,因此,您正在嘗試使用cudaMemcpy2D 就帶寬利用而言,一種更方便的解決方案是將數據分配為“數組結構”,如下所示:

class Particle{
    public:
        float x[N];
        float v[N];
}

Particle foo;

這樣,您將可以避免使用cudaMemcpy2D並通過簡單的cudaMemcpy將數據從主機復制到設備。

您的cudaMemcpy2D呼叫設置不正確。 檢查文檔

試試這個代替:

cudaMemcpy2D( (void*) pos_dev, sizeof(float), (void*)&(p_all[0].x), sizeof(Particle), sizeof(float), 512, cudaMemcpyHostToDevice);

有多個參數需要修改,但是無效音調錯誤出現,因為請求的傳輸寬度(以字節為單位)(您具有sizeof(Particle) )寬於目標音調( sizeof(float) ,這是正確的)

編輯:另外,盡管您沒有詢問,但是現在發布的代碼中的最終cudaMemcpy操作也不正確。 以下更改應有所幫助:

cudaMemcpy( (void*) &(pos[0]), (void*)pos_dev, N*sizeof(float), cudaMemcpyDeviceToHost);

暫無
暫無

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

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