私は現在、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と一緒に初期化されていた場合にどうなるか見てみました。私はまだ同じ "無効な引数"エラーを受けているので、変数がグローバルかどうかは問題に関係していてはいけません。
「既知の」データを割り当てようとしましたか?すなわち:device_fb [index] .one = blockIdx.x;期待値は0,1,2です。 – pQB
はい、私は '既知の'データを試しましたが、接続があるようです。出力を生成するために呼び出される関数が順番に動作する必要があるので、これが何を意味するのかよく分かりません。 – albireneo
むしろ、「接続」とは、ホストアレイがデバイスアレイがコピーバックしている正しい値を読み取ることができることを意味します。 – albireneo