在C++/CLI和C#

在C++/CLI和C#,c#,c++11,cuda,c++-cli,cublas,C#,C++11,Cuda,C++ Cli,Cublas,我用Visual Studio用C++11/CLI编写了一个包装器,以使用CUDA的CuBLAS。我正在使用CUDA Toolkit 7.0 以下是我的包装器的源代码: #pragma once #include "stdafx.h" #include "BLAS.h" #include "cuBLAS.h" namespace lab { namespace Mathematics { namespace CUDA {

我用Visual Studio用C++11/CLI编写了一个包装器,以使用CUDA的CuBLAS。我正在使用CUDA Toolkit 7.0

以下是我的包装器的源代码:

#pragma once

#include "stdafx.h"
#include "BLAS.h"
#include "cuBLAS.h"

namespace lab
{
    namespace Mathematics
    {
        namespace CUDA
        {

            void BLAS::DAXPY(int n, double alpha, const array<double> ^x, int incx, array<double> ^y, int incy)
            {
                pin_ptr<double> xPtr = &(x[0]);
                pin_ptr<double> yPtr = &(y[0]);
                pin_ptr<double> alphaPtr = &alpha;

                cuBLAS::DAXPY(n, alphaPtr, xPtr, incx, yPtr, incy);
            }
       }
   }
}

编辑:我添加了David Yaw的新建议,还为所有cuda操作添加了错误检查。但是由于可读性,我没有在这里写所有的错误检查。仍然不工作。

您的错误在这些行中

// Initialize the input matrix and vector
cublasSetVector(n, sizeof(*devX), x, incx, devX, incx);

// Call cuBLAS function
cublasDaxpy(handle, n, alpha, devX, incx, devY, incy);

// Retrieve resulting vector
cublasGetVector(n, sizeof(*devY), devY, incy, y, incy);
引用(重点):

此函数将向量x乘以标量α,然后将其添加到向量y中,并用结果覆盖最新的向量


Y
既是一个输入又是一个输出,但您从不设置值,因此您会得到未初始化内存中的任何垃圾。在调用
cublasedaxpy
之前,添加对
cublasetvector
的调用,以设置
devY
的初始值

所以编写的代码是完全完美的。我唯一的问题是没有正确编译它。根据,每次更改cuda程序(准确地说是.cu文件)时,都必须重新构建整个项目,以便Prallel Nsight将其编译。否则它将坚持到最后一次编译


这是一个非常小的点,但可能会节省很多人,一整天的调试,结果一事无成。

这是一个很好的点,但仍然不起作用。我甚至在cuda代码中添加了很多错误检查,但仍然不起作用。就好像它从来没有达到cuda代码一样。不过,我在主要问题中添加了您的观点和例外情况。这对于VisualStudio中的任何类型的项目都是正确的。这不是CUDA或parallel nsight独有的。更改代码后,必须重新编译。这是任何涉及编译代码的计算机编程的基本原则。
void cuBLAS::DAXPY(int n, const double *alpha, const double *x, int incx, double *y, int incy)
        {

            cudaError_t cudaStat;
            cublasStatus_t stat;

            // Allocate GPU memory
            double *devX, *devY;
            cudastat = cudaMalloc((void **)&devX, (size_t)n*sizeof(*devX));

            if (cudaStat != cudaSuccess) {
                // throw exception

                std::ostringstream msg;
                msg << "device memory allocation failed: fail.Stat = " << cudaStat;
                throw new std::exception(msg.str().c_str());
            }
            cudaMalloc((void **)&devY, (size_t)n*sizeof(*devY));

            // Create cuBLAS handle
            cublasHandle_t handle;
            cublasCreate(&handle);

            // Initialize the input matrix and vector
            cublasSetVector(n, sizeof(*devX), x, incx, devX, incx);
            cublasSetVector(n, sizeof(*devY), y, incy, devY, incy);

            // Call cuBLAS function
            cublasDaxpy(handle, n, alpha, devX, incx, devY, incy);

            // Retrieve resulting vector
            cublasGetVector(n, sizeof(*devY), devY, incy, y, incy);

            // Free GPU resources
            cudaFree(devX);
            cudaFree(devY);
            cublasDestroy(handle);
        }
// Initialize the input matrix and vector
cublasSetVector(n, sizeof(*devX), x, incx, devX, incx);

// Call cuBLAS function
cublasDaxpy(handle, n, alpha, devX, incx, devY, incy);

// Retrieve resulting vector
cublasGetVector(n, sizeof(*devY), devY, incy, y, incy);