使用 cublas gemm 函数 (cublasSgemm) 乘法矩阵大小的上限
Upper Limit on Matrix Size for Multiplication using cublas gemm function (cublasSgemm)
这是我第一次无法从以前发布的问题的答案中获得帮助。
我一直在使用 cublasSgemm 非常成功地 乘方矩阵。
但是,最近我观察到如果行数或列数增加 超过 269(即 270 x 270 矩阵及以上),我开始得到 "Memory Access Violations",当我 通过启用 Nsight Cuda 内存检查器进行调试。如果我不启用内存检查器,那么没有例外,结果也是正确的。
以下是准确的错误信息
Memory Checker detected 64 access violations
access violations on store (global memory)
这是我的 gpu 或 cublasSgemm 函数的限制吗?
我该怎么做才能解决这个问题?
我在 Quadro FX 1800M (sm_12) 上使用 Cuda 6.5 和 MS Visual Studio 2012。 OS 是 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;
}
已编辑
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 > 500 得到与之前相同的错误。
如果 Cuda Memory Checker 未启用,则与之前一样,此程序 运行s 成功完成并显示 "test passed" 消息。
实际上,访问冲突从 N = 350 开始,但此时它们是不可预测的,即它们有时会发生,有时不会发生。但是对于 N > 500,它们总是会发生
使用了 cudaDeviceGetLimit(&heap_size, cudaLimitMallocHeapSize);得到 3435973836 字节的 heap_size。所以,大概这也不是问题!
已编辑
我现在 运行 示例项目代码位于 'C:\ProgramData\NVIDIA Corporation\CUDA Samples\v6.5_CUDALibraries\simpleCUBLAS'。运气不好!!
已编辑使用单个 GPU 可能是原因吗?
尽管以下不是 'complete' 答案,但即便如此我还是决定分享我的观察结果
我终于决定在 linux 上切换回使用 cuda。
使用 cuda-gdb 并启用 memcheck。虽然第 1 级中的 运行 linux 并不好玩,但是与使用 windows 相关的所有不确定性都被移除了
上面的代码现在甚至运行 N = 15000。
简而言之,cublas gemm 功能仅受限于硬件能力
这是我第一次无法从以前发布的问题的答案中获得帮助。
我一直在使用 cublasSgemm 非常成功地 乘方矩阵。 但是,最近我观察到如果行数或列数增加 超过 269(即 270 x 270 矩阵及以上),我开始得到 "Memory Access Violations",当我 通过启用 Nsight Cuda 内存检查器进行调试。如果我不启用内存检查器,那么没有例外,结果也是正确的。
以下是准确的错误信息
Memory Checker detected 64 access violations
access violations on store (global memory)
这是我的 gpu 或 cublasSgemm 函数的限制吗? 我该怎么做才能解决这个问题?
我在 Quadro FX 1800M (sm_12) 上使用 Cuda 6.5 和 MS Visual Studio 2012。 OS 是 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;
}
已编辑
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 > 500 得到与之前相同的错误。
如果 Cuda Memory Checker 未启用,则与之前一样,此程序 运行s 成功完成并显示 "test passed" 消息。
实际上,访问冲突从 N = 350 开始,但此时它们是不可预测的,即它们有时会发生,有时不会发生。但是对于 N > 500,它们总是会发生
使用了 cudaDeviceGetLimit(&heap_size, cudaLimitMallocHeapSize);得到 3435973836 字节的 heap_size。所以,大概这也不是问题!
已编辑 我现在 运行 示例项目代码位于 'C:\ProgramData\NVIDIA Corporation\CUDA Samples\v6.5_CUDALibraries\simpleCUBLAS'。运气不好!!
已编辑使用单个 GPU 可能是原因吗?
尽管以下不是 'complete' 答案,但即便如此我还是决定分享我的观察结果
我终于决定在 linux 上切换回使用 cuda。 使用 cuda-gdb 并启用 memcheck。虽然第 1 级中的 运行 linux 并不好玩,但是与使用 windows 相关的所有不确定性都被移除了 上面的代码现在甚至运行 N = 15000。
简而言之,cublas gemm 功能仅受限于硬件能力