5

私はCudaを学ぶために旅を始めています。私はいくつかの hello world タイプの cuda コードで遊んでいますが、機能していません。その理由はわかりません。

コードは非常に単純で、2 つの int を取り、それらを GPU に追加して結果を返しますが、数値を何に変更しても同じ結果が得られます (数学がそのように機能した場合、私は主題でより多くのことをしたでしょう)実際に行った)。

サンプルコードは次のとおりです。

// CUDA-C includes
#include <cuda.h>
#include <stdio.h>

__global__ void add( int a, int b, int *c ) {
    *c = a + b;
}

extern "C"
void runCudaPart();

// Main cuda function

void runCudaPart() {

    int c;
    int *dev_c;

    cudaMalloc( (void**)&dev_c, sizeof(int) );
    add<<<1,1>>>( 1, 4, dev_c );

    cudaMemcpy( &c, dev_c, sizeof(int), cudaMemcpyDeviceToHost );

    printf( "1 + 4 = %d\n", c );
    cudaFree( dev_c );

}

出力は少しずれているようです:1 + 4 = -1065287167

私は環境のセットアップに取り組んでおり、コードに問題があるかどうかを知りたいだけでした。それ以外の場合は、おそらく私の環境です。

更新:エラーを表示するコードを追加しようとしましたが、出力は得られませんが、番号が変更されます(回答の代わりにエラーコードを出力していますか?カーネルで割り当て以外の作業を行わなくてもvariable 私はまだ simlair の結果を取得します)。

// CUDA-C includes
#include <cuda.h>
#include <stdio.h>

__global__ void add( int a, int b, int *c ) {
    //*c = a + b;
    *c = 5;
}

extern "C"
void runCudaPart();

// Main cuda function

void runCudaPart() {

    int c;
    int *dev_c;

    cudaError_t err = cudaMalloc( (void**)&dev_c, sizeof(int) );
    if(err != cudaSuccess){
         printf("The error is %s", cudaGetErrorString(err));
    }
    add<<<1,1>>>( 1, 4, dev_c );

    cudaError_t err2 = cudaMemcpy( &c, dev_c, sizeof(int), cudaMemcpyDeviceToHost );
    if(err2 != cudaSuccess){
         printf("The error is %s", cudaGetErrorString(err));
    }


    printf( "1 + 4 = %d\n", c );
    cudaFree( dev_c );

}

コードは問題ないようです。おそらく私のセットアップに関連しています。Cuda を OSX ライオンにインストールするのは悪夢でしたが、SDK のサンプルは問題ないように見えたので、うまくいったと思いました。これまでに行った手順は、Nvida の Web サイトにアクセスして、ドライバー、ツールキット、および SDK の最新の Mac リリースをダウンロードすることです。次にexport DYLD_LIBRARY_PATH=/usr/local/cuda/lib:$DYLD_LIBRARY_PATH、「PATH=/usr/local/cuda/bin:$PATH」を追加して deviceQuery を実行すると、システムに関する次の情報が渡されました。

[deviceQuery] starting...

/Developer/GPU Computing/C/bin/darwin/release/deviceQuery Starting...

 CUDA Device Query (Runtime API) version (CUDART static linking)

Found 1 CUDA Capable device(s)

Device 0: "GeForce 320M"
  CUDA Driver Version / Runtime Version          4.2 / 4.2
  CUDA Capability Major/Minor version number:    1.2
  Total amount of global memory:                 253 MBytes (265027584 bytes)
  ( 6) Multiprocessors x (  8) CUDA Cores/MP:    48 CUDA Cores
  GPU Clock rate:                                950 MHz (0.95 GHz)
  Memory Clock rate:                             1064 Mhz
  Memory Bus Width:                              128-bit
  Max Texture Dimension Size (x,y,z)             1D=(8192), 2D=(65536,32768), 3D=(2048,2048,2048)
  Max Layered Texture Size (dim) x layers        1D=(8192) x 512, 2D=(8192,8192) x 512
  Total amount of constant memory:               65536 bytes
  Total amount of shared memory per block:       16384 bytes
  Total number of registers available per block: 16384
  Warp size:                                     32
  Maximum number of threads per multiprocessor:  1024
  Maximum number of threads per block:           512
  Maximum sizes of each dimension of a block:    512 x 512 x 64
  Maximum sizes of each dimension of a grid:     65535 x 65535 x 1
  Maximum memory pitch:                          2147483647 bytes
  Texture alignment:                             256 bytes
  Concurrent copy and execution:                 Yes with 1 copy engine(s)
  Run time limit on kernels:                     Yes
  Integrated GPU sharing Host Memory:            Yes
  Support host page-locked memory mapping:       Yes
  Concurrent kernel execution:                   No
  Alignment requirement for Surfaces:            Yes
  Device has ECC support enabled:                No
  Device is using TCC driver mode:               No
  Device supports Unified Addressing (UVA):      No
  Device PCI Bus ID / PCI location ID:           4 / 0
  Compute Mode:
     < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 4.2, CUDA Runtime Version = 4.2, NumDevs = 1, Device = GeForce 320M
[deviceQuery] test results...
PASSED

更新:本当に奇妙なのは、カーネル内のすべての作業を削除しても、c の結果が得られることですか? 私はcudaを再インストールし、サンプルでmakeを使用しましたが、それらはすべて成功しました。

4

2 に答える 2

8

基本的に、ここには 2 つの問題があります。

  1. 正しいアーキテクチャ用にカーネルをコンパイルしていません (コメントから収集)
  2. コードに不完全なエラー チェックが含まれているため、実行時エラーが発生している時点が欠落しており、不可解で説明のつかない症状が発生しています。

ランタイム API では、ほとんどのコンテキスト関連のアクションが「遅延」して実行されます。初めてカーネルを起動すると、ランタイム API がコードを呼び出して、ターゲット ハードウェアのツールチェーンによって生成されたファット バイナリ イメージ内から適切な CUBIN イメージをインテリジェントに見つけ、それをコンテキストにロードします。これには、下位互換性のあるアーキテクチャ用の PTX の JIT 再コンパイルも含まれますが、その逆は含まれません。そのため、コンピューティング機能 1.2 デバイス用にコンパイルされたカーネルがあり、それをコンピューティング機能 2.0 デバイスで実行する場合、ドライバーは、含まれている PTX 1.x コードを新しいアーキテクチャ用に JIT コンパイルできます。しかし、逆はうまくいきません。したがって、あなたの例では、実行可能ファイルに埋め込まれた CUDA ファットバイナリ イメージで使用可能なバイナリ イメージが見つからないため、ランタイム API はエラーを生成します。もう少し詳しい情報については、この質問を参照してください)。

コードに次のようなエラー チェックが含まれている場合:

cudaError_t err = cudaMalloc( (void**)&dev_c, sizeof(int) );
if(err != cudaSuccess){
     printf("The error is %s", cudaGetErrorString(err));
}

add<<<1,1>>>( 1, 4, dev_c );
if (cudaPeekAtLastError() != cudaSuccess) {
    printf("The error is %s", cudaGetErrorString(cudaGetLastError()));
}

cudaError_t err2 = cudaMemcpy( &c, dev_c, sizeof(int), cudaMemcpyDeviceToHost );
if(err2 != cudaSuccess){
     printf("The error is %s", cudaGetErrorString(err));
}

カーネルの起動後の追加のエラー チェックでは、カーネルのロード/起動の失敗によって生成されたランタイム API エラーをキャッチする必要があります。

于 2012-05-10T07:08:23.853 に答える