Cuda 为什么用cuBLAS计算L2范数会导致错误?

Cuda 为什么用cuBLAS计算L2范数会导致错误?,cuda,thrust,gpu,cublas,Cuda,Thrust,Gpu,Cublas,编辑2:包括更完整的程序 编辑1:包括完整的程序 我想用cuBLAS计算向量的L2范数。我的代码如下 void GPU_Print_Matrix(real_t *A, int nrows, int ncols) { real_t *hostA = (real_t*)malloc(nrows*ncols * sizeof(real_t)); CUDA_SAFE_CALL(cudaMemcpy(hostA, A, nrows*ncols * sizeof(real_t), cudaMemcp

编辑2:包括更完整的程序

编辑1:包括完整的程序

我想用cuBLAS计算向量的L2范数。我的代码如下

void GPU_Print_Matrix(real_t *A, int nrows, int ncols) {
  real_t *hostA = (real_t*)malloc(nrows*ncols * sizeof(real_t));
  CUDA_SAFE_CALL(cudaMemcpy(hostA, A, nrows*ncols * sizeof(real_t), cudaMemcpyDeviceToHost));

  cout << "GPU Matrix of Size: " << nrows << "x" << ncols << endl;
  for (int i = 0; i < nrows; ++i) {
    for (int j = 0; j < ncols; ++j) {
      cout << fixed << setprecision(PRINT_PRECISION) << hostA[j*nrows + i] << " ";
    }
    cout << endl;
  }

  free(hostA);
  cout << endl;
}

void GPU_Random_Vector(thrust::device_vector <real_t> &vec) {
  thrust::counting_iterator<unsigned int> index_sequence_begin(rand());
  thrust::transform(index_sequence_begin, index_sequence_begin + vec.size(), vec.begin(), RANDOM(-initRange, initRange));
}

int main(int argc, char *argv[]) {
  srand(clock());
  cout << "# Running NMT" << endl;

  //ParseOpts(argc, argv);

  cublasHandle_t handle;
  CUBLAS_SAFE_CALL(cublasCreate(&handle));
  thrust::device_vector <real_t> x(10);
  GPU_Random_Vector(x);
  GPU_Print_Matrix(thrust::raw_pointer_cast(&x[0]), 10, 1);
  real_t nrm = 0; 
  CUBLAS_SAFE_CALL(cublasXnrm2(handle, 10, thrust::raw_pointer_cast(&x[0]), 1, &nrm));
  cout << "nrm2 = " << nrm << endl;
}
#define CUBLAS_SAFE_CALL(call)                                                     \
{                                                                                  \
  const cublasStatus_t stat = call;                                                \
  if (stat != CUBLAS_STATUS_SUCCESS) {                                             \
    cout << "cuBlas Error: " << __FILE__ << ":" << __LINE__ << endl;               \
    cout << "  Code: " << stat << endl;                                            \
    exit(1);                                                                       \
  }                                                                                \
}
GPU\u Random\u Vector
GPU\u Print\u Matrix
之前已确认工作正常。另外,
cublasHandle[singleGPU]
在被调用之前已经初始化。当我运行程序时,我有以下输出

// GPU_Print_Matrix
GPU Matrix of Size: 10x1
0.0652332678 
0.0747700930 
0.0274266358 
-0.0885794610 
-0.0192640368 
-0.0942506194 
0.0283640027 
-0.0411146656 
-0.0460337885 
-0.0970785618 

cuBlas Error: nmt.cu:2252
  Code: 14

发生了什么事?关于如何解释cuBLAS的错误号,有什么参考资料吗?非常感谢。

CUBLAS错误14是
CUBLAS\u状态\u内部错误
,通常意味着在L2 norm调用结束时,内部设备到主机的复制失败。但是,如果没有关于您的代码所做的其他事情的上下文,就无法说明为什么会发生这种情况

如果您发布的代码被组装并充实成一个完整的演示案例(简单的随机数播种错误得到纠正),如下所示:

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cublas_v2.h>
#include <thrust/transform.h>
#include <thrust/device_vector.h>
#include <thrust/device_ptr.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/random.h>

typedef float real_t;

#define CUBLAS_SAFE_CALL(call)                                                     \
{                                                                                  \
  const cublasStatus_t stat = call;                                                \
  if (stat != CUBLAS_STATUS_SUCCESS) {                                             \
    std::cout << "cuBlas Error: " << __FILE__ << ":" << __LINE__ << std::endl;     \
    std::cout << "  Code: " << stat << std::endl;                                  \
    exit(1);                                                                       \
  }                                                                                \
}

#define PRINT_PRECISION (6)

struct RANDOM
{
    real_t a, b;

    __host__ __device__
    RANDOM(real_t _a=0, real_t _b=1) : a(_a), b(_b) {};

    __host__ __device__
        real_t operator()(const unsigned int n) const
        {
            thrust::default_random_engine rng;
            thrust::uniform_real_distribution<float> dist(a, b);
            rng.discard(n);

            return dist(rng);
        }
};

void GPU_Print_Matrix(real_t *A, int nrows, int ncols) {
  real_t *hostA = (real_t*)malloc(nrows*ncols * sizeof(real_t));
  cudaMemcpy(hostA, A, nrows*ncols * sizeof(real_t), cudaMemcpyDeviceToHost);

  std::cout << "GPU Matrix of Size: " << nrows << "x" << ncols << std::endl;
  for (int i = 0; i < nrows; ++i) {
    for (int j = 0; j < ncols; ++j) {
      std::cout << std::fixed << std::setprecision(PRINT_PRECISION) << hostA[j*nrows + i] << " ";
    }
    std::cout << std::endl;
  }

  free(hostA);
  std::cout << std::endl;
}

void GPU_Random_Vector(thrust::device_vector <real_t> &vec) {
  const real_t initRange = 10;
  thrust::counting_iterator<unsigned int> index_sequence_begin(std::rand());
  thrust::transform(index_sequence_begin, index_sequence_begin + vec.size(), vec.begin(), RANDOM(-initRange, initRange));
}

int main(int argc, char *argv[]) {
  std::srand(std::time(0));
  std::cout << "# Running NMT" << std::endl;

  cublasHandle_t handle;
  CUBLAS_SAFE_CALL(cublasCreate(&handle));
  thrust::device_vector <real_t> x(10);
  GPU_Random_Vector(x);
  GPU_Print_Matrix(thrust::raw_pointer_cast(&x[0]), 10, 1);
  real_t nrm = 0; 
  CUBLAS_SAFE_CALL(cublasSnrm2(handle, 10, thrust::raw_pointer_cast(&x[0]), 1, &nrm));
  std::cout << "nrm2 = " << nrm << std::endl;
}

它按预期工作。您应该能够编译并运行它来确认这一点。因此,从这一点,我们只能得出结论,你有另一个问题,你没有描述。但这可能有助于缩小可能性列表。

我已经编辑了这个问题,将完整的程序包括在内。@HieuPham:对不起,这不是完整的程序。什么是
GPU\U随机\U向量
GPU\U打印\U矩阵
?此代码仍然不完整且不可编译。在您能够提供再现您的问题的代码之前,您不可能提供和回答您的问题。那么这里发生了什么?一年多前,我还没来得及阅读,你就对我的答案添加和删除了一条评论,但结论是什么?您是否能够使用我发布的代码重现您遇到的问题?您是否最终在自己的代码中找到了问题的根源?这里是否有需要添加或接受的答案?还是应该删除这个问题?
>nvcc -arch=sm_21 -run runkkari.cu -lcublas
runkkari.cu
   Creating library a.lib and object a.exp
# Running NMT
GPU Matrix of Size: 10x1
-5.712992
8.181723
-0.086308
-6.177320
-5.442665
-2.889552
-1.555665
6.506872
-6.800190
8.024273

nrm2 = 18.196394