我有一个基于C ++类的dll。我想将某些类成员转换为基于CUDA的操作。
我正在使用VS2012,WINDOWS 7,CUDA6.5,sm_20;
说原始的SuperProjector.h文件是这样的:
class __declspec(dllexport) SuperProjector
{
public:
SuperProjector(){};
~SuperProjector(){};
void sumVectors(float* c, float* a, float* b, int N);
};
以及SuperProjector.cpp中原始的
sumVector()
函数void SuperProjector::sumVectors(float* c, float* a, float* b, int N)
{
for (int n = 1; n < N; b++)
c[n] = a[n] + b[n];
}
我被困在如何将sumVector()转换为CUDA上。特别:
我读了一些帖子,说在前面添加
__global__ __device__
关键字的班级成员可以工作,但是我需要更改后缀
CPP文件到铜?
我也尝试从一开始就创建一个cuda项目,但是当我选择创建CUDA项目后,VS2012似乎没有给我创建dll的选项。
我非常困惑将这种基于C ++类的dll的某些成员转换为某些CUDA内核函数的最佳方法是什么。我感谢任何人都可以提出一些想法,或者提供一些非常简单的示例来更好。
最佳答案
创建CUDA项目,将其命名为cudaSuperProjector
并添加两个文件SuperProjector.cu
和SuperProjector.h
cudaSuperProjector.h
class __declspec(dllexport) cudaSuperProjector {
public:
cudaSuperProjector(){ }
~cudaSuperProjector(){ }
void sumVectors(float* c, float* a, float* b, int N);
};
cudaSuperProjector.cu
#include <stdio.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include "cudaSuperProjector.h"
__global__ void addKernel(float *c, const float *a, const float *b) {
int i = threadIdx.x;
c[i] = a[i] + b[i];
}
// Helper function for using CUDA to add vectors in parallel.
cudaError_t addWithCuda(float *c, const float *a, const float *b, unsigned int size) {
float *dev_a = 0;
float *dev_b = 0;
float *dev_c = 0;
cudaError_t cudaStatus;
// Choose which GPU to run on, change this on a multi-GPU system.
cudaStatus = cudaSetDevice(0);
// Allocate GPU buffers for three vectors (two input, one output) .
cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(float));
cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(float));
cudaStatus = cudaMalloc((void**)&dev_b, size * sizeof(float));
// Copy input vectors from host memory to GPU buffers.
cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(float), cudaMemcpyHostToDevice);
cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(float), cudaMemcpyHostToDevice);
// Launch a kernel on the GPU with one thread for each element.
addKernel << <1, size >> >(dev_c, dev_a, dev_b);
// Check for any errors launching the kernel
cudaStatus = cudaGetLastError();
// cudaDeviceSynchronize waits for the kernel to finish, and returns
// any errors encountered during the launch.
cudaStatus = cudaDeviceSynchronize();
// Copy output vector from GPU buffer to host memory.
cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(float), cudaMemcpyDeviceToHost);
return cudaStatus;
}
void cudaSuperProjector::sumVectors(float* c, float* a, float* b, int N) {
cudaError_t cudaStatus = addWithCuda(c, a, b, N);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaSuperProjector::sumVectors failed!");
}
}
注意:在文件
cudaSuperProjector.cu
的属性中,Item Type
应该为CUDA C/C++
。转到项目的属性,然后在
General
中将Configuration Type
的值设置为Dynamic Library (.dll)
。现在,用于创建库的所有内容都已准备就绪。编译该项目,并在输出文件夹中找到cudaSuperProjector.dll
和cudaSuperProjector.lib
。创建目录cudaSuperProjector\lib
并在其中复制cudaSuperProjector.dll
和cudaSuperProjector.lib
。还要创建cudaSuperProjector\include
并在其中复制cudaSuperProjector.h
。创建另一个
Visual C++
项目,我们称之为SuperProjector
。将文件SuperProjector.cpp
添加到项目中。SuperProjector.cpp
#include <stdio.h>
#include "cudaSuperProjector/cudaSuperProjector.h"
int main(int argc, char** argv) {
float a[6] = { 0, 1, 2, 3, 4, 5 };
float b[6] = { 1, 2, 3, 4, 5, 6 };
float c[6] = { };
cudaSuperProjector csp;
csp.sumVectors(c, a, b, 6);
printf("c = {%f, %f, %f, %f, %f, %f}\n",
c[0], c[1], c[2], c[3], c[4], c[5]);
return 0;
}
在项目的属性中,将
dll
的路径添加到lib
的文件,将VC++ Directories -> Library Directories
的文件添加到D:\cudaSuperProjector\lib;
,在VC++ Directories -> Include Directories
的表头中添加路径,例如D:\cudaSuperProjector\include;
。然后转到Linker -> Input
并添加cudaSuperProjector.lib;
。现在您的项目应该可以正常编译了,但是当您运行它时,它将向您显示错误
该程序无法启动,因为缺少cudaSuperProjector.dll
你的电脑。尝试重新安装该程序以解决此问题。
您需要将
cudaSuperProjector.dll
复制到项目的输出文件夹,因此它将与SuperProjector.exe
放在同一文件夹下。您可以手动执行或添加copy D:\cudaSuperProjector\lib\cudaSuperProjector.dll $(SolutionDir)$(Configuration)\
在
Build Events -> Post-Build Events -> Command Line
中,其中,
$(SolutionDir)$(Configuration)\
是解决方案的输出路径(请参见Configuration Properties -> General -> Output Directory
)。