使用cublas gemm函数(cublasSgemm)的乘法矩阵大小上限

时间:2015-12-25 09:13:51

标签: cuda nvidia nvcc nsight cublas

这是我第一次无法从之前发布的问题的答案中获得帮助。

我已经非常成功地使用 cublasSgemm 乘以平方矩阵。 但是,最近我观察到如果行数或列数增加超过269 (即270 x 270矩阵及以上),当我调试时,我开始得到“内存访问冲突”启用Nsight Cuda Memory Checker 。如果我没有启用内存检查器,那么没有例外,结果也是正确的。

以下是确切的错误消息

  

内存检查器检测到64次访问冲突

     

存储上的访问冲突(全局内存)

是我的gpu或cublasSgemm 功能的限制? 我该怎么做才能解决这个问题?

我在Quadro FX 1800M(sm_12)上使用Cuda 6.5和MS Visual Studio 2012。操作系统是MS Windows 7 64位。

我在下面添加了代码的精简版

#include <stdio.h>
#include <cuda.h>
#include <cublas_v2.h>

int main(int argc, char **argv)
{
const int m = 269; // for 1 - 269 there are no access violations
// but as soon as m >= 270 Memory Checker throws memory access violations
// Note: the results are correct even with these violations
float *X = new float[m*m];
float *Y = new float[m*m];
float *Z = new float[m*m];
float *devX, *devY, *devZ;
cublasHandle_t handle;
cudaError_t err;
cublasStatus_t err1;

//simple initialization
for(unsigned long i = 0; i < m*m; i++)
{
    X[i] = 1;
    Y[i] = 2;
}

err1 = cublasCreate(&handle);
if(err1 != CUBLAS_STATUS_SUCCESS)
  return 1;

err = cudaMalloc((void **)&devX, m*m*sizeof(*devX));
if(err != CUBLAS_STATUS_SUCCESS)
  return 1;

err = cudaMalloc((void **)&devY, m*m*sizeof(*devY));
if(err != CUBLAS_STATUS_SUCCESS)
  return 1;

err = cudaMalloc((void **)&devZ, m*m*sizeof(*devZ));
if(err != CUBLAS_STATUS_SUCCESS)
  return 1;


err1 = cublasSetMatrix(m, m, sizeof(*X), X, m, devX, m);
if(err1 != CUBLAS_STATUS_SUCCESS)
  return 1;

err1 = cublasSetMatrix(m, m, sizeof(*Y), Y, m, devY, m);
if(err1 != CUBLAS_STATUS_SUCCESS)
  return 1;

////////////////////////////////////////////////////////////
printf("Reached sgemm without error\n");
const float alpha = 1.0f, beta = 0.0f;
// cuda memory checker detects access violations when m > 269
cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, m, m, m, &alpha, devX, m, devY, m, &beta, devZ, m);
cudaDeviceSynchronize();
printf("reached after sgemm without error\n");
////////////////////////////////////////////////////////////

err1 = cublasGetMatrix(m, m, sizeof(*devZ), devZ, m, Z, m);
if(err != CUBLAS_STATUS_SUCCESS)
  return 1;

// just printing a single element for brevity
printf("....%f....", Z[0]); 

cudaFree(devX);
cudaFree(devY);
cudaFree(devZ);
cublasDestroy_v2(handle);
getchar();
return 0;
}

EDITED

Update: Same result even after disabling TDR, as shown in this image

再次编辑

编译并运行下载的cublas示例:

https://people.maths.ox.ac.uk/gilesm/cuda/prac5/simpleCUBLAS.cpp

再次 N&gt; 500 得到与以前相同的错误。

如果Cuda Memory Checker 未启用,那么此程序成功运行并显示“test passed”消息。

实际上,访问冲突从N = 350开始,但此时它们是不可预测的,即它们有时会发生,而其他时候则不会发生。但对于N&gt; 500他们总是出现

使用过cudaDeviceGetLimit(&amp; heap_size,cudaLimitMallocHeapSize);获取341_s973836字节的heap_size。所以,大概这也不是问题!

EDITED 我现在在'C:\ ProgramData \ NVIDIA Corporation \ CUDA Samples \ v6.5 \ 7_CUDALibraries \ simpleCUBLAS'中运行示例项目代码。没有运气!!

已编辑可以使用单个GPU吗?

1 个答案:

答案 0 :(得分:0)

即使以下不是完整的&#39;回答,但即便如此,我决定分享我的观察

我终于决定改用linux上的cuda。 使用cuda-gdb和memcheck。虽然在1级运行linux并不好玩,但删除了与使用Windows相关的所有不确定性 上面的代码现在运行甚至N = 15000。

简而言之,cublas gemm功能仅受硬件功能的限制