具有CUDA成员的C++类dll
C++ class dll with CUDA member?
我有一个基于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 中的原始CCD_ 1函数
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文件到cu - 我也试图从一开始就创建一个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
应为sumVector()
0。 -
转到项目的属性,并在
General
中设置Configuration Type
到Dynamic Library (.dll)
的值。现在创建库的一切都准备好了。编译这个项目,在输出文件夹中你会发现cudaSuperProjector.dll
和cudaSuperProjector.lib
。创建目录cudaSuperProjectorlib
并将cudaSuperProjector.dll
和cudaSuperProjector.lib
复制到那里。同时创建cudaSuperProjectorinclude
并在其中复制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:cudaSuperProjectorlib;
,在VC++ Directories -> Include Directories
中,将通道添加到标头,例如D:cudaSuperProjectorinclude;
。然后转到Linker -> Input
并添加cudaSuperProjector.lib;
。 -
现在你的项目应该编译得很好,但当你运行它时,它会显示错误
程序无法启动,因为中缺少cudaSuperProjector.dll你的电脑。请尝试重新安装程序以解决此问题。
您需要将
cudaSuperProjector.dll
复制到项目的输出文件夹,因此它将与SuperProjector.exe
位于同一文件夹下。您可以手动操作或添加copy D:cudaSuperProjectorlibcudaSuperProjector.dll $(SolutionDir)$(Configuration)
在CCD_ 35中,其中
$(SolutionDir)$(Configuration)
是解的输出路径(参见Configuration Properties -> General -> Output Directory
)。
- 挂起和取消挂起一个文件DLL
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 导入库可以跨dll版本工作吗
- 从C++dll访问C#中的一行主要参数
- 链接到自行创建的dll失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何指定我希望我的LIB链接到的DLL文件?-Visual Studio 2019
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- C++:将外部库链接到dll库
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 不同的Visual Studio版本中缺少.dll
- 从DLL中删除类的实例
- 如何包装第三方DLL在R中使用
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- Python ctypes:不会按预期加载 dll
- 在 C++/CLI 中将 .NET 事件从一个 DLL 引发到另一个 DLL