【求助】执行OpenCL时显卡停止响应,电脑黑屏

愉快的编码时光_LZT 2014-12-01 02:58:19
我在执行
ciErrNum=clEnqueueReadBuffer(myqueue,bufferR,CL_TRUE,0,365*sizeof(float),result,0,NULL,NULL);
时会出现电脑黑屏的情况,之后操作系统会提示显卡驱动停止响应,如图,。请问这是为什么。

我的环境:
--sdk:AMD app sdk 2.9,安装了Intel OpenCL sdk CPU only runtime package。
--硬件:cpu:Intel i5-3230M,显卡用的是核显hd4000。
同样的代码在我同学的机器上跑也会出现同样的问题,我同学电脑的配置:
--sdk: NVIDIA CUDA
--硬件:CPU:Intel e8400,GPU: NVIDIA 9600GS.
操作系统都是win7.
我的代码:

int main()
{
clock_t start,finish;
double totaltime;
start=clock();
int test_num = 0;
int test_flag = 1;
float* A;
float* B;
float* C;
float* D;
float* E;
float* F;
float* G;
float* result;
A=(float*)malloc(365*sizeof(float));
B=(float*)malloc(365*sizeof(float));
C=(float*)malloc(365*sizeof(float));
D=(float*)malloc(365*sizeof(float));
E=(float*)malloc(365*sizeof(float));
F=(float*)malloc(365*sizeof(float));
G=(float*)malloc(365*sizeof(float));
result=(float*)malloc(365*sizeof(float));
for(int i=0;i<365;i++)
{
A[i]=1992;
}
for(int i=0;i<365;i++)
{
B[i]=1993;
}
for(int i=0;i<365;i++)
{
C[i]=1994;
}
for(int i=0;i<365;i++)
{
D[i]=1995;
}
for(int i=0;i<365;i++)
{
E[i]=1996;
}
for(int i=0;i<365;i++)
{
F[i]=1997;
}
for(int i=0;i<365;i++)
{
G[i]=1998;
}

cl_platform_id platform;
cl_int ciErrNum;
cl_platform_info platformName;
ciErrNum=clGetPlatformIDs(1,&platform,NULL);
if (ciErrNum != CL_SUCCESS)
{
printf("Error: Getting platforms!");
return FAILURE;
}
//get platform information
size_t infoSize;
platformName=CL_PLATFORM_NAME;
ciErrNum=clGetPlatformInfo(platform,platformName,0,NULL,&infoSize);
if (ciErrNum != CL_SUCCESS)
{
printf("Error1: Getting platforms information!");
return FAILURE;
}
char* info=(char*)malloc(sizeof(char)*infoSize);
ciErrNum=clGetPlatformInfo(platform,platformName,infoSize,info,NULL);

if (ciErrNum != CL_SUCCESS)
{
printf("Error2: Getting platforms information!");
return FAILURE;
}
printf("%s\n",info);
free(info);
//Find device.
cl_device_id *device;
device=NULL;
cl_uint numDevice;
ciErrNum=clGetDeviceIDs(platform,CL_DEVICE_TYPE_GPU,4,device,&numDevice);//第二个参数应该为CL_DEVICE_TYPE_GPU,
if (numDevice == 0) //No GPU available.
{
printf( "No GPU device available." );
printf( "Choose CPU as default device.");
ciErrNum = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 0, NULL, &numDevice);
device = (cl_device_id*)malloc(numDevice * sizeof(cl_device_id));
ciErrNum = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, numDevice, device, NULL);
}
else
{
device = (cl_device_id* )malloc(numDevice*sizeof(cl_device_id));
ciErrNum = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevice, device, NULL);
}

/*get device information*/
cl_device_info itemName;
itemName=CL_DEVICE_NAME;
cl_uint coreNum;
//cl_uint coreNum;
infoSize=NULL;
ciErrNum=clGetDeviceInfo(*device,itemName,0,NULL,&infoSize);
info=(char*)malloc(sizeof(char)*infoSize);
ciErrNum=clGetDeviceInfo(*device,itemName,infoSize,info,NULL);
printf("%s\n",info);
free(info);
itemName=CL_DEVICE_MAX_COMPUTE_UNITS;
ciErrNum=clGetDeviceInfo(*device,itemName,sizeof(cl_uint),&coreNum,NULL);
printf("Device has max compute units:%d\n",coreNum);
/*Context properties*/
cl_context_properties cps[3]={CL_CONTEXT_PLATFORM,(cl_context_properties)platform,0};

/*Create context */
cl_context ctx=clCreateContext(cps,numDevice,device,NULL,NULL,&ciErrNum);
if(ciErrNum!=CL_SUCCESS)
{
printf("can't create contex");
getchar();
return 0;
}
/*Create command queue*/
cl_command_queue myqueue=clCreateCommandQueue(ctx,*device,0,&ciErrNum);
if(ciErrNum!=CL_SUCCESS)
{
printf("can't create command queue");
getchar();
return 0;
}

start=clock();
// start=clock();
/*Create buffer A*/
cl_mem bufferA=clCreateBuffer(ctx,CL_MEM_READ_ONLY,365*sizeof(float),NULL,&ciErrNum);
/*Copy MAtrix A to device*/
ciErrNum=clEnqueueWriteBuffer(myqueue,bufferA,CL_TRUE,0,365*sizeof(float),A,0,NULL,NULL);

/*Create buffer B*/
cl_mem bufferB=clCreateBuffer(ctx,CL_MEM_READ_ONLY,365*sizeof(float),NULL,&ciErrNum);
/*Copy MAtrix B to device*/
ciErrNum=clEnqueueWriteBuffer(myqueue,bufferB,CL_TRUE,0,365*sizeof(float),B,0,NULL,NULL);

/*Create buffer C*/
cl_mem bufferC=clCreateBuffer(ctx,CL_MEM_READ_ONLY,365*sizeof(float),NULL,&ciErrNum);
/*Copy MAtrix C to device*/
ciErrNum=clEnqueueWriteBuffer(myqueue,bufferC,CL_TRUE,0,365*sizeof(float),C,0,NULL,NULL);

/*Create buffer D*/
cl_mem bufferD=clCreateBuffer(ctx,CL_MEM_READ_ONLY,365*sizeof(float),NULL,&ciErrNum);
/*Copy MAtrix D to device*/
ciErrNum=clEnqueueWriteBuffer(myqueue,bufferD,CL_TRUE,0,365*sizeof(float),D,0,NULL,NULL);

/*Create buffer E*/
cl_mem bufferE=clCreateBuffer(ctx,CL_MEM_READ_ONLY,365*sizeof(float),NULL,&ciErrNum);
/*Copy MAtrix E to device*/
ciErrNum=clEnqueueWriteBuffer(myqueue,bufferE,CL_TRUE,0,365*sizeof(float),E,0,NULL,NULL);

/*Create buffer F*/
cl_mem bufferF=clCreateBuffer(ctx,CL_MEM_READ_ONLY,365*sizeof(float),NULL,&ciErrNum);
/*Copy MAtrix F to device*/
ciErrNum=clEnqueueWriteBuffer(myqueue,bufferF,CL_TRUE,0,365*sizeof(float),F,0,NULL,NULL);

/*Create buffer G*/
cl_mem bufferG=clCreateBuffer(ctx,CL_MEM_READ_ONLY,365*sizeof(float),NULL,&ciErrNum);
/*Copy MAtrix G to device*/
ciErrNum=clEnqueueWriteBuffer(myqueue,bufferG,CL_TRUE,0,365*sizeof(float),G,0,NULL,NULL);

/*Create space for result*/
cl_mem bufferR=clCreateBuffer(ctx,CL_MEM_WRITE_ONLY,365*sizeof(float),NULL,&ciErrNum);

/*Create program object*/

//将kernel转换成String
const char *sourceStr = testKernel;
size_t sourceSize[] = {strlen(sourceStr)};
cl_program program;
program= clCreateProgramWithSource(ctx, numDevice, (const char**)&sourceStr, sourceSize, &ciErrNum);
if(ciErrNum!=CL_SUCCESS)
{
printf("can't create programe");
getchar();
system("pause");
return 0;
}
/*Build program*/
ciErrNum=clBuildProgram(program, numDevice,device,NULL,NULL,NULL);
/*输出build失败的原因,主要是kernel的错误*/
if (ciErrNum!= CL_SUCCESS)
{
size_t len;
char buffer[2048];

printf("Error: Failed to build program executable!\n");
clGetProgramBuildInfo(program, *device, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len);
printf("%s\n", buffer);

exit(1);
}
/*above are very important code */
cl_kernel myKernel=clCreateKernel(program,"testKernel",NULL);
/*Set Kernel arguments*/

clSetKernelArg(myKernel,0,sizeof(cl_mem),&bufferA);
clSetKernelArg(myKernel,1,sizeof(cl_mem),&bufferB);
clSetKernelArg(myKernel,2,sizeof(cl_mem),&bufferC);
clSetKernelArg(myKernel,3,sizeof(cl_mem),&bufferD);
clSetKernelArg(myKernel,4,sizeof(cl_mem),&bufferE);
clSetKernelArg(myKernel,5,sizeof(cl_mem),&bufferF);
clSetKernelArg(myKernel,6,sizeof(cl_mem),&bufferG);
clSetKernelArg(myKernel,7,sizeof(cl_mem),&bufferR);
size_t localws[2]={(size_t)6,(size_t)6};
size_t globalws[2]={(size_t)200,(size_t)200};

ciErrNum=clEnqueueNDRangeKernel(myqueue,myKernel,2,NULL,globalws,NULL,0,NULL,NULL);
finish=clock();
totaltime=(double)(finish-start)/CLOCKS_PER_SEC;;
printf("\nTotal time is %f",totaltime);
ciErrNum=clEnqueueReadBuffer(myqueue,bufferR,CL_TRUE,0,365*sizeof(float),result,0,NULL,NULL);


for(int i=0;i<365;i++)
{
printf("%f\n",result[i]);
}



clReleaseProgram(program);
clReleaseKernel(myKernel);
clReleaseMemObject(bufferA);
clReleaseMemObject(bufferB);
clReleaseMemObject(bufferC);
clReleaseMemObject(bufferD);
clReleaseMemObject(bufferE);
clReleaseMemObject(bufferF);
clReleaseMemObject(bufferG);
clReleaseMemObject(bufferR);

clReleaseCommandQueue(myqueue);
clReleaseContext(ctx);
free(A);
free(B);
free(C);
free(D);
free(E);
free(F);
free(G);
free(result);
system("pause");
...全文
1777 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
jkkj1630 2017-01-19
  • 打赏
  • 举报
回复
楼主解决了吗,我现在也是这个问题,不过不是黑屏,是卡屏,显卡是AMD RX 480 8G版。
KevinIiang 2015-11-19
  • 打赏
  • 举报
回复
将KERNEL中的while改成if,你将内核写成死循环了
the_venus 2015-05-05
  • 打赏
  • 举报
回复
你把内核函数写个死循环,内核函数无法退出,运行超时,自己太粗心了吧。
嘤鸣求友 2015-04-13
  • 打赏
  • 举报
回复
我在运行Julia集时出现过这种情况,原因在于显卡性能不足,你降低线程数目试试。
  • 打赏
  • 举报
回复
引用 1 楼 outstander 的回复:
这个问题一般是GPU长时间占用GPU运行通用计算程序,导致windows认为 死锁。有的时候可能是kernel中循环太多或运行时间太长,但更多时候还是有死循环。 你确定是readbuffer时出现GPU无响应的吗(是否可能是kernel的问题)?是否存在读取的空间不合法(超过范围)?
我的程序执行到readbuffer时才出现这个错误,之前的语句都能执行。我不知道程序从什么时候开始占用GPU,什么时候结束占用,是在 clEnqueueNDRangeKernel执行的期间占用吗? 我的kernel代码:
const char *testKernel = "\n" \
"__kernel void testKernel(                                                       \n" \
"   __global float* A,                                              \n" \
"   __global float* B,                                             \n" \
"   __global float* C,                                             \n" \
"   __global float* D,                                             \n" \
"   __global float* E,                                             \n" \
"   __global float* F,                                             \n" \
"   __global float* G,                                             \n" \
"   __global float* Result)                                             \n" \
"{                                                                      \n" \

"   int i=get_local_id(0);                                          \n" \

"   while(i < 366)                                                       \n" \
"   {                                                               \n" \
"       Result[i]=A[i]+B[i]+C[i]+D[i]+E[i]+F[i]+G[i];                         \n" \
"    }                                                                      \n" \
"}                                                                      \n" \
"\n";
清风水岸 2014-12-15
  • 打赏
  • 举报
回复
可以说是系统的自我保护机制,可能算死了之后,系统判定无响应就会出现这种情况。比较常见的是改系统的TDR参数。你可以参考http://blog.sina.com.cn/s/blog_509927e5010123sc.html
outstander 2014-12-02
  • 打赏
  • 举报
回复
这个问题一般是GPU长时间占用GPU运行通用计算程序,导致windows认为 死锁。有的时候可能是kernel中循环太多或运行时间太长,但更多时候还是有死循环。 你确定是readbuffer时出现GPU无响应的吗(是否可能是kernel的问题)?是否存在读取的空间不合法(超过范围)?

603

社区成员

发帖
与我相关
我的任务
社区描述
异构开发技术
社区管理员
  • OpenCL和异构编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧