CUDAプログラムのdll化
普通のdll作成と何一つ変わらないので記事にするか迷ったのだが、一カ所だけわかりにくかったので念のためにまとめておく。
環境は Visual C++ 2017 + CUDA 9.2
手順は以下の通りである。
②kernel.cuファイルの中身を普通に書く。ただし関数名はmain以外にする
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <cstring>
#include "cudadll.h"
__global__ void hello(char *c) {
c[0] = 'h';
c[1] = 'e';
c[2] = 'l';
c[3] = 'l';
c[4] = 'o';
c[5] = '\0';
}
//この関数の名前はmainではなく、呼び出す際に適切な名前にする
void func_hello(char **c_cpu) {
const size_t LEN = 6;// LEN = strlen("hello") + 1;
char *c_gpu;
cudaMalloc((void**)&c_gpu, LEN);//GPU側にメモリを確保
hello << <1, 1 >> >(c_gpu);//GPU側の関数を呼出
cudaMemcpy(c_cpu, c_gpu, LEN, cudaMemcpyDeviceToHost);//GPU側から実行結果を取得
cudaFree(c_gpu);//GPU側のメモリを解放
}
③ヘッダファイルを作成し、_declspecを追加
ソースコードに、_declspec(dllexport) , _declspec(dllimport)の分岐プリプロセッサを書き、先ほどのcall_cuda_funcの先頭につける。
cudadll.h
#ifdef __DLL_EXPORT_DO
#define DLL_PORT extern "C" _declspec(dllexport)
#else
#define DLL_PORT extern "C" _declspec(dllimport)
#endif
DLL_PORT void func_hello(char **c_cpu);
④プロジェクトの構成をdllへ変更
プロジェクトの設定を開き、[全般]→[構成の種類]をdllへ変更。それに伴いターゲットの拡張子も.dllへ変更
⑤CUDA側が_declspec(dllexport)となるようにマクロを追加
[構成プロパティ]→[CUDA C/C++]→[Host]の[Preprocessor Definitions]で、④の分岐で_declspec(dllexport) が入るようにマクロを定義
⑥exeのプロジェクトを作成し、呼び出し
#include "../cudadll/cudadll.h"
#pragma comment(lib,"cudadll.lib")
int main()
{
char c_cpu[12];
func_hello( (char**)&c_cpu);
puts(c_cpu);
getchar();
return 0;
}
基本的に、普通のDLL生成と全く同じである。違いは、
A. dll側のプロジェクトのファイル名が、 (上記②,③)
- 普通のプロジェクト ... function.c/function.h
- CUDAプロジェクト ... function.cu,function.h
B. _declspecの分岐のためのプリプロセッサを定義する場所が、 (上記⑤)
- 普通のプロジェクト ... [C/C++]→[プリプロセッサ]→[プリプロセッサの定義]
- CUDAプロジェクト ... [CUDA C/C++]→[Host]→[Preprocessor Definitions]
の二点である。
この記事のトラックバックURL: