#第二章 平台模型
由于同一个平台可能有多个设备,那么我们需要对这些设备进行统一的管理,这时需要使用上下文这样一个结构来完成对多个设备的管理工作,上下文不能跨平台管理设备。
#####以下三个接口是关于上下文的:
cl_context clCreateContext (const cl_context_properties *properties, //上下文的属性(一般为NULL)
cl_uint num_devices, //该上下文管理的设备数量
const cl_device_id *devices, //该上下文管理的设备ID列表
void (CL_CALLBACK *pfn_notify)(const char *errinfo, //回调函数用于报告创建或运行上下文时的错误信息
const void *private_info, size_t cb,
void *user_data),
void *user_data, //当发生错误时回调函数会访问该参数
cl_int *errcode_ret) //错误信息
cl_context clCreateContextFromType (const cl_context_properties *properties, //上下文的属性(一般为NULL)
cl_device_type device_type, //该上下文管理的设备类型
void (CL_CALLBACK *pfn_notify)(const char *errinfo, //回调函数用于报告创建或运行上下文时的错误信息
const void *private_info, size_t cb,
void *user_data),
void *user_data, //当发生错误时回调函数会访问该参数
cl_int *errcode_ret) //错误信息
这两个创建上下文的接口的区别是第一个通过确定的设备来创建上下文,第二个通过设备的类型来创建上下文,因为上下文是用来管理设备的,所以创建的方法有两种。
#####根据具体设备创建上下文的方法:
cl_int err;
cl_context context = clCreateContext(NULL, device_num, devices, NULL, NULL, &err);
checkError(err, "Can't create context");
#####根据设备类型创建上下文的方法:
cl_int err;
cl_context context = clCreateContextFromType(NULL, CL_DEVICE_TYPE_ALL, NULL, NULL, &err);
checkError(err, "Can't create context");
cl_int clGetContextInfo (cl_context context, //上下文
cl_context_info param_name, //查询信息名称
size_t param_value_size, //传入用于存放信息的参数的大小
void *param_value, //传入用于存放信息的参数
size_t *param_value_size_ret) //返回用于存放信息的参数的大小
该接口用来查询已创建上下文的信息
可查询的信息有:
查询上下文信息方法:
cl_uint devicenum;
err = clGetContextInfo(context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &devicenum, NULL);
cout << "This context contain : " << devicenum << " device(s)" << endl;
如果上下文被申明为局部变量,那么他的内存将会在函数调用结束后被释放,如果想要继续访问该上下文的话可以使用引用计数这样一个参数来控制,当上下文创建后,他的引用计数被初始化为1,当上下文的引用计数为0的时候会释放上下文的内存,因此可以通过管理上下文的引用计数来控制什么时候释放上下文。控制上下文引用计数的接口如下:
cl_int clRetainContext (cl_context context) //引用计数加一
cl_int clReleaseContext (cl_context context) //引用计数减一
实验代码:
#include"opencl.h"
int main(){
cl_uint platform_num;
clGetPlatformIDs(0,NULL,&platform_num);
cl_platform_id *platforms = new cl_platform_id[platform_num];
clGetPlatformIDs(platform_num, platforms, NULL);
cl_uint device_num;
clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_ALL, 0, NULL, &device_num);
cl_device_id *devices = new cl_device_id[device_num];
clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_ALL, device_num, devices, NULL);
cl_int err;
/*cl_context context = clCreateContext(NULL, device_num, devices, NULL, NULL, &err);*/
cl_context context = clCreateContextFromType(NULL, CL_DEVICE_TYPE_ALL, NULL, NULL, &err);
checkError(err, "Can't create context");
cl_uint devicenum;
err = clGetContextInfo(context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &devicenum, NULL);
cout << "This context contain : " << devicenum << " device(s)" << endl;
cl_uint reference_count = 0;
err = clGetContextInfo(context, CL_CONTEXT_REFERENCE_COUNT, sizeof(cl_uint), &reference_count, NULL);
cout << "Initial count is : " << reference_count << endl;
clRetainContext(context);
err = clGetContextInfo(context, CL_CONTEXT_REFERENCE_COUNT, sizeof(cl_uint), &reference_count, NULL);
cout << "Add count is : " << reference_count << endl;
clReleaseContext(context);
err = clGetContextInfo(context, CL_CONTEXT_REFERENCE_COUNT, sizeof(cl_uint), &reference_count, NULL);
cout << "Sub count is : " << reference_count << endl;
/*clReleaseContext(context);
err = clGetContextInfo(context, CL_CONTEXT_REFERENCE_COUNT, sizeof(cl_uint), &reference_count, NULL);
cout << "Sub count is : " << reference_count << endl;*/
return 0;
}
实验结果:
我的平台创建的context初始值为5,当引用计数减到4的时候再调用context就会报错,因为这时候context的内存已经被释放。