具有 CUDA 成员的 C++ class dll?
C++ class dll with CUDA member?
我有一个基于 C++ class 的 dll。我想将一些 class 成员转换为基于 CUDA 的操作。
我用的是VS2012,WINDOWS7,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__
关键字
class 个成员可以工作,但我需要更改后缀
cpp 文件到 cu?
- 我也试过从一开始就创建一个cuda项目,但是当我选择创建一个CUDA项目时,VS2012似乎没有给我创建一个dll的选项。
我很困惑将这个基于 C++ class 的 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
将路径添加到 header,例如 D:\cudaSuperProjector\include;
。然后转到 Linker -> Input
并添加 cudaSuperProjector.lib;
.
现在您的项目应该可以正常编译,但是当您 运行 它会显示错误
The program can't start because cudaSuperProjector.dll is missing from
your computer. Try reinstalling the program to fix this problem.
您需要将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
)。
我有一个基于 C++ class 的 dll。我想将一些 class 成员转换为基于 CUDA 的操作。
我用的是VS2012,WINDOWS7,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__
关键字 class 个成员可以工作,但我需要更改后缀 cpp 文件到 cu? - 我也试过从一开始就创建一个cuda项目,但是当我选择创建一个CUDA项目时,VS2012似乎没有给我创建一个dll的选项。
我很困惑将这个基于 C++ class 的 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
将路径添加到 header,例如D:\cudaSuperProjector\include;
。然后转到Linker -> Input
并添加cudaSuperProjector.lib;
.现在您的项目应该可以正常编译,但是当您 运行 它会显示错误
The program can't start because cudaSuperProjector.dll is missing from your computer. Try reinstalling the program to fix this problem.
您需要将
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
)。