结合了几篇文章的方法,前半部分主要参考 http://hi.baidu.com/yilinghl/item/a94b63959e89a3f028164739
需要补充的一点是,编写DLL工程时,需要添加链接器,方法如 http://www.cnblogs.com/chunshan/archive/2011/08/15/2139992.html 所示,在Linker | Input中添加 cudart.lib。
后半部分调用CUDA DLL主要参考:
http://blog.csdn.net/openhero/article/details/4059411
http://www.cnblogs.com/c1230v/articles/1401448.html
http://www.cppblog.com/amyvmiwei/archive/2008/01/02/40202.html
步骤总结起来就是:
1. 新建DLL工程,在工程上单击右键 -> 生成自定义,勾选CUDA;
2. 进入工程属性页,选择Linker | Input,添加 cudart.lib;
3. 新建CUDA文件,编写代码,Release 生成dll和lib;
4. 新建调用工程,编写代码,生成,将dll和lib复制到新工程exe同目录下,运行。
主要代码:
cuda.cu
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
__global__ void vecAdd(int *a, int *b, int *c)
{
int i = threadIdx.x;
c[i] = a[i] + b[i];
}
bool cudaVecAdd(int *a, int *b, int *c, int n)
{
int *dev_a;
int *dev_b;
int *dev_c;
cudaError_t cudaStatus;
cudaStatus = cudaSetDevice(0);
if (cudaStatus != cudaSuccess) {
return false;
}
cudaMalloc((void**)&dev_a, n * sizeof(int));
cudaMemcpy(dev_a, a, n * sizeof(int), cudaMemcpyHostToDevice);
cudaMalloc((void**)&dev_b, n * sizeof(int));
cudaMemcpy(dev_b, b, n * sizeof(int), cudaMemcpyHostToDevice);
cudaMalloc((void**)&dev_c, n * sizeof(int));
vecAdd<<<1, n>>>(dev_a, dev_b, dev_c);
cudaDeviceSynchronize();
cudaMemcpy(c, dev_c, n * sizeof(int), cudaMemcpyDeviceToHost);
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
return true;
}
CUDA_dll.cpp
bool cudaVecAdd(int *a, int *b, int *c, int n);
extern "C" _declspec(dllexport) bool cuda_vec_add(int *a, int *b, int *c, int n)
{
return cudaVecAdd(a, b, c, n);
}
test.cpp
#include "stdafx.h"
#include <Windows.h>
typedef int (*HFUNC)(int *a, int *b, int *c, int n);
int _tmain(int argc, _TCHAR* argv[])
{
int a[2] = {1, 2};
int b[2] = {3, 4};
int c[2] = {0, 0};
HINSTANCE hDll = LoadLibrary(__T("CUDA_dll.dll"));
if (hDll)
{
HFUNC hFun = (HFUNC)GetProcAddress(hDll, "cuda_vec_add");
if (hFun)
{
hFun(a, b, c, 2);
printf("%d %d\n", c[0], c[1]);
}
}
return 0;
}
上面是动态调用DLL,静态调用方法如下:
1. 将dll文件复制到DEBUG目录下,lib文件复制到工程文件下;
2. 将dll的头文件包含到工程目录下;
3. 直接在程序中调用即可。
CUDA_dll.h
#pragma comment(lib, "CUDA_dll.lib")
extern "C" _declspec(dllimport) bool cuda_vec_add(int *a, int *b, int *c, int n);
test.cpp
#include "CUDA_dll.h"
int _tmain(int argc, _TCHAR* argv[])
{
int a[2] = {1, 2};
int b[2] = {3, 4};
int c[2] = {0, 0};
cuda_vec_add(a, b, c, 2);
printf("%d %d\n", c[0], c[1]);
return 0;
}