0

皆さん: 最近、cuda 5.5 の最新のプロパティ、つまり動的並列処理をプログラムに利用しようと試みました。しかし、私はいくつかの非常に紛らわしい問題を抱えています。私のコードはここにあります:

    /* Includes, system */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    using namespace std;
    /* Includes, cuda */
    #include <cuda_runtime.h>
    #include <cublas_v2.h>
    
    /* Includes, cuda helper functions */
    #include <helper_cuda.h>
    
    #include "kernels.cu"
    /* Matrix size */
    #define N  (275)
    
    #define LengthSignal (64)
    
    #define AmountSignal (255025)
    
    #define NBLOCKX (32768)
    
    #define NTHREADS_PER_BLOCK (128)
    /* Declaration of the function that computes sgemm using CUBLAS device API */
    
    __global__ void invokeDeviceCublasSgemm(float *d_A, float *Test);
    
    /* Main */
    int main(int argc, char **argv)
    {
      float *h_A;
      float *d_A = 0;
      int n2 = N * N;
    
      h_A = (float *)malloc(n2 * sizeof(h_A[0]));
  /* Fill the matrices with test data */
  for (int i = 0; i < n2; i++)
    {
      h_A[i] = rand() / (float)RAND_MAX;
    }

      cudaMalloc((void **)&d_A, n2 * sizeof(h_A[0]));
    
      /* Initialize the device matrices with the host matrices */
      //  cudaMemcpy(d_A, h_A, sizeof(float) * LengthSignal * AmountSignal, cudaMemcpyHostToDevice);
      cudaMemcpy(d_A, h_A, n2 * sizeof(h_A[0]), cudaMemcpyHostToDevice);
    
      int Length = 100;
      float *h_Test = (float *) malloc(sizeof(float) * Length);
      float *d_Test;
      cudaMalloc((void **) &d_Test, sizeof(float) * Length);
      cudaMemset(d_Test, 0, sizeof(float) * Length);

  invokeDeviceCublasSgemm<<<NBLOCKX, NTHREADS_PER_BLOCK>>>(d_A, d_Test);
  cudaMemcpy(h_Test, d_Test, sizeof(float) * Length, cudaMemcpyDeviceToHost);

  printf("\n The first 10 elements of d_A in location 1 are: \n");
  for (int j = 0; j < 10; j ++)
    {
      printf("%f ", h_Test[j]);
    }

  printf("\n The first 10 elements of d_A in location 2 are: \n");
  for (int j = 10; j < 20; j ++)
    {
      printf("%f ", h_Test[j]);
    }
  printf("\n");

  free(h_Test);
  cudaFree(d_Test);

  /* Memory clean up */
  free(h_A);
  cudaFree(d_A);
}

#ifndef __GLOBAL__CU__
#define __GLOBAL__CU__

__global__ void invokeDeviceCublasSgemm(float *d_A, float *Test)
{
  // save the first 10 elements of d_A in location 1
  for (int j = 0; j < 10; j ++)
    {
      Test[j] = d_A[j];
    }
  cublasHandle_t cnpHandle;
  cublasCreate(&cnpHandle);

    // save the first 10 elements of d_A in location 2
    for (int j = 10; j < 20; j ++)
      {
        Test[j] = d_A[j - 10];
      }
  cublasDestroy(cnpHandle);
}

#endif

構成パラメータを <<<1, 1>>> に設定すると、すべてがうまく機能します。出力は次のようになります。

位置 1 にある d_A の最初の 10 個の要素は次のとおりです。

0.840188 0.394383 0.783099 0.798440 0.911647 0.197551 0.335223 0.768230 0.277775 0.553970

位置 2 の d_A の最初の 10 個の要素は次のとおりです。

0.840188 0.394383 0.783099 0.798440 0.911647 0.197551 0.335223 0.768230 0.277775 0.553970

ただし、構成パラメーターを <<<32768, 128>>> に設定すると、出力はかなり奇妙になります。出力は次のようになります。

位置 1 にある d_A の最初の 10 個の要素は次のとおりです。

-0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

位置 2 の d_A の最初の 10 個の要素は次のとおりです。

0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

なぜなのか本当にわかりません!私のコードは、「サンプル」に少し変更を加えたものです。


そして、最後のコード「cublasDestroy(cnpHandle);」を削除するだけで、正常になります。出力は次のとおりです。

位置 1 にある d_A の最初の 10 個の要素は次のとおりです。

0.840188 0.394383 0.783099 0.798440 0.911647 0.197551 0.335223 0.768230 0.277775 0.553970

位置 2 の d_A の最初の 10 個の要素は次のとおりです。

0.840188 0.394383 0.783099 0.798440 0.911647 0.197551 0.335223 0.768230 0.277775 0.553970


誰かが同じ問題を抱えていましたか?

ありがとう!

4

1 に答える 1

2

適切なcudaエラー チェック を行う ホスト API 呼び出し、デバイス API 呼び出し、および CUBLAS API 呼び出し (およびカーネル呼び出し) で実行できます。よくわからない場合は、動的並列処理のドキュメントをお読みください。

いつでも未処理になる可能性のあるカーネル起動の数を超えている可能性があります。2048 カーネル起動の (構成可能な) 制限があり、未処理にすることができます。コードは のホスト カーネル起動パラメーターで失敗するため、<<<32768, 128>>>32768x128 スレッドを起動しようとしていることを意味し、それぞれが子カーネルを起動しようとする可能性があります。カーネルの起動回数が制限を超えると、残りのカーネルの起動は失敗します。

「しかし、私は子カーネルを起動していませんか??」実際、デバイスの CUBLAS API を使用すると、カーネルが起動される可能性があります。それがデバイスCUBLASシステムのしくみです。

本当に明確にするために、しっかりとしたエラーチェックを行うことを強くお勧めします。

于 2013-11-27T22:29:51.593 に答える