2016-11-30 9 views
0

カーネル機能の実行後、印刷出力は常に0になります。 いくつかのテストの後、cudaMemcpyはまだ正しいです。しかし、カーネルは動作していないようですが、d_inputsから正しいデータを取得できません。 誰かが説明するのに役立つでしょうか?ありがとう!あなたはCUDAコードに問題があるCUDA出力は常に0

#include <cuda_runtime.h> 
#include <cuda.h> 
#include <stdio.h> 
#include <sys/time.h> 
#include <math.h> 

#define N 32 

__global__ void Kernel_double(int niters, int* d_inputs,double* d_outputs) 
{ 
    int tid = blockIdx.x * blockDim.x + threadIdx.x; 

    if (tid<N) { 
    double val =(double) d_inputs[tid]; 
    /*for (int iter=0; iter < niters; iter++){ 
    val = (sqrt(pow(val,2.0)) + 5.0) - 101.0; 
    val = (val/3.0) + 102.0; 
    val = (val + 1.07) - 103.0; 
    val = (val/1.037) + 104.0; 
    val = (val + 3.00) - 105.0; 
    val = (val/0.22) + 106.0; 
    }*/ 
    val = val + 1.0; 
    //printf("This is %f\n",val); 
    d_outputs[tid] = val; 
} 
} 

int main(int argc, char **argv) 
{ 

    int niters = 10; 
    printf("Iterate %d times with GPU 0 or CPU 1: %d\n", niters, cpu); 

    int inputs[N]; 
    for (int i = 0; i<N; i++){ 
    inputs[i] = i+1; 
    } 

    int d_inputs[N]; 
    double d_outputs[N]; 
    double outputs[N]; 

    cudaMalloc((void**)&d_inputs, N*sizeof(int)); 
    cudaMalloc((void**)&d_outputs, N*sizeof(double)); 
    printf("test %d \n", inputs[3]); 
    cudaMemcpy(d_inputs, inputs, N*sizeof(int), cudaMemcpyHostToDevice); 
    printf("test %d \n", d_inputs[1]); 
    Kernel_double<<<16,2>>>(niters, d_inputs,d_outputs); 
    //cudaDeviceSynchronize(); 
    cudaMemcpy(outputs, d_outputs, N*sizeof(double), cudaMemcpyDeviceToHost); 
    for(int j =0;j<10; j++){ 
     printf("Outputs[%d] is: %f and %f\n",j, d_outputs[j], outputs[j]); 
     } 
    cudaFree(d_inputs); 
    cudaFree(d_outputs); 

    return EXIT_SUCCESS; 
} 
+1

あなたはあなたのコードをチェックイン全くエラーを持っていないので、それはどんな時に失敗することができあなたは知りません。エラーが発生するたびにエラーチェックを追加し、それが問題の絞り込みに役立つかどうかを確認します。 –

+0

CHECK(cudaMalloc(void **)&d_inputs、N * sizeof(int))); \t CHECK(cudaGetLastError()); \tチェック(cudaMalloc((void **)&d_outputs、N * sizeof(double))); \t CHECK(cudaGetLastError()); \t printf( "test%d \ n"、inputs [3]); \t CHECK(cudaMemcpy(d_inputs、inputs、N * sizeof(int)、cudaMemcpyHostToDevice)); \t CHECK(cudaGetLastError()); \t printf( "テスト%d \ n"、d_inputs [1]); \t Kernel_double <<<16,2> >>(niters、d_inputs、d_outputs); \t CHECK(cudaGetLastError()); – user45690

+0

これを追加した後、私はcudaMemcpyの行でエラーを受け取り、無効な引数を示します – user45690

答えて

4
  1. いつでも、あなたはproper cuda error checkingを使用し、助けを他の人に尋ねる前cuda-memcheckでコードを実行する必要があります。あなたがエラー出力を理解していなくても、あなたを助けようとしている他の人にとっては役に立ちます。ここで適切なcudaエラーチェックを行っていた場合、cudaMemcpy操作が無効な引数を報告しているという通知が表示されます。
  2. コードはコンパイルされません。 cpuはどこにも定義されていません。
  3. 我々はのために割り当てる、またはこのようなデバイスのポインタを作成しないでください:

    int d_inputs[N]; 
    double d_outputs[N]; 
    

    これらは、コンパイラが、それは一定のポインタであるかのように処理するために許可されていることをスタック変数(配列)を作成しています。代わりに、あなたはこのようにそれを実行する必要があります。

    int *d_inputs; 
    double *d_outputs; 
    

    コンパイラは、これらが(あなたがcudaMallocと、後で変更します)修正のポインタであることを理解しています。あなたは項目3の問題を解決したら

  4. 、これは法律上できなくなります。

    printf("test %d \n", d_inputs[1]); 
    

    これは、少なくともとして、CUDAでは違法であるホストコードでデバイスのポインタ(d_inputs)が、逆参照が必要ですとしてあなたはここでそうしました。後でコードのprintfステートメントにも同様の問題があります(d_outputs)。

次のコードでは、ある程度宛上記の項目があり、私のために正常に実行するようだ:

$ cat t44.cu 
#include <cuda_runtime.h> 
#include <cuda.h> 
#include <stdio.h> 
#include <sys/time.h> 
#include <math.h> 

#define N 32 

__global__ void Kernel_double(int niters, int* d_inputs,double* d_outputs) 
{ 
    int tid = blockIdx.x * blockDim.x + threadIdx.x; 

    if (tid<N) { 
    double val =(double) d_inputs[tid]; 
    /*for (int iter=0; iter < niters; iter++){ 
    val = (sqrt(pow(val,2.0)) + 5.0) - 101.0; 
    val = (val/3.0) + 102.0; 
    val = (val + 1.07) - 103.0; 
    val = (val/1.037) + 104.0; 
    val = (val + 3.00) - 105.0; 
    val = (val/0.22) + 106.0; 
    }*/ 
    val = val + 1.0; 
    //printf("This is %f\n",val); 
    d_outputs[tid] = val; 
} 
} 

int main(int argc, char **argv) 
{ 

    int niters = 10; 
    int cpu = 0; 
    printf("Iterate %d times with GPU 0 or CPU 1: %d\n", niters, cpu); 

    int inputs[N]; 
    for (int i = 0; i<N; i++){ 
    inputs[i] = i+1; 
    } 

    int *d_inputs; 
    double *d_outputs; 
    double outputs[N]; 

    cudaMalloc((void**)&d_inputs, N*sizeof(int)); 
    cudaMalloc((void**)&d_outputs, N*sizeof(double)); 
    printf("test %d \n", inputs[3]); 
    cudaMemcpy(d_inputs, inputs, N*sizeof(int), cudaMemcpyHostToDevice); 
// printf("test %d \n", d_inputs[1]); 
    Kernel_double<<<16,2>>>(niters, d_inputs,d_outputs); 
    //cudaDeviceSynchronize(); 
    cudaMemcpy(outputs, d_outputs, N*sizeof(double), cudaMemcpyDeviceToHost); 
    for(int j =0;j<10; j++){ 
     printf("Outputs[%d] is: %f\n",j, outputs[j]); 
     } 
    cudaFree(d_inputs); 
    cudaFree(d_outputs); 

    return EXIT_SUCCESS; 
} 
$ nvcc -lineinfo -arch=sm_61 -o t44 t44.cu 
$ cuda-memcheck ./t44 
========= CUDA-MEMCHECK 
Iterate 10 times with GPU 0 or CPU 1: 0 
test 4 
Outputs[0] is: 2.000000 
Outputs[1] is: 3.000000 
Outputs[2] is: 4.000000 
Outputs[3] is: 5.000000 
Outputs[4] is: 6.000000 
Outputs[5] is: 7.000000 
Outputs[6] is: 8.000000 
Outputs[7] is: 9.000000 
Outputs[8] is: 10.000000 
Outputs[9] is: 11.000000 
========= ERROR SUMMARY: 0 errors 
$ 
+0

ありがとうございました!私はポイントごとに自分のコードを修正しようとし、エラーチェックツールに慣れる。本当に感謝! – user45690

+0

これが役立つ場合は、この回答を受け入れることを検討してください。 – Taro