CUDA でのコーディングを練習するために、3 つのファイルがある小さなテスト シナリオを作成しました。
memory.c
純粋なC
コードを保持memory_kernels.h
カーネルを起動するための CUDA カーネルと関数の宣言memory_kernels.cu
カーネルの定義
プログラムがすべきことは、ホスト上に整数配列を作成し、それをデバイスにコピーして要素をクエリすることです。カーネルはいくつかの詳細を表示します。
ただし、次のエラーが表示されます。
Error in memory_kernels.cu at line 43 with error code "unspecified launch failure"
3 つのファイルのソース コードは次のとおりです。
/**
* memory.c
*
* Test copying large arrays to device
* and printing from kernel
*/
/* Include standard libraries */
#include <stdlib.h>
#include <stdio.h>
/* Include local header files */
#include "memory_kernels.h"
int main() {
/* Size of array */
int i, N = 1024;
/* Array */
int *intArr = (int *) malloc( N * sizeof(int) );
/* Fill array */
for( i = 0; i < N; i++ ) {
intArr[i] = i;
}
/* Run CUDA code */
cuda_mem( &intArr );
/* Clean up device */
cudaDeviceReset();
/* Everything done */
exit(EXIT_SUCCESS);
}
/**
* memory_kernels.h
*
* Declarations for CUDA kernels
*/
/* Determine compiler */
#ifdef __cplusplus
#define EXTCFUNC extern "C"
#else
#define EXTCFUNC extern
#endif
#ifndef KERNELS_H
#define KERNELS_H
/* Standard libraries (only needed for debugging) */
#include <stdio.h>
/* Include CUDA header files */
#include <cuda.h>
#include <cuda_runtime.h>
#define CUDA_CALL(x) do { if((x) != cudaSuccess) { \
printf("Error in %s at line %d with error code \"%s\"\n",__FILE__,__LINE__,cudaGetErrorString(x)); \
exit(x);}} while(0)
/* Device globals */
__device__ int *d_intArr;
/* Device kernels */
__global__ void mem();
/* Host access functions */
EXTCFUNC void cuda_mem( int **intArr );
#endif
/**
* memory_kernels.cu
*
* CUDA kernel implementations
*/
/* Include header file */
#include "memory_kernels.h"
__global__ void mem() {
int i = threadIdx.x;
int a = d_intArr[i];
printf("i = %d a = %d\n",i,a);
}
/* Determine compiler */
#ifdef __cplusplus
#define EXTCFUNC extern "C"
#else
#define EXTCFUNC extern
#endif
/**
* cuda_mem()
*
* Test copying large array to device
* and printing from kernel
*/
EXTCFUNC void cuda_mem( int **intArr ) {
/* Local variables */
int N = 1024;
/* Initialise device variables */
CUDA_CALL( cudaMalloc( (void **) &d_intArr, sizeof(int) * N ) );
/* Copy to device initial values */
CUDA_CALL( cudaMemcpy( d_intArr, *intArr, sizeof(int) * N, cudaMemcpyHostToDevice ) );
/* Run kernel */
mem <<< 1,N >>> ();
CUDA_CALL( cudaPeekAtLastError() );
CUDA_CALL( cudaDeviceSynchronize() );
/* Free local scoped dynamically allocated memory */
CUDA_CALL( cudaFree( d_intArr ) );
}
コンパイルは次のコマンドで行われます。
nvcc -c -o memory.o memory.c -arch=sm_20
nvcc -c -o memory_kernels.o memory_kernels.cu -arch=sm_20
nvcc -o memory memory.o memory_kernels.o -arch=sm_20
CUDA 4.0 を搭載した NVIDIA Tesla M2050 で実行されました。printf()
カーネルで使用するには、コンピューティング機能 2.0 が必要です。
解決策を探し回った結果、エラー コードは、グローバル メモリからの読み取り時に、カーネルにセグメンテーション エラーがあることを示しています。ただし、配列のサイズと同じ数のスレッドを起動しています。
いろいろ試してみると、デバイスへのコピー時にエラーが発生する気がしintArr
ます。多分私は私のポインタをすべて混同していますか?
ファイル構造が少し変わっているかどうかは理解していますが、それはすべて大きなプログラムの一部ですが、エラーをこの小さなケースに減らしました。