OpenCL编程步骤(二):创建命令队列

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操作分配内存失败。
当command_queue的引用计数降为0,并且其中的所有命令全部执行完毕时,此命令队列就会被删除。
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,则忽略。
clGetCommandQueueInfo所支持的param_name
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;
}
实例二:使用clCreateContextFromType的上下文来创建命令队列
   
   
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;
}



  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值