我有一个基于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.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应该为CUDA C/C++
转到项目的属性,然后在General中将Configuration Type的值设置为Dynamic Library (.dll)。现在,用于创建库的所有内容都已准备就绪。编译该项目,并在输出文件夹中找到cudaSuperProjector.dllcudaSuperProjector.lib。创建目录cudaSuperProjector\lib并在其中复制cudaSuperProjector.dllcudaSuperProjector.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)。

10-08 09:17