1

行 5 をコンパイルするときに、CUDA C プログラミングのカーネルに問題があり"expected an identifier"ます。エラーが発生しました。なぜこうなった?

私のカーネル関数は次のとおりです。

__global__ void txz_kernel(float *txz,float *vz)
{
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
int offset = x + y * blockDim.x * gridDim.x; --> error
txz[offset]=txz[offset]+vz[offset];
}

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

#include  "../common/book.h"
#include "conio.h"
#include "cuda.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <assert.h>
#include "../common/book.h"
#include <fstream>
#define DIMX 320
#define DIMZ 320
#define PI 3.1415926535897932f

__global__ void txz_kernel(float *txz,float *vz)
{
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
int offset = x + y * blockDim.x * gridDim.x; --> error
txz[offset]=txz[offset]+vz[offset];
}

int  main( void ) {
    float              *txz;
    float              *vz;

        HANDLE_ERROR( cudaMalloc( (void**)&txz, DIMX * DIMZ * sizeof(float)));
        HANDLE_ERROR( cudaMalloc( (void**)&vz, DIMX * DIMZ * sizeof(float)));

        float *tempvz = (float*)malloc( sizeof(float)*(DIMX*DIMZ));    
        float *temptxz = (float*)malloc( sizeof(float)*(DIMX*DIMZ)); 

    for (int i=0; i<DIMX; i++) {
        for (int j=0; j<DIMZ; j++) {
        int ij=DIMX*j + i; 
        tempvz[ij]=200.0;
        temptxz[ij]=100.0;
        }
    }

    for (int i=0; i<DIMX; i++) {
        for (int j=(121); j<DIMZ; j++) {
        int ij=DIMX*j + i;       
        tempvz[ij]=250.0;
        temptxz[ij]=150.0;
        }
    }
            HANDLE_ERROR( cudaMemcpy( vz, tempvz,sizeof(float)*(DIMX*DIMZ),cudaMemcpyHostToDevice ) );
            HANDLE_ERROR( cudaMemcpy( txz, temptxz,sizeof(float)*(DIMX*DIMZ),cudaMemcpyHostToDevice ) );
                dim3    blocks(DIMX/16,DIMZ/16);
                dim3    threads(16,16);
            txz_kernel<<<blocks,threads>>>(txz,vz) ;            
}
4

1 に答える 1

4

このコードをファイル拡張子 .cu のファイルに入れ、nvcc でコンパイルする必要があります。nvcc は、ファイル拡張子を使用して、任意の入力ファイルのコンパイル パスを決定します。ファイルに .cu ファイル拡張子がない場合、入力にデバイス コードがないと想定し、それをホスト コンパイラに渡します。コードに問題はありません。正しくコンパイルしていないだけです。

.cppファイル内のカーネル コードから始めましょう。

> type txzkernel.cpp
__global__ void txz_kernel(float *txz, float *vz)
{
    int x = threadIdx.x + blockIdx.x * blockDim.x;
    int y = threadIdx.y + blockIdx.y * blockDim.y;
    int offset = x + y * blockDim.x * gridDim.x;
    txz[offset]=txz[offset]+vz[offset];
}

それでは、nvcc でコンパイルしてみましょう。

> nvcc -arch=sm_20 -Xptxas="-v" -c txzkernel.cpp
txzkernel.cpp
txzkernel.cpp(1) : error C2144: syntax error : 'void' should be preceded by ';'
txzkernel.cpp(1) : error C4430: missing type specifier - int assumed. Note: C++
does not support default-int
txzkernel.cpp(3) : error C2065: 'threadIdx' : undeclared identifier
txzkernel.cpp(3) : error C2228: left of '.x' must have class/struct/union
        type is ''unknown-type''
txzkernel.cpp(3) : error C2065: 'blockIdx' : undeclared identifier
txzkernel.cpp(3) : error C2228: left of '.x' must have class/struct/union
        type is ''unknown-type''
txzkernel.cpp(3) : error C2065: 'blockDim' : undeclared identifier
txzkernel.cpp(3) : error C2228: left of '.x' must have class/struct/union
        type is ''unknown-type''
txzkernel.cpp(4) : error C2065: 'threadIdx' : undeclared identifier
txzkernel.cpp(4) : error C2228: left of '.y' must have class/struct/union
        type is ''unknown-type''
txzkernel.cpp(4) : error C2065: 'blockIdx' : undeclared identifier
txzkernel.cpp(4) : error C2228: left of '.y' must have class/struct/union
        type is ''unknown-type''
txzkernel.cpp(4) : error C2065: 'blockDim' : undeclared identifier
txzkernel.cpp(4) : error C2228: left of '.y' must have class/struct/union
        type is ''unknown-type''
txzkernel.cpp(5) : error C2065: 'blockDim' : undeclared identifier
txzkernel.cpp(5) : error C2228: left of '.x' must have class/struct/union
        type is ''unknown-type''
txzkernel.cpp(5) : error C2065: 'gridDim' : undeclared identifier
txzkernel.cpp(5) : error C2228: left of '.x' must have class/struct/union
        type is ''unknown-type''

その結果、ホスト コンパイラ (この場合は Microsoft Visual C++) がカーネル コード内の CUDA 言語拡張を認識しないため、多くの構文エラーが発生します。

正しい拡張子を持つようにファイルの名前を変更し、再度コンパイルします。

> rename txzkernel.cpp txzkernel.cu
> nvcc -arch=sm_20 -Xptxas="-v" -c txzkernel.cu
txzkernel.cu
tmpxft_000012dc_00000000-3_txzkernel.cudafe1.gpu
tmpxft_000012dc_00000000-8_txzkernel.cudafe2.gpu
txzkernel.cu
ptxas info    : Compiling entry function '_Z10txz_kernelPfS_' for 'sm_20'
ptxas info    : Function properties for _Z10txz_kernelPfS_
    0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info    : Used 5 registers, 40 bytes cmem[0]
tmpxft_000012dc_00000000-3_txzkernel.cudafe1.cpp
tmpxft_000012dc_00000000-14_txzkernel.ii

エラーなし。nvcc を使用してカーネル コードをコンパイルし、カーネル コードを適切な拡張子のファイルに入れると、このコードは変更なしでコンパイルされます。

于 2013-07-04T07:35:40.357 に答える