2011-11-15 17 views
1

私は現在、CUDAプログラミングで、特にデバイスがホストに返す配列をコピーして読み出す際に、非常に難しい問題を抱えています。私が私に返すはずのデータを読み込もうとすると、私はすべて迷惑データになります。誰かが私のコードスニペットを見て、私が間違っていることを教えてもらえますか?どうもありがとうございました!CUDA - デバイスデータがホストに転送されないのはなぜですか?

struct intss { 
u_int32_t one; 
u_int32_t two; 
}; 



int main() 
{ 
    int block_size = 3;    
    int grid_size = 1; 

    intss *device_fb = 0; 
    intss *host_fb = 0; 


    int num_bytes_fb = (block_size*grid_size)*sizeof(intss); 


host_fb = (intss*)malloc(num_bytes_fb); 
cudaMalloc((void **)&device_fb, num_bytes_fb); 

    .... 

    render2<<<block_size,grid_size>>>(device_fb, device_pixelspercore, samples, obj_list_flat_dev, numOpsPerCore, lnumdev, camdev, lightsdev, uranddev, iranddev); 


    .... 

    cudaMemcpy(host_fb, device_fb, num_bytes_fb, cudaMemcpyDeviceToHost); 


    printf("output %d ", host_fb[0].one); 

    printf("output %d ", host_fb[1].one); 

    printf("output %d ", host_fb[2].one); 
    //Note that I'm only looking at elements the 3 elements 0-2 from host_fb. I am doing this because block_size*grid_size = 3. Is this wrong? 

    cudaFree(device_fb); 
    free(host_fb); 
} 


__global__ void render2(intss *device_fb, struct parallelPixels *pixelsPerCore, int  samples, double *obj_list_flat_dev, int numOpsPerCore, int lnumdev, struct camera camdev, struct vec3 *lightsdev, struct vec3 *uranddev, int *iranddev)   //SPECIFY ARGUMENTS!!! 
{ 
int index = blockIdx.x * blockDim.x + threadIdx.x; //DETERMINING INDEX BASED ON WHICH THREAD IS CURRENTLY RUNNING 

.... 

//computing data... 


device_fb[index].one = (((u_int32_t)(MIN(r, 1.0) * 255.0) & 0xff) << RSHIFT | 
        ((u_int32_t)(MIN(g, 1.0) * 255.0) & 0xff) << GSHIFT | 
        ((u_int32_t)(MIN(b, 1.0) * 255.0) & 0xff) << BSHIFT); 
} 

EDIT:提案へ

おかげで、私は私のプログラムでCudaErrorCheck機能を実装し、機能は私にエラーを与えられたパターンがあるように思われています。

私のプログラムでは、グローバルホストアレイ(obj_list、lights、urand、irand)がたくさんあります。 cudaMemCpyを使用してこれらのホストアレイをデバイスアレイにコピーしようとすると、次のエラーが表示されます。 "x:無効な引数のファイル 'cudatrace.cu'にCudaエラーがあります。

obj_listとライトは次の関数で充填され、load_scene():

空隙load_scene(ファイル*のFP){ チャーライン[256]、* ptrは、タイプ;

obj_list = (sphere *)malloc(sizeof(struct sphere)); 
obj_list->next = 0; 
objCounter = 0; 

while((ptr = fgets(line, 256, fp))) { 
    int i; 
    struct vec3 pos, col; 
    double rad, spow, refl; 

    while(*ptr == ' ' || *ptr == '\t') ptr++; 
    if(*ptr == '#' || *ptr == '\n') continue; 

    if(!(ptr = strtok(line, DELIM))) continue; 
    type = *ptr; 

    for(i=0; i<3; i++) { 
     if(!(ptr = strtok(0, DELIM))) break; 
     *((double*)&pos.x + i) = atof(ptr); 
    } 

    if(type == 'l') { 
     lights[lnum++] = pos; 
     continue; 
    } 

    if(!(ptr = strtok(0, DELIM))) continue; 
    rad = atof(ptr); 

    for(i=0; i<3; i++) { 
     if(!(ptr = strtok(0, DELIM))) break; 
     *((double*)&col.x + i) = atof(ptr); 
    } 

    if(type == 'c') { 
     cam.pos = pos; 
     cam.targ = col; 
     cam.fov = rad; 
     continue; 
    } 

    if(!(ptr = strtok(0, DELIM))) continue; 
    spow = atof(ptr); 

    if(!(ptr = strtok(0, DELIM))) continue; 
    refl = atof(ptr); 

    if(type == 's') { 
     objCounter++; 
     struct sphere *sph = (sphere *)malloc(sizeof(*sph)); 
     sph->next = obj_list->next; 
     obj_list->next = sph; 

     sph->pos = pos; 
     sph->rad = rad; 
     sph->mat.col = col; 
     sph->mat.spow = spow; 
     sph->mat.refl = refl; 

    } else { 
     fprintf(stderr, "unknown type: %c\n", type); 
    } 
} 

}

次のようにurandとIRANDがメインに充填されています

/* initialize the random number tables for the jitter */ 
for(i=0; i<NRAN; i++) urand[i].x = (double)rand()/RAND_MAX - 0.5; 
for(i=0; i<NRAN; i++) urand[i].y = (double)rand()/RAND_MAX - 0.5; 
for(i=0; i<NRAN; i++) irand[i] = (int)(NRAN * ((double)rand()/RAND_MAX)); 

私はcudaMallocコールが作成するので、無効な引数は、素子アレイが原因で発生することがないと思いますcudaMemcpyコールの前のデバイスアレイにはCudaErrorメッセージがありませんでした。例えば、次のコード行に:

cudaErrorCheck(cudaMalloc((void **)&lightsdev, MAX_LIGHTS*sizeof(struct vec3))); 

cudaErrorCheck(cudaMemcpy(&lightsdev, &lights, sizeof(struct vec3) * MAX_LIGHTS, cudaMemcpyHostToDevice)); 

cudaMallocは、エラーが発生しなかったが、cudaMemcpyはなかったです。私は自分のコードに十分な情報を提供していない場合は

、私はに全体のコードを貼り付けています(http://pastebin.com/UgzABPgH

ペーストビンバージョンでは、私はCudaMemcpyのエラーを生成した上でCudaErrorCheck機能を取り出したことに注意してください。)

ありがとうございました!

EDIT: 実際には、urandとirandがグローバルではない場合や、デバイス配列uranddevとiranddevと一緒に初期化されていた場合にどうなるか見てみました。私はまだ同じ "無効な引数"エラーを受けているので、変数がグローバルかどうかは問題に関係していてはいけません。

+0

「既知の」データを割り当てようとしましたか?すなわち:device_fb [index] .one = blockIdx.x;期待値は0,1,2です。 – pQB

+0

はい、私は '既知の'データを試しましたが、接続があるようです。出力を生成するために呼び出される関数が順番に動作する必要があるので、これが何を意味するのかよく分かりません。 – albireneo

+0

むしろ、「接続」とは、ホストアレイがデバイスアレイがコピーバックしている正しい値を読み取ることができることを意味します。 – albireneo

答えて

0

<<< >>>構文を正しく使用していないと思います。

MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C); 

グリッドサイズは、最初に行く必要があることを意味します:

はここCUDA Programming Guideからカーネルの呼び出しです。

カーネルへの引数の最大サイズにも制限があります。 thisを参照してください。あなたがそれを上回ると、コンパイラが不平を言うのか不快なことをするのかが分かりません。

device_fb以外の引数をすべて削除して、カーネルにdevice_fb[index]=indexを設定するだけで、値を正常に読み取ることができます。

+0

応答ありがとう!残念ながら、私はrender2()の呼び出しでblock_sizeとgrid_sizeの位置を入れ替えましたが、データはまだ読み込まれていません。 – albireneo

+0

引数が256バイトの制限を超えているとは思われません。そのほとんどはポインタです。私は引数を削除しようとすることができますが、私は必要な計算を実行するためにそれらのすべてを必要とします。 – albireneo

+0

最悪のシナリオでは、それらを構造体としてパックし、そのポインタを渡すことができます。あなたが256を超えているかもしれないと思うひとつの議論は、私があなたが価値を超えているのを見ている 'camdev'です。どちらの方法でも、問題をさらに分離するために、 'device_fb'をビットに対して既知の値に設定しようとすることができます。 – Vlad

4

実際の問題の適切な説明がなく、不完全でコンパイルできないコードを投稿したときは、何かを言うことは絶対に不可能です。 StackOverflowでより良い質問をすることで、より良い回答が得られます。

と言われています。最も可能性の高い問題は、データがデバイスとの間でコピーされていないことではなく、カーネル自体が実行されていないことです。すべてのCUDAランタイムAPIコールはステータスコードを返します。すべてのCUDAランタイムAPIコールをチェックする必要があります。あなたはこの1つのようにチェックマクロエラーを定義することができます。

#include <stdio.h> 

#define cudaErrorCheck(call) { cudaAssert(call,__FILE__,__LINE__) } 

void cudaAssert(const cudaError err, const char *file, const int line) 
{ 
    if(cudaSuccess != err) {             
     fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n",   
       file, line, cudaGetErrorString(err)); 
     exit(1); 
    } 
} 

と、このように、それにすべてのAPI呼び出しをラップ:カーネルの起動については

cudaErrorCheck(cudaMemcpy(host_fb, device_fb, num_bytes_fb, cudaMemcpyDeviceToHost)); 

、自身をあなたが打ち上げ失敗を確認することができますかこのようなランタイムエラー:

kernel<<<....>>>(); 
cudaErrorCheck(cudaPeekAtLastError()); // Checks for launch error 
cudaErrorCheck(cudaThreadSynchronize()); // Checks for execution error 

私の提案は、あなたのコードにチェックを徹底し、エラーを追加してから戻って来て、あなたが得る結果とあなたの質問を編集しています。その後、誰かが何が起こっているのかについて具体的な提案をすることができるかもしれません。

+0

ご回答ありがとうございます - 申し訳ございませんが、不十分な情報が記載されています。私は現在、ErrorCheck関数でAPI呼び出しをラップしようとしていますが、すべての呼び出しで次のエラーが発生しています。 cudatrace.cu(337):エラー: ";" これは、関数をラップする方法の例です: cudaErrorCheck(cudaMalloc(void **)&device_pixelspercore、num_bytes_ParallelPixel)); ありがとう – albireneo

+0

talonmiesは忘れました;私は思う。 #define cudaErrorCheck(call){cudaAssert(コール、__FILE __、__LINE __); }(FILEとLINEの後にスペースを入れずに、フォーマットのためにそれらを使用しなければならなかった) – jmsu

関連する問題