在C++/CLI和C#
我用Visual Studio用C++11/CLI编写了一个包装器,以使用CUDA的CuBLAS。我正在使用CUDA Toolkit 7.0 以下是我的包装器的源代码:在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 {
#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 = α
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);