一、建立CUDA工程
1、新建动态链接库项目
2、添加cuda文件
可以添加已有的.cu文件,也可以重新建立一个
各个文件的内容:
targetver.h
#pragma once
// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并
// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
#include <SDKDDKVer.h>
extern "C" __declspec(dllexport) int _stdcall vectorAdd(int c[], int a[], int b[], int size);
cuda.cpp
// cuda.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
__global__ void addKernel(int *c, const int *a, const int *b);
//向量相加
int _stdcall vectorAdd(int c[], int a[], int b[], int size)
{
int result = -1;
int *dev_a = 0;
int *dev_b = 0;
int *dev_c = 0;
cudaError_t cudaStatus;
// 选择用于运行的GPU
cudaStatus = cudaSetDevice(0);
if (cudaStatus != cudaSuccess) {
result = 1;
goto Error;
}
// 在GPU中为变量dev_a、dev_b、dev_c分配内存空间.
cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(int));
if (cudaStatus != cudaSuccess) {
result = 2;
goto Error;
}
cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(int));
if (cudaStatus != cudaSuccess) {
result = 3;
goto Error;
}
cudaStatus = cudaMalloc((void**)&dev_b, size * sizeof(int));
if (cudaStatus != cudaSuccess) {
result = 4;
goto Error;
}
// 从主机内存复制数据到GPU内存中.
cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess) {
result = 5;
goto Error;
}
cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(int), cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess) {
result = 6;
goto Error;
}
// 启动GPU内核函数
addKernel <<<1, size >>> (dev_c, dev_a, dev_b);
// 采用cudaDeviceSynchronize等待GPU内核函数执行完成并且返回遇到的任何错误信息
cudaStatus = cudaDeviceSynchronize();
if (cudaStatus != cudaSuccess) {
result = 7;
goto Error;
}
// 从GPU内存中复制数据到主机内存中
cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost);
if (cudaStatus != cudaSuccess) {
result = 8;
goto Error;
}
result = 0;
// 重置CUDA设备,在退出之前必须调用cudaDeviceReset
cudaStatus = cudaDeviceReset();
if (cudaStatus != cudaSuccess) {
return 9;
}
Error:
//释放设备中变量所占内存
cudaFree(dev_c);
cudaFree(dev_a);
cudaFree(dev_b);
return result;
}
testCuda.cu
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
__global__ void addKernel(int *c, const int *a, const int *b);
//CUDA核函数
__global__ void addKernel(int *c, const int *a, const int *b)
{
int i = threadIdx.x;
c[i] = a[i] + b[i];
}
3、配置编译环境
运行CUDA程序的文件,都修改属性页-常规-项类型-CUDA C/C++
(1)包含目录配置
项目属性–>属性–>配置属性–>VC++目录–>包含目录
添加包含目录: $(CUDA_PATH)\include
(2)库目录配置
VC++目录–>库目录
添加库目录: $(CUDA_PATH)\lib\x64
(3)依赖项配置
配置属性–>链接器–>输入–>附加依赖项
添加库文件:
cublas.lib
cuda.lib
cudadevrt.lib
cudart.lib
cudart_static.lib
OpenCL.lib
cufft.lib
(4)修改以下属性
4、生成
二、C#调用
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
//int a = 2;
//int b = 3;
//int c =0;
//c=Class1.Add(a,b);
int[] a = { 1,2,3};
int[] b = { 1, 2, 3 };
int[] c = { 1, 2, 3 };
int size = 3;
int d = 0;
d = Class1.vectorAdd(a,b,c,size);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Class1
{
//bool __stdcall SetLaserMode(int laserType,int standby,float frequency, float pulseWidth);
//[DllImport("Dll1.dll", EntryPoint = "Add", CallingConvention = CallingConvention.Cdecl)]
//[DllImport("Dll1.dll")]
// public static extern int Add(int a, int b);
[DllImport("cuda.dll")]
public static extern int vectorAdd(int []c, int[] a, int[] b, int size);
}
}
}
参考:
https://blog.youkuaiyun.com/weixin_40106401/article/details/101352609