web-dev-qa-db-ja.com

CUDA__device__未解決のextern関数

個別のヘッダーファイルでCUDA ___device___コードを分離する方法を理解しようとしています。

私は3つのファイルを持っています。

ファイル:1:int2.cuh

_#ifndef INT2_H_
#define INT2_H_

#include "cuda.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

__global__ void kernel();
__device__ int k2(int k);

int launchKernel(int dim);

#endif /* INT2_H_ */
_

ファイル2:int2.c

_#include "int2.cuh"
#include "cstdio"

__global__ void kernel() {
    int tid = threadIdx.x;
    printf("%d\n", k2(tid));
}

__device__ int k2(int i) {
    return i * i;
}

int launchKernel(int dim) {
    kernel<<<1, dim>>>();
    cudaDeviceReset();
    return 0;
}
_

ファイル3:CUDASample.c

_include <stdio.h>
#include <stdlib.h>
#include "int2.cuh"
#include "iostream"

using namespace std;

static const int WORK_SIZE = 256;

__global__ void sampleCuda() {
    int tid = threadIdx.x;
//    printf("%d\n", k2(tid)); //Can not call k2
    printf("%d\n", tid * tid);
}

int main(void) {

    int var;
    var = launchKernel(16);

    kernel<<<1, 16>>>();
    cudaDeviceReset();

    sampleCuda<<<1, 16>>>();
    cudaDeviceReset();

    return 0;
}
_

コードはファイルを動作させます。 sampleCuda()カーネル(同じファイル内)を呼び出し、C関数launchKernel()(他のファイル内)を呼び出し、kernel()を直接(他のファイル内)呼び出すことができます。 。

私が直面している問題は、sampleCuda()カーネルから___device___関数を呼び出すことです。次に、次のエラーが表示されます。ただし、同じ関数をkernel()で呼び出すことができます。

_10:58:11 **** Incremental Build of configuration Debug for project CUDASample ****
make all 
Building file: ../src/CUDASample.cu
Invoking: NVCC Compiler
/Developer/NVIDIA/CUDA-6.5/bin/nvcc -G -g -O0 -gencode Arch=compute_20,code=sm_20  -odir "src" -M -o "src/CUDASample.d" "../src/CUDASample.cu"
/Developer/NVIDIA/CUDA-6.5/bin/nvcc -G -g -O0 --compile --relocatable-device-code=false -gencode Arch=compute_20,code=compute_20 -gencode Arch=compute_20,code=sm_20  -x cu -o  "src/CUDASample.o" "../src/CUDASample.cu"
../src/CUDASample.cu(18): warning: variable "var" was set but never used

../src/CUDASample.cu(8): warning: variable "WORK_SIZE" was declared but never referenced

../src/CUDASample.cu(18): warning: variable "var" was set but never used

../src/CUDASample.cu(8): warning: variable "WORK_SIZE" was declared but never referenced

ptxas fatal   : Unresolved extern function '_Z2k2i'
make: *** [src/CUDASample.o] Error 255

10:58:14 Build Finished (took 2s.388ms)
_
11
max

問題は、__device__関数をそれを呼び出す__global__とは別のコンパイル単位で定義したことです。 -dcフラグを追加して再配置可能デバイスコードモードを明示的に有効にするか、定義を同じユニットに移動する必要があります。

nvcc ドキュメントから:

--device-c|-dc各.c/.cc/.cpp/.cxx /.cu入力ファイルを再配置可能なデバイスコードを含むオブジェクトファイルにコンパイルします。 --relocatable-device-code = true --compileと同等です。

詳細については、 CUDA C++デバイスコードの個別のコンパイルとリンク を参照してください。

12