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

Cuda 使用cublas gemm函数(cublasSgemm)乘法的矩阵大小上限,cuda,nvidia,nvcc,nsight,cublas,Cuda,Nvidia,Nvcc,Nsight,Cublas,这是我第一次无法从之前发布的问题的答案中获得帮助 我已经非常成功地使用了cublasSgemm来乘平方矩阵。 但是,最近我观察到,如果行或列的数量增加超过269(即270 x 270矩阵及以上),当我通过启用Nsight Cuda内存检查器进行调试时,我开始出现“内存访问冲突”。如果我没有启用内存检查器,则没有异常,结果也是正确的 下面是确切的错误消息 内存检查器检测到64个访问冲突 存储上的访问冲突(全局内存) 这是我的gpu或cublasSgemm功能的限制吗? 如何解决此问题 我正在Qua

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

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

下面是确切的错误消息

内存检查器检测到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;
}
#包括
#包括
#包括
int main(int argc,字符**argv)
{
const int m=269;//对于1-269,没有访问冲突
//但一旦m>=270内存检查器抛出内存访问冲突
//注意:即使存在这些违规行为,结果也是正确的
浮点数*X=新浮点数[m*m];
浮动*Y=新浮动[m*m];
浮点数*Z=新浮点数[m*m];
浮动*devX,*devY,*devZ;
立方手柄;
错误;
库布拉斯塔图斯错误1;
//简单初始化
for(无符号长i=0;i269时检测访问冲突
cublasSgemm(句柄、CUBLAS_OP_N、CUBLAS_OP_N、m、m和alpha、devX、m、devY、m和beta、devZ、m);
cudaDeviceSynchronize();
printf(“在sgemm之后到达,没有错误\n”);
////////////////////////////////////////////////////////////
err1=立方矩阵(m,m,sizeof(*devZ),devZ,m,Z,m);
如果(错误!=CUBLAS\u状态\u成功)
返回1;
//为了简洁起见,只需打印一个元素
printf(“..%f..”,Z[0]);
cudaFree(devX);
库达弗里(德维);
库达弗里(devZ);
cublasu v2(手柄);
getchar();
返回0;
}
已编辑

再次编辑

编译并运行从以下站点下载的cublas示例:

对于N>500再次获得与之前相同的错误

如果Cuda内存检查器未启用
,则与之前一样,此程序成功运行至完成,并显示“测试通过”消息

实际上,访问冲突从N=350开始,但在这一点上它们是不可预测的,即有时会发生,有时不会发生。但当N>500时,它们总是出现

使用的cudaDeviceGetLimit(&堆大小,cudaLimitMallocHeapSize);获取3435973836字节的堆大小。所以,想必这也不是问题所在

已编辑 我现在已经在“C:\ProgramData\NVIDIA Corporation\CUDA Samples\v6.5\7\u CUDALibraries\SimpleCleas”上运行了示例项目代码。不走运


编辑使用单个GPU可能是原因吗?

尽管以下不是一个“完整”的答案,但即使如此,我还是决定分享我的观察结果

我终于决定在linux上重新使用cuda。 在memcheck打开的情况下使用cuda gdb。虽然在1级运行linux并不有趣,但与使用windows相关的所有不确定性都已消除 以上代码现在运行的时间为偶数N=15000


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

还必须注意,为两个输入矩阵和一个输出矩阵分配内存没有问题。GPU有1GB的内存。存在错误故障检测。你确定这些是真的吗?你自己能发现吗?这有关系吗?您可能会遇到windows TDR事件。您是否修改了TDR超时设置?我已经在windows的Quadro FX1800上的CUDA 6.5上运行了您的代码,没有发现任何内存检查问题。能否正确运行SimpleCleas[示例代码]()(带或不带内存检查器)?这是一个320x320 sgemm操作。@RobertCrovella:我已经尝试过禁用TDR,甚至将其增加到高达60秒的值。您不应该切换到运行级别1。如果您的目标是阻止X运行,运行级别3应该可以。@RobertCrovella但在我的ubuntu 14.04上停止lightdm不起作用。因此,我只是切换到运行级别1,您不必停止lightdm。在运行级别3中,X服务不会在启动时启动。将运行级别设置为3并重新启动。运行级别3的优点是,网络等功能仍然正常,并且您仍然可以将linux用作mutliuser环境。