我收到“有时”访问违规错误;该程序有时工作并吐出设备名称和类型,有时它只会引发访问冲突异常。
我程序的输出(来自printf)如下:
不必要的东西
检测到的OpenCL设备数量:2
所以显然我正在检测每个平台的两个设备(参见代码中的for循环)。
该数字由 getDeviceInfo 函数给出并存储在虚拟变量中,因此该函数可能存在问题。
我在调试期间注意到了 getDeviceInfo 返回
0x0000000d49eff270 {0x000001f1ff027af0} _cl_device_id **
我猜第一位(0x0000000d49eff270)是设备数组开头的内存位置。 但是当我在这行中访问我的设备数组时
cl_device_id device = devices[i]; //see me in the main inside the second for loop
我得到这个值(对于设备[i]和设备):
0xcccccccccccccccc {...} _cl_device_id *
无论如何,程序继续尝试使用 displayDeviceDetails 函数获取设备信息,并且如前所述, clGetDeviceInfo 上的访问冲突失败。
发生什么事了?为什么它有时也能正常工作,如果有什么不对的话。它不应该工作吗?
我附上相关的源代码:
getDeviceInfo :
cl_device_id* getDeviceInfo(cl_platform_id platform_id, cl_device_type device_type, cl_uint &numOfDev)
{
cl_int error = 0;
cl_uint numberOfDevices = 0;
/* Determine how many devices are in the platform */
error = clGetDeviceIDs(platform_id, device_type, 0, NULL, &numberOfDevices);
if (checkCLError(error, "Unable to obtain any OpenCL device info"))
{
exit(1);
}
numOfDev = numberOfDevices;
/* allocate memory for the devices array (pointer) */
cl_device_id* devices = (cl_device_id*)alloca(sizeof(cl_device_id) * numberOfDevices);
/* Load device information into array devices */
error = clGetDeviceIDs(platform_id, device_type, numberOfDevices, devices, NULL);
if (checkCLError(error, "Unable to obtain device info"))
{
exit(1);
}
printf("Number of detected OpenCL devices: %d\n", numberOfDevices);
return devices;
}
displayDeviceDetails:
void displayDeviceDetails(cl_device_id dev_id, cl_device_info param_name, const char* paramNameAsStr)
{
cl_int error = 0;
size_t paramSize = 0;
/* Get Device Info size */
error = clGetDeviceInfo(dev_id, param_name, 0, NULL, ¶mSize);
if (checkCLError(error, "Unable to obtain device info"))
{
return;
}
switch (param_name)
{
case CL_DEVICE_TYPE:
{
cl_device_type* devType = (cl_device_type*)alloca(sizeof(cl_device_type)* paramSize);
error = clGetDeviceInfo(dev_id, param_name, paramSize, devType, NULL);
if (checkCLError(error, "Unable to obtain a specific device info"))
{
return;
}
switch (*devType)
{
case CL_DEVICE_TYPE_CPU:
printf("\tCPU Detected\n");
break;
case CL_DEVICE_TYPE_GPU:
printf("\tGPU Detected\n");
break;
default:
printf("\tOther stuff Detected\n");
}
break;
}
case CL_DEVICE_NAME:
{
char* devName = (char*)alloca(sizeof(CL_DEVICE_NAME)*paramSize);
error = clGetDeviceInfo(dev_id, param_name, paramSize, devName, NULL);
printf("\tName: %s\n", devName);
break;
}
}
}
主要
int main() {
cl_platform_id* platforms;
cl_uint numOfPlatforms;
cl_int error;
error = clGetPlatformIDs(0, NULL, &numOfPlatforms);
if (checkCLError(error, "Unable to find OpenCL Plaftorms"))
{
exit(1);
}
printf("Number of OpenCL platform found: %d\n", numOfPlatforms);
platforms = (cl_platform_id*)alloca(sizeof(cl_platform_id)* numOfPlatforms);
error = clGetPlatformIDs(numOfPlatforms, platforms, NULL); // This line initializes ""something"". Delete and u will get access violation
for (cl_uint i = 0; i < numOfPlatforms; ++i) {
printf("\n--------------------\nThe %d th platform\n----------------- ---\n",i+1);
displayPlatformInfo(platforms[i], CL_PLATFORM_PROFILE, "CL_PLATFORM_PROFILE");
displayPlatformInfo(platforms[i], CL_PLATFORM_VERSION, "CL_PLATFORM_VERSION");
displayPlatformInfo(platforms[i], CL_PLATFORM_NAME, "CL_PLATFORM_NAME");
displayPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, "CL_PLATFORM_VENDOR");
displayPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, "CL_PLATFORM_EXTENSIONS");
cl_uint numOfDevices = 0;
cl_device_id* devices = getDeviceInfo(platforms[i], CL_DEVICE_TYPE_ALL, numOfDevices);
for (cl_uint i = 0; i < numOfDevices; ++i)
{
printf("\tDevice (%d) Information\n\t----------------------\n",i);
cl_device_id device = devices[i];
displayDeviceDetails(device, CL_DEVICE_NAME, "CL_DEVICE_NAME");
displayDeviceDetails(device, CL_DEVICE_TYPE, "CL_DEVICE_TYPE");
}
}
return 0;
}
答案 0 :(得分:2)
这是因为你正在使用alloca()
。不要那么做! alloca()
函数在调用者的堆栈帧中分配空间的大小字节,然后返回(这会破坏堆栈帧)。