1、创建命令队列
OpenCL对象,比如内存对象,程序对象和内核对象都是用上下文创建的。对这些对象的操控都是通过命令队列来实现的。用命令队列可以把一系列操作按序排队。如果有多个命令队列,应用可以将多个相互独立的命令分别排队而无须同步。然而这仅在没有共享任何对象时才成立。如果要在多个命令队列间共享对象,就要求应用事实相应的同步。
cl_command_queue clCreateCommandQueue(
cl_context context,
cl_device_id device,
cl_command_queue_properties properties,
cl_int *errcode_ret)
clCreateCommandQueue就是用来在某个设备上创建命令队列。
- conetxt必须是一个有效的OpenCL上下文。
- device 必须是与context关联的设备。必须是clCreateContext或者clCreateContextFromType中相应的设备类型。
- properties指定了命令队列的一系列属性,它是位段。其值参见下表
- errcode_ret用来返回错误吗。如果errcode_ret是NULL,就不返回错误码。
命令队列属性 |
CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE |
用来确定命令队列中的命令是顺序执行还是乱序执行。如果设置了此属性,就乱序执行。否则顺序执行。 |
CL_QUEUE_PROFILING_ENABLE |
设置对命令队列中命令的评测。如果设置了此项,则设置了评测。反之则没有设置。 |
如果成功创建了命令队列,clCreateCommandQueue会将其返回,同时把errcode_ret置为CL_SUCCESS。否则返回NULL,同时将errcode_ret置为下面的错误码之一:
- CL_INVALID_CONTEXT,context无效。
- CL_INVALID_DEVICE,无效的device或者device未与context关联。
- CL_INVALID_VALUE,properties的值无效。
- CL_INVVALID_QUEUE_PROPERTIES,properties本身没有问题,但是device不支持。
- CL_OUT_OF_RESOURCES,为设备上的OpenCL操作分配内存是失败。
- CL_OUT_OF_HOST_MEMORY,为主机上的OpenCL操作分配内存失败。
2、释放命令队列
cl_int clReleaseCommandQueue(
cl_command_queue command_queue)
此函数会使command_queuq的引用计数减一。
如果执行成功,返回CL_SUCCESS。否者返回下面错误码之一:
- CL_INVALID_COMMAND_QUEUE,command_queue无效。
- CL_OUT_OF_RESOURCES,为设备上的OpenCL操作分配内存是失败。
- CL_OUT_OF_HOST_MEMORY,为主机上的OpenCL操作分配内存失败。
clReleaseCommadQueue会实施隐式的刷新(flush),会将出发所有之前入队的OpenCL命令。
3、查询命令队列
cl_int clGetCommadQueueInfo(
cl_command_queue command_queue,
cl_command_queue_info param_name,
size_t param_value_size,
void *param_value,
size_t *param_value_size_ret)
- command_queue指定所要查询的的命令队列。
- parma_name指定所要查询的信息。
- param_value指定用来存放查询结果的内存。如果是NULL,则忽略。
- param_value_size即param_value所指项内存块的大小(字节)。其值必须大于cl_command_queue_info中所对应的类型大小。
- param_value_size_ret会返回查询结果的实际大小。如果是NULL,则忽略。
cl_command_queue_info | 返回类型 |
CL_QUEUE_CONTEXT | cl_context |
返回创建命令队列时所执行的上下文。 | |
CL_QUEUE_DEVICE | cl_device_id |
返回创建命令队列时所指定的设备。 | |
CL_QUEUE_REFERENCE_COUNT | cl_uint |
返回命令队列的引用计数 | |
CL_QUEUE_PROPERTIES | cl_command_queue_properties |
返回命令队列当前的属性。 |
4、示例程序
int main(int argc, char *argv[])
{
cl_int errNum;
cl_uint numPlatforms;
cl_uint numDevices;
cl_platform_id *platforms;
cl_device_id *devices;
cl_context contex = NULL;
cl_command_queue command_queue;
errNum = clGetPlatformIDs(0, NULL, &numPlatforms);
if (errNum != CL_SUCCESS || numPlatforms <= 0)
{
cerr << "Failed to found platforms." << endl;
return -1;
}
platforms = (cl_platform_id *)alloca(sizeof(cl_platform_id) * numPlatforms);
errNum = clGetPlatformIDs(numPlatforms, platforms, NULL);
if (errNum != CL_SUCCESS)
{
cerr << "Failed to found platforms." << endl;
return -1;
}
errNum = clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
if (errNum != CL_SUCCESS || numDevices <= 0)
{
cerr << "Failed to found any devices." << end;
return -1;
}
devices = (cl_device_id *)alloca(sizeof(cl_device_id *) * numDevices);
errNum = clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_GPU, numDevices, devices, NULL);
if (errNum != CL_SUCCESS)
{
cerr << "Failed to found devices." << endl;
return -1;
}
cl_context_properties properties[] =
{
CL_CONTEXT_PLATFOMR, (cl_context_properties)platforms[0], 0
};
context = clCreateContext(properties, numDevices, devices, NULL, NULL, &errNum);
if (errNum != CL_SUCCESS || context == NULL)
{
cerr << "Failed to create context." << endl;
return -1;
}
command_queue = clCreateCommandQueue(context, devices[0], 0, &errNum);
if (errNum != CL_SUCCESS || command_queue == NULL)
{
cerr << "Failed to create command queue." << endl;
return -1;
}
cout << "create commad queue successfully." << endl;
return 0;
}
int main(int argc, char *argv[])
{
cl_int errNum;
cl_uint numPlatforms;
cl_uint numDevices;
cl_platform_id *platforms;
cl_device_id *devices;
cl_context contex = NULL;
cl_command_queue command_queue;
errNum = clGetPlatformIDs(0, NULL, &numPlatforms);
if (errNum != CL_SUCCESS || numPlatforms <= 0)
{
cerr << "Failed to found platforms." << endl;
return -1;
}
platforms = (cl_platform_id *)alloca(sizeof(cl_platform_id) * numPlatforms);
errNum = clGetPlatformIDs(numPlatforms, platforms, NULL);
if (errNum != CL_SUCCESS)
{
cerr << "Failed to found platforms." << endl;
return -1;
}
cl_context_properties properties[] =
{
CL_CONTEXT_PLATFOMR, (cl_context_properties)platforms[0], 0
};
context = clCreateContextFromType(properties, CL_DEVICE_TYPE_GPU, NULL, NULL, &errNum);
if (errNum != CL_SUCCESS || context == NULL)
{
cerr << "Failed to create context." << endl;
return -1;
}
size_t size;
errNum = clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &size);
if (errNum != CL_SUCCESS || size <= 0)
{
cerr << "Failed to get the devices." << endl;
return -1;
}
devices = (cl_device_id *)alloca(size/sizeof(cl_device_id));
errNum = clGetContextInfo(context, CL_CONTEXT_DEVICES, size, devices, NULL);
if (errNum != CL_SUCCESS)
{
cerr << "Failed to found devices." << endl;
return -1;
}
command_queue = clCreateCommandQueue(context, devices[0], 0, &errNum);
if (errNum != CL_SUCCESS || commad_queue == NULL)
{
cerr << "Failed to create command queue." << endl;
return -1;
}
cout << "create commad queue successfully." << endl;
return 0;
}