普通のdll作成と何一つ変わらないので記事にするか迷ったのだが、一カ所だけわかりにくかったので念のためにまとめておく。
環境は Visual C++ 2017 + CUDA 9.2
手順は以下の通りである。
#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(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);
#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側のプロジェクトのファイル名が、 (上記②,③)
B. _declspecの分岐のためのプリプロセッサを定義する場所が、 (上記⑤)
の二点である。