2

CUDAで排他的な合計削減を試みています。私は CUB ライブラリを使用しており、CUB::DeviceReduce を試すことにしました。しかし、私の結果は NaN で、その理由がわかりません。

コードは次のとおりです。

#include <cub/cub.cuh>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using std::cout;
using std::endl;
#define DSIZE 512

void dev_cumsum( const float *dev_inData, float *dev_outData ) {
    int n = 512;
    void* dev_temp_storage = NULL;
    size_t temp_storage_bytes = 0;
    cub::DeviceScan::ExclusiveSum(dev_temp_storage,temp_storage_bytes,const_cast<float*>(dev_inData),dev_outData,n);
    cudaMalloc(&dev_temp_storage,temp_storage_bytes);
    cub::DeviceScan::ExclusiveSum(dev_temp_storage,temp_storage_bytes,const_cast<float*>(dev_inData),dev_outData,n);
}

int main(){
    float h_data[512];
    float* d_data;
    float* d_result;
    float h_result[512];
    cudaMalloc(&d_data, DSIZE*sizeof(float));
    cudaMalloc(&d_result, DSIZE*sizeof(float));
    h_data[0] = rand()%10;
    h_result[0] = 0;
    for (int i=1; i<DSIZE; i++) {
        h_data[i] = rand()%10;
        h_result[i] = h_data[i-1]+h_result[i-1];
    }
    cudaMemcpy(d_data, h_data, DSIZE*sizeof(float), cudaMemcpyHostToDevice);
    dev_cumsum(d_data, d_result);
    printf("CPU result = %f\n", h_result[511]);
    cudaMemcpy(h_result, d_result, DSIZE*sizeof(float), cudaMemcpyDeviceToHost);
    printf("GPU result = %f\n", h_result[511]);
    for( int i = 0; i < DSIZE; i++ ) {cout << h_result[i] << " ";}
    cout << endl;
    return 0;
}

このコードは、デバイスの結果の最後の 8 つの要素に対して NaN を返します。

このコードは、Linux Mint15 の GTX650 Ti Boost で実行されています。私は NSight を使用しており、コンソール出力のコンパイル コマンドは次のとおりです。

Invoking: NVCC Compiler
/usr/local/cuda-5.5/bin/nvcc -G -g -O0 -gencode arch=compute_30,code=sm_30 -odir "" -M -o "main.d" "../main.cu"
/usr/local/cuda-5.5/bin/nvcc --device-c -G -O0 -g -gencode arch=compute_30,code=compute_30 -gencode arch=compute_30,code=sm_30  -x cu -o  "main.o" "../main.cu"

Cuda バージョンは 5.5 CUB バージョン 1.0.2 です

これは、Cuda 6、OSX10.9.2、CUB 1.2.3 を搭載し、GT750M を実行している別のコンピューターでテストされ、最後の 8 つの数字が NaN であるというエラーを再現しました。

編集: コードは int と double で正しく動作しますが、float では動作しません。

編集: Robert Crovella のおかげで、この質問はもともと DeviceReduce に関して尋ねられたものです。そのコードは機能し、DeviceScan を使用する以前のコードが入力として NaN を供給していたため、NaN をスローしていました。質問はそれに合わせて修正されます

4

2 に答える 2

1

編集: cub 1.3.0が最近リリースされましたが、この問題の修正が含まれていると思います。


エラーと思われるいくつかの変更をコードに加えますが、それらが表示されているものに影響を与えているかどうかはわかりません。次のコード セクションでは、h_result[0]初期化せずに使用しているため、コメントでマークした行を追加します。

h_data[0] = rand()%10;
h_result[0] = 0;    // ADD THIS LINE
for (int i=1; i<DSIZE; i++) {
    h_data[i] = rand()%10;
    h_result[i] = h_data[i-1]+h_result[i-1];
}

(明らかに、GPU の結果に影響を与えるべきではありません。) また、最終的なcudaMemcpy操作は正しくありません。

cudaMemcpy(&h_result, d_result, DSIZE*sizeof(float), cudaMemcpyDeviceToHost);
           ^
           delete this ampersand

はすでに定式化のポインターであるためh_result、そのアドレスを に渡す必要はありませんcudaMemcpy

これらの変更を行ってみて、どのような結果が得られるかを確認できますか?

私はこれに少し苦労してきました。それでもエラーを再現できる場合は、次のことを教えていただければ幸いです。

  1. マシンを再起動して、もう一度やり直してください
  2. 実行している実際の更新されたコード、使用しているコンパイル コマンド、CUDA のバージョン、CUB のバージョン、実行している GPU、システム OS を返信してください。(この情報で元の質問を編集してください)
于 2014-04-29T18:05:51.617 に答える