Cuda cublas地址超出特定矩阵大小的界限

Cuda cublas地址超出特定矩阵大小的界限,cuda,cublas,Cuda,Cublas,当我运行以下代码来计算矩阵乘法y=X*B时: #include <iostream> #include <Eigen/Dense> #include <cuda_runtime.h> #include "cublas_v2.h" using namespace Eigen; int main(){ int N = 240000; int K = 3; int p = 9700; MatrixXf X_host = M

当我运行以下代码来计算矩阵乘法y=X*B时:

#include <iostream>
#include <Eigen/Dense>
#include <cuda_runtime.h>
#include "cublas_v2.h"


using namespace Eigen;

int main(){
  int N = 240000;
  int K = 3;
  int p = 9700;

  MatrixXf X_host = MatrixXf::Zero(N, p);
  MatrixXf B_host = MatrixXf::Zero(p, K);
  MatrixXf y_host(N, K);

  float *X_dev;
  float *B_dev;
  float *y_dev;

  cudaMalloc((void**)&X_dev, sizeof(float) * p * N);
  cudaMalloc((void**)&B_dev, sizeof(float) * p * K);
  cudaMalloc((void**)&y_dev, sizeof(float) * N * K);

  cudaMemcpy(X_dev, X_host.data(), sizeof(float)*p*N, cudaMemcpyHostToDevice);
  cudaMemcpy(B_dev, B_host.data(), sizeof(float)*p*K, cudaMemcpyHostToDevice);

  cublasHandle_t handle;
  cublasCreate(&handle);

  cudaError_t error = cudaGetLastError();
  if(error != cudaSuccess)
  {
    std::cout << "CUDA error: " << cudaGetErrorString(error) << std::endl;
  } else {
    std::cout << "No problem before cublas call\n";
  }

  float alpha = 1.0;
  float beta = 0.0;
  cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, 
              N, K, p, &alpha, 
              X_dev, N, B_dev, p, &beta, y_dev, N);

  cudaDeviceSynchronize();
  error = cudaGetLastError();
  if(error != cudaSuccess)
  {
      std::cout << "CUDA error: " << cudaGetErrorString(error) << std::endl;
  }

  cublasDestroy(handle);
  cudaFree(X_dev);
  cudaFree(B_dev);
  cudaFree(y_dev);
  return 0;
}

大约有100个这样的地址越界错误,它们的数量在不同的运行中有所不同。当我将K设置为更大的数字(例如10)时,问题就消失了。有人知道会发生什么吗?我在CentOS 7上使用CUDA 10.1和P100。谢谢

2020年9月21日更新:
这个问题在我更新到CUDA 11之后就消失了。

如评论中所述,这似乎是库布拉斯图书馆的内部问题。我会发表社论并猜测,他们没有针对这个不寻常的维度问题的测试覆盖率,因为内部产品维度非常小,而且这个bug通过了发布前测试,但未被检测到


与常见的bug一样,您最好将问题中的代码作为复制案例提交到具有的票证上

我能够重现这个问题。我猜你发现了库布拉斯的一个缺陷。根据我的测试,CUDA 10.2.89(目前最新版本)仍然存在此问题。如果我切换到Volta V100 GPU,问题就会消失。很明显,在幕后,CUBLAS使用不同的内核在P100和V100上实现此操作,我怀疑这是行为差异的原因,也是我没有立即怀疑代码中存在缺陷的原因,尽管我没有仔细研究它。您可能希望在developer.nvidia.com上提交错误报告。这将在下一个CUDA公共版本(10.2.89之后)中修复。关于这件事,我不能再回答任何问题了。
========= Invalid __global__ read of size 4
=========     at 0x00000a88 in void gemmSN_NN_kernel<float, int=256, int=4, int=2, int=8, int=4, int=4, cublasGemvTensorStridedBatched<float const >, cublasGemvTensorStridedBatched<float>>(cublasGemmSmallNParams<float const , cublasGemvTensorStridedBatched<float const >, float>)
=========     by thread (223,0,0) in block (190,0,0)
=========     Address 0x2b660269807c is out of bounds