具有CUDA成员的C++类dll

C++ class dll with CUDA member?

本文关键字:dll C++ CUDA 成员 具有      更新时间:2023-10-16

我有一个基于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。具体而言:

  1. 我读到一些帖子说在前面添加__global__ __device__关键字的类成员将起作用,但因此我需要更改的后缀cpp文件到cu
  2. 我也试图从一开始就创建一个cuda项目,但一旦我选择创建一个cuda项目,VS2012似乎就没有给我创建dll的选项

我很困惑将基于C++类的dll的一些成员转换为一些CUDA内核函数的最佳方法是什么。我很感激任何人能提供一些想法,或者用一些非常简单的例子来更好。

  1. 创建CUDA项目,称之为cudaSuperProjector,并添加两个文件SuperProjector.cuSuperProjector.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。

  2. 转到项目的属性,并在General中设置Configuration TypeDynamic Library (.dll)的值。现在创建库的一切都准备好了。编译这个项目,在输出文件夹中你会发现cudaSuperProjector.dllcudaSuperProjector.lib。创建目录cudaSuperProjectorlib并将cudaSuperProjector.dllcudaSuperProjector.lib复制到那里。同时创建cudaSuperProjectorinclude并在其中复制cudaSuperProjector.h

  3. 创建另一个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;
    }
    
  4. 在项目的属性中,将路径添加到dll,将lib文件添加到VC++ Directories -> Library Directories,例如D:cudaSuperProjectorlib;,在VC++ Directories -> Include Directories中,将通道添加到标头,例如D:cudaSuperProjectorinclude;。然后转到Linker -> Input并添加cudaSuperProjector.lib;

  5. 现在你的项目应该编译得很好,但当你运行它时,它会显示错误

    程序无法启动,因为中缺少cudaSuperProjector.dll你的电脑。请尝试重新安装程序以解决此问题。

    您需要将cudaSuperProjector.dll复制到项目的输出文件夹,因此它将与SuperProjector.exe位于同一文件夹下。您可以手动操作或添加

    copy D:cudaSuperProjectorlibcudaSuperProjector.dll $(SolutionDir)$(Configuration)
    

    在CCD_ 35中,其中$(SolutionDir)$(Configuration)是解的输出路径(参见Configuration Properties -> General -> Output Directory)。