| | |
| | | #include<stdio.h> |
| | | #include<stdlib.h> |
| | | #include<iostream> |
| | | #include<CL/cl.h> |
| | | #include <chrono> |
| | | #include "OpenCLExcuter.h" |
| | | #include "ImgUtil.h" |
| | | using namespace std; |
| | | void printDevice(); |
| | | uchar* createDemoData(int line); |
| | | uchar* createTemplateData(int line); |
| | | #include <stdio.h> |
| | | #include <stdlib.h> |
| | | #include <CL/cl.h> |
| | | |
| | | int LINE_NUMBER = 10; |
| | | int RE = _NUMBER_L2_TOTAL_NUMBER; |
| | | const int ARRAY_SIZE = 1000; |
| | | /* |
| | | 1. 创建平台 |
| | | 2. 创建设备 |
| | | 3. 根据设备创建上下文 |
| | | */ |
| | | cl_context CreateContext(cl_device_id* device) { |
| | | cl_int errNum; |
| | | cl_uint numPlateforms; |
| | | cl_platform_id firstPlatformId; |
| | | cl_context context = NULL; |
| | | errNum = clGetPlatformIDs(1, &firstPlatformId, &numPlateforms); |
| | | |
| | | |
| | | |
| | | #define CHECK_ERRORS(ERR) \ |
| | | if(ERR != CL_SUCCESS){ \ |
| | | std::cerr << "OpenCL error code" << ERR << "file: " << __FILE__ << "line: " << __LINE__ << ".\nExiting..." << std::endl; \ |
| | | exit(1); \ |
| | | if (errNum != CL_SUCCESS || numPlateforms <= 0) { |
| | | printf("Failed to find any OpenCL platforms.\n"); |
| | | return NULL; |
| | | } |
| | | int main1() { |
| | | //printDevice(); |
| | | //return 1; |
| | | auto starttime = std::chrono::steady_clock::now(); |
| | | errNum = clGetDeviceIDs(firstPlatformId, CL_DEVICE_TYPE_GPU, 1, device, NULL); |
| | | if (errNum != CL_SUCCESS) { |
| | | printf("There is no GPU , trying CPU...\n"); |
| | | errNum = clGetDeviceIDs(firstPlatformId, CL_DEVICE_TYPE_CPU, 1, device, NULL); |
| | | |
| | | cl_int error; |
| | | cl_uint num_of_platforms = 0; |
| | | cl_platform_id platforms; |
| | | } |
| | | if (errNum != CL_SUCCESS) { |
| | | printf("There is NO CPU or GPU\n"); |
| | | return NULL; |
| | | } |
| | | context = clCreateContext(NULL, 1, device, NULL, NULL, &errNum); |
| | | if (errNum != CL_SUCCESS) { |
| | | printf("Create context error\n"); |
| | | return NULL; |
| | | } |
| | | return context; |
| | | } |
| | | /* |
| | | @ 在上下文可用的第一个设备中创建命令队列 |
| | | */ |
| | | |
| | | cl_device_id devices; |
| | | cl_command_queue CreateCommandQueue(cl_context context, cl_device_id device) { |
| | | cl_int errNum; |
| | | cl_command_queue commandQueue = NULL; |
| | | //commandQueue = clCreateCommandQueue(context, device, 0, NULL); |
| | | // OpenCL 2.0 的用法 |
| | | commandQueue = clCreateCommandQueueWithProperties(context, device, 0, NULL); |
| | | if (commandQueue == NULL) { |
| | | printf("Failed to create commandQueue for device 0\n"); |
| | | return NULL; |
| | | } |
| | | return commandQueue; |
| | | } |
| | | |
| | | cl_context context; |
| | | char* ReadKernelSourceFile(const char* filename, size_t* length) { |
| | | FILE* file = NULL; |
| | | size_t sourceLenth; |
| | | char* sourceString; |
| | | int ret; |
| | | fopen_s(&file, filename, "rb"); |
| | | |
| | | FILE* program_handle; |
| | | size_t program_size; |
| | | char* program_buffer; |
| | | if (file == NULL) { |
| | | printf("%s at %d : Can't open %s \n", __FILE__, __LINE__ - 2, filename); |
| | | return NULL; |
| | | } |
| | | //重定位到文件末尾 |
| | | fseek(file, 0, SEEK_END); |
| | | sourceLenth = ftell(file); |
| | | //重定位到文件开头 |
| | | fseek(file, 0, SEEK_SET); |
| | | sourceString = (char*)malloc(sourceLenth + 1); |
| | | sourceString[0] = '\0'; |
| | | ret = fread(sourceString, sourceLenth, 1, file); |
| | | if (ret == 0) { |
| | | printf("%s at %d : Cant't read source %s\n", __FILE__, __LINE__ - 2, filename); |
| | | return NULL; |
| | | } |
| | | fclose(file); |
| | | if (length != 0) { |
| | | *length = sourceLenth; |
| | | } |
| | | sourceString[sourceLenth] = '\0'; |
| | | return sourceString; |
| | | |
| | | |
| | | } |
| | | cl_program CreateProgram(cl_context context, cl_device_id device, const char* filename) { |
| | | cl_int errNum; |
| | | cl_program program; |
| | | //记录大小的数据类型 |
| | | size_t program_length; |
| | | char* const source = ReadKernelSourceFile(filename, &program_length); |
| | | program = clCreateProgramWithSource(context, 1, (const char**)&source, NULL, NULL); |
| | | |
| | | size_t log_size; |
| | | char* program_log; |
| | | |
| | | char kernel_name[] = "createBuffer"; |
| | | cl_kernel kernel; |
| | | |
| | | cl_command_queue queue; |
| | | //获取平台 |
| | | error = clGetPlatformIDs(1, &platforms, &num_of_platforms); |
| | | if (error != 0) { |
| | | printf("Get platform failed!"); |
| | | return -1; |
| | | if (program == NULL) { |
| | | printf("Failed to creae CL program from source.\n"); |
| | | return NULL; |
| | | } |
| | | //获取设备 |
| | | error = clGetDeviceIDs(platforms, CL_DEVICE_TYPE_GPU, 1, &devices, NULL); |
| | | if (error != 0) { |
| | | printf("Get device failed!"); |
| | | return -1; |
| | | errNum = clBuildProgram(program, 0, NULL, NULL, NULL, NULL); |
| | | if (errNum != CL_SUCCESS) { |
| | | char buildLog[16384]; |
| | | clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, sizeof(buildLog), buildLog, NULL); |
| | | printf("Error in kernel : %s \n", buildLog); |
| | | clReleaseProgram(program); |
| | | return NULL; |
| | | } |
| | | return program; |
| | | } |
| | | /* |
| | | @ 创建内存对象 |
| | | */ |
| | | bool CreateMemObjects(cl_context context, cl_mem memObjects[3], float* a, float* b) { |
| | | memObjects[0] = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float) * ARRAY_SIZE, a, NULL); |
| | | memObjects[1] = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float) * ARRAY_SIZE, b, NULL); |
| | | memObjects[2] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * ARRAY_SIZE, NULL, NULL); |
| | | if (memObjects[0] == NULL || memObjects[1] == NULL || memObjects[2] == NULL) { |
| | | printf("Error creating memeory objects.\n"); |
| | | return false; |
| | | |
| | | } |
| | | return true; |
| | | } |
| | | /* |
| | | @ 清楚OpenCL资源 |
| | | */ |
| | | void CleanUp(cl_context context, cl_command_queue commandQueue, cl_program program, cl_kernel kernel, cl_mem memObjects[3]) { |
| | | for (int i = 0; i < 3; i++) { |
| | | if (memObjects[i] != 0) { |
| | | clReleaseMemObject(memObjects[i]); |
| | | } |
| | | } |
| | | |
| | | std::cout << " 获取设备:" << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - starttime).count() << std::endl; |
| | | |
| | | //创建上下文 |
| | | context = clCreateContext(NULL, 1, &devices, NULL, NULL, &error); |
| | | if (error != 0) { |
| | | printf("Creat context failed!"); |
| | | return -1; |
| | | if (commandQueue != 0) { |
| | | clReleaseCommandQueue(commandQueue); |
| | | } |
| | | std::cout << " 创建上下文:" << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - starttime).count() << std::endl; |
| | | //创建程序;注意要用"rb" |
| | | fopen_s(&program_handle,"kernel.cl", "rb"); |
| | | if (program_handle == NULL) { |
| | | printf("The kernle can not be opened!"); |
| | | return -1; |
| | | } |
| | | fseek(program_handle, 0, SEEK_END); |
| | | program_size = ftell(program_handle); |
| | | rewind(program_handle); |
| | | |
| | | program_buffer = (char*)malloc(program_size + 1); |
| | | program_buffer[program_size] = '\0'; |
| | | error = fread(program_buffer, sizeof(char), program_size, program_handle); |
| | | if (error == 0) { |
| | | printf("Read kernel failed!"); |
| | | return -1; |
| | | } |
| | | fclose(program_handle); |
| | | program = clCreateProgramWithSource(context, 1, (const char**)&program_buffer, |
| | | &program_size, &error); |
| | | if (error < 0) { |
| | | printf("Couldn't create the program!"); |
| | | return -1; |
| | | } |
| | | //编译程序 |
| | | error = clBuildProgram(program, 1, &devices, NULL, NULL, NULL); |
| | | if (error < 0) { |
| | | //确定日志文件的大小 |
| | | clGetProgramBuildInfo(program, devices, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size); |
| | | program_log = (char*)malloc(log_size + 1); |
| | | program_log[log_size] = '\0'; |
| | | //读取日志 |
| | | clGetProgramBuildInfo(program, devices, CL_PROGRAM_BUILD_LOG, |
| | | log_size + 1, program_log, NULL); |
| | | printf("%s\n", program_log); |
| | | free(program_log); |
| | | return -1; |
| | | } |
| | | free(program_buffer); |
| | | |
| | | //创建命令队列 |
| | | queue = clCreateCommandQueue(context, devices, CL_QUEUE_PROFILING_ENABLE, &error); |
| | | if (error < 0) { |
| | | printf("Coudn't create the command queue"); |
| | | return -1; |
| | | } |
| | | //----------程序正文开始--------- |
| | | |
| | | for (int n = 0;n < 100;n++) |
| | | { |
| | | |
| | | auto startexectime = std::chrono::steady_clock::now(); |
| | | |
| | | |
| | | |
| | | //创建内核 |
| | | kernel = clCreateKernel(program, "createBuffer", &error); |
| | | if (kernel == NULL) { |
| | | printf("Couldn't create kernel!\n"); |
| | | return -1; |
| | | } |
| | | //初始化参数 |
| | | const int size = 70000; |
| | | float result[size]; |
| | | float a_in[size]; |
| | | float b_in[size]; |
| | | for (int i = 0; i < size; i++) { |
| | | a_in[i] = i+n; |
| | | b_in[i] = i * 2.0; |
| | | } |
| | | //创建缓存对象 |
| | | cl_mem memObject1 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float) * size, a_in, &error); |
| | | if (error < 0) { |
| | | printf("Creat memObject1 failed!\n"); |
| | | return -1; |
| | | } |
| | | cl_mem memObject2 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, |
| | | sizeof(float) * size, b_in, &error); |
| | | if (error < 0) { |
| | | printf("Creat memObject2 failed!\n"); |
| | | return -1; |
| | | } |
| | | cl_mem memObject3 = clCreateBuffer(context, CL_MEM_WRITE_ONLY, |
| | | sizeof(float) * size, NULL, &error); |
| | | if (error < 0) { |
| | | printf("Creat memObject3 failed!\n"); |
| | | return -1; |
| | | } |
| | | //设置内核参数 |
| | | error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObject1); |
| | | error |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &memObject2); |
| | | error |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &memObject3); |
| | | if (error != CL_SUCCESS) { |
| | | printf("Error setting kernel arguments!\n"); |
| | | return -1; |
| | | } |
| | | //执行内核 |
| | | size_t globalWorkSize[1] = { size }; |
| | | size_t localWorkSize[1] = { 1 }; |
| | | |
| | | const int work_dim = 2; |
| | | |
| | | error = clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, globalWorkSize, |
| | | localWorkSize, 0, NULL, NULL); |
| | | if (error != CL_SUCCESS) { |
| | | printf("Error queuing kernel for execution!\n"); |
| | | return -1; |
| | | } |
| | | |
| | | //读取执行结果 |
| | | error = clEnqueueReadBuffer(queue, memObject3, CL_TRUE, 0, size * sizeof(float), |
| | | result, 0, NULL, NULL); |
| | | if (error != CL_SUCCESS) { |
| | | printf("Error reading result buffer!\n"); |
| | | return -1; |
| | | } |
| | | //显示结果 |
| | | for (int i = 0; i < 2; i++) { |
| | | printf("%f ", result[i]); |
| | | } |
| | | |
| | | if (kernel != 0) { |
| | | clReleaseKernel(kernel); |
| | | clReleaseMemObject(memObject1); |
| | | clReleaseMemObject(memObject2); |
| | | clReleaseMemObject(memObject3); |
| | | |
| | | |
| | | std::cout << " 执行结束:" << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - startexectime).count() << std::endl; |
| | | } |
| | | if (program != 0) { |
| | | clReleaseProgram(program); |
| | | } |
| | | if (context != 0) { |
| | | clReleaseContext(context); |
| | | } |
| | | } |
| | | |
| | | //-------------程序正文结束 |
| | | /*main函数*/ |
| | | int main__(int argc, char** agrv) { |
| | | cl_context context = 0; |
| | | cl_command_queue commandQueue = 0; |
| | | cl_program program = 0; |
| | | cl_device_id device = 0; |
| | | cl_kernel kernel = 0; |
| | | cl_mem memObjects[3] = { 0,0,0 }; |
| | | cl_int errNum; |
| | | //创建OpenCL上下文 |
| | | context = CreateContext(&device); |
| | | if (context == NULL) { |
| | | printf("Failed to create OpenCL context\n"); |
| | | return 1; |
| | | } |
| | | //获得OpenCL设备,并创建命令队列 |
| | | commandQueue = CreateCommandQueue(context, device); |
| | | if (commandQueue == NULL) { |
| | | CleanUp(context, commandQueue, program, kernel, memObjects); |
| | | return 1; |
| | | } |
| | | //创建OpenCL程序 |
| | | program = CreateProgram(context, device, "kernel.cl"); |
| | | if (program == NULL) { |
| | | CleanUp(context, commandQueue, program, kernel, memObjects); |
| | | return 1; |
| | | } |
| | | kernel = clCreateKernel(program, "vector_add", NULL); |
| | | if (kernel == NULL) { |
| | | printf("Failed to create kernel\n"); |
| | | CleanUp(context, commandQueue, program, kernel, memObjects); |
| | | return 1; |
| | | |
| | | } |
| | | //创建OpenCL内存对象 |
| | | float result[ARRAY_SIZE]; |
| | | float a[ARRAY_SIZE]; |
| | | float b[ARRAY_SIZE]; |
| | | for (int i = 0; i < ARRAY_SIZE; i++) { |
| | | a[i] = (float)i; |
| | | b[i] = (float)(i * 2); |
| | | } |
| | | if (!CreateMemObjects(context, memObjects, a, b)) { |
| | | CleanUp(context, commandQueue, program, kernel, memObjects); |
| | | return 1; |
| | | } |
| | | //设置内核参数 |
| | | errNum = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObjects[0]); |
| | | errNum |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &memObjects[1]); |
| | | errNum |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &memObjects[2]); |
| | | |
| | | |
| | | //释放资源 |
| | | clReleaseDevice(devices); |
| | | clReleaseContext(context); |
| | | clReleaseProgram(program); |
| | | clReleaseCommandQueue(queue); |
| | | |
| | | std::cout << " 耗时:" << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - starttime).count() << std::endl; |
| | | if (errNum != CL_SUCCESS) { |
| | | printf("Error setting kernel arguments.\n"); |
| | | CleanUp(context, commandQueue, program, kernel, memObjects); |
| | | return 1; |
| | | } |
| | | size_t globalWorkSize[1] = { ARRAY_SIZE }; |
| | | size_t localWorkSize[1] = { 1 }; |
| | | //执行内核 |
| | | errNum = clEnqueueNDRangeKernel(commandQueue, kernel, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL); |
| | | if (errNum != CL_SUCCESS) { |
| | | printf("Error queueing kernel for execution\n"); |
| | | CleanUp(context, commandQueue, program, kernel, memObjects); |
| | | return 1; |
| | | } |
| | | //将计算的结果拷贝到主机上 |
| | | errNum = clEnqueueReadBuffer(commandQueue, memObjects[2], CL_TRUE, 0, ARRAY_SIZE * sizeof(float), result, 0, NULL, NULL); |
| | | if (errNum != CL_SUCCESS) { |
| | | printf("Error reading result buffer.\n"); |
| | | CleanUp(context, commandQueue, program, kernel, memObjects); |
| | | return 1; |
| | | } |
| | | for (int i = 0; i < ARRAY_SIZE; i++) { |
| | | printf("i=%d:%f\n", i, result[i]); |
| | | } |
| | | printf("Executed program succesfully\n"); |
| | | CleanUp(context, commandQueue, program, kernel, memObjects); |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | int main3() { |
| | | ImgUtil::init(); |
| | | OpenCLExcuter* op = new OpenCLExcuter(); |
| | | int dataCount = 100; |
| | | |
| | | |
| | | int rows = 8* dataCount; |
| | | int cols = 5 * LINE_NUMBER * RE; |
| | | uchar* b_in = createTemplateData(dataCount); |
| | | uchar* a_in = createDemoData(dataCount); |
| | | |
| | | //printf("输入1: \n"); |
| | | for (int r = 0;r < rows;r++) { |
| | | for (int c = 0;c < cols;c++) { |
| | | // printf("%d ", a_in[r*cols+c]); |
| | | } |
| | | // printf("\n"); |
| | | } |
| | | |
| | | //printf("输入2: \n"); |
| | | for (int r = 0;r < rows;r++) { |
| | | for (int c = 0;c < cols;c++) { |
| | | // printf("%d ", b_in[r * cols + c]); |
| | | } |
| | | //printf("\n"); |
| | | } |
| | | |
| | | /* |
| | | int rows = 10; |
| | | int cols = 10; |
| | | uchar* b_in = (uchar*)malloc(sizeof(uchar*)*400); |
| | | uchar* a_in = (uchar*)malloc(sizeof(uchar*) * 400); |
| | | for (int i = 0;i < 400;i++) { |
| | | b_in[i] = i; |
| | | a_in[i] = i + 1; |
| | | } |
| | | */ |
| | | |
| | | op->init(); |
| | | for (int i = 0;i < 100;i++) |
| | | { |
| | | op->recognition_numbers(a_in, b_in, rows, cols ,_NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER); |
| | | } |
| | | op->destory(); |
| | | |
| | | return 1; |
| | | } |
| | | |
| | | uchar* createDemoData(int line) { |
| | | unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * line) * 5 * LINE_NUMBER * RE); |
| | | int outLineDataCount = 8 * 5 * LINE_NUMBER * RE; |
| | | int inLineDataCount = 5 * LINE_NUMBER * RE; |
| | | for (int l = 0;l < line;l++) |
| | | { |
| | | int outLineCount = outLineDataCount * l; |
| | | for (int re = 0;re < RE;re++) { |
| | | |
| | | |
| | | |
| | | for (int n = 0;n < LINE_NUMBER;n++) |
| | | { |
| | | for (int r = 0;r < 8;r++) { |
| | | int intLineCount = inLineDataCount * r; |
| | | |
| | | for (int c = 0;c < 5;c++) { |
| | | uchar value = ImgUtil::NUMS_LEVEL2[re%10].data.ptr(r)[c]; |
| | | int index = outLineCount; |
| | | index += intLineCount; |
| | | int x = re * LINE_NUMBER * 5 + n * 5 + c; |
| | | index += x; |
| | | data[index] = value > 40 ? 1 : 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | uchar* createTemplateData(int line) { |
| | | unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * line) * _NUMBER_L2_WIDTH * LINE_NUMBER * RE); |
| | | int outLineDataCount = _NUMBER_L2_HEIGHT * _NUMBER_L2_WIDTH * LINE_NUMBER * RE; |
| | | int inLineDataCount = _NUMBER_L2_WIDTH * LINE_NUMBER * RE; |
| | | for (int l = 0;l < line;l++) |
| | | { |
| | | int outLineCount = outLineDataCount * l; |
| | | for (int re = 0;re < RE;re++) { |
| | | for (int n = 0;n < LINE_NUMBER;n++) |
| | | { |
| | | for (int r = 0;r < _NUMBER_L2_HEIGHT;r++) { |
| | | int intLineCount = inLineDataCount * r; |
| | | |
| | | for (int c = 0;c < _NUMBER_L2_WIDTH;c++) { |
| | | uchar value = ImgUtil::NUMS_LEVEL2[n].data.ptr(r)[c]; |
| | | int index = outLineCount; |
| | | index += intLineCount; |
| | | int x = re * LINE_NUMBER * _NUMBER_L2_WIDTH + n * _NUMBER_L2_WIDTH + c; |
| | | index += x; |
| | | data[index] = value > 40 ? 1 : 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | |
| | | void printDevice() { |
| | | |
| | | cl_int err = CL_SUCCESS; |
| | | |
| | | // 1. 获取当前设备所有支持OpenCL的平台的数量 |
| | | cl_uint num_of_platforms = 0; |
| | | err = clGetPlatformIDs(0, 0, &num_of_platforms); |
| | | CHECK_ERRORS(err); |
| | | |
| | | // 2. 获取当前设备所有支持OpenCL的平台的信息 |
| | | cl_platform_id* platforms = new cl_platform_id[num_of_platforms]; |
| | | err = clGetPlatformIDs(num_of_platforms, platforms, 0); |
| | | CHECK_ERRORS(err); |
| | | |
| | | cl_char platform_names[10][50]; |
| | | // 3. 打印平台信息 |
| | | cout << "平台信息:\n"; |
| | | for (cl_uint i = 0; i < num_of_platforms; i++) |
| | | { |
| | | // 获取平台字符串的长度 |
| | | size_t platform_name_length = 0; |
| | | err = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, 0, 0, &platform_name_length); |
| | | CHECK_ERRORS(err); |
| | | |
| | | // 获取平台字符串 |
| | | char* platform_name = new char[platform_name_length]; |
| | | err = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, platform_name_length, platform_name, 0); |
| | | CHECK_ERRORS(err); |
| | | |
| | | cout << " [" << i << "] " << platform_name << endl; |
| | | |
| | | // 备份platform name |
| | | if (i < 10) { |
| | | memset(platform_names[i], 0, 50); |
| | | memcpy(platform_names[i], platform_name, platform_name_length); |
| | | } |
| | | |
| | | delete[] platform_name; |
| | | } |
| | | |
| | | // 4. 查询各平台设备数量 |
| | | struct { |
| | | cl_device_type type; |
| | | const char* name; |
| | | cl_uint count; |
| | | }devices[] = { |
| | | {CL_DEVICE_TYPE_GPU, "CL_DEVICE_TYPE_GPU", 0}, // GPU |
| | | {CL_DEVICE_TYPE_CPU, "CL_DEVICE_TYPE_CPU", 0}, // CPU |
| | | {CL_DEVICE_TYPE_ACCELERATOR, "CL_DEVICE_TYPE_ACCELERATOR", 0} // 加速器 |
| | | }; |
| | | |
| | | // 5. 遍历查询各个平台下拥有的设备数量 |
| | | for (cl_int j = 0; j < num_of_platforms; j++) { |
| | | cl_platform_id platform = platforms[j]; |
| | | cout << "\nplatform:" << platform_names[j] << endl; |
| | | |
| | | // 6. 遍历查询GPU、CPU、ACCELERATOR设备的数量 |
| | | for (cl_int i = 0; i < (sizeof(devices) / sizeof(devices[0])); i++) |
| | | { |
| | | err = clGetDeviceIDs(platform, devices[i].type, 0, 0, &devices[i].count); |
| | | if (err == CL_DEVICE_NOT_FOUND) { |
| | | devices[i].count = 0; |
| | | err = CL_SUCCESS; |
| | | } |
| | | CHECK_ERRORS(err); |
| | | |
| | | cout << "\tdevices:" << devices[i].name |
| | | << "\tcount:" << devices[i].count; |
| | | |
| | | if (devices[i].count != 0) { |
| | | // 7. 遍历查询GPU、CPU、ACCELERATOR 所有设备的信息 |
| | | cl_device_id* device = new cl_device_id[devices[i].count]; |
| | | err = clGetDeviceIDs(platform, devices[i].type, devices[i].count, device, 0); |
| | | |
| | | cout << "\t\tdevice name:"; |
| | | for (cl_int k = 0; k < devices[i].count; k++) |
| | | { |
| | | // 8. 获取和打印各个设备的name |
| | | size_t length = 0; |
| | | cl_device_id each_device = device[k]; |
| | | err = clGetDeviceInfo(each_device, CL_DEVICE_NAME, 0, 0, &length); |
| | | CHECK_ERRORS(err); |
| | | |
| | | char* value = new char[length]; |
| | | err = clGetDeviceInfo(each_device, CL_DEVICE_NAME, length, value, 0); |
| | | CHECK_ERRORS(err); |
| | | cout << value << " "; |
| | | |
| | | // 9. 获取和打印各个设备的version |
| | | err = clGetDeviceInfo(each_device, CL_DEVICE_VERSION, 0, 0, &length); |
| | | CHECK_ERRORS(err); |
| | | |
| | | char* version = new char[length]; |
| | | err = clGetDeviceInfo(each_device, CL_DEVICE_VERSION, length, version, 0); |
| | | CHECK_ERRORS(err); |
| | | cout << version << " "; |
| | | |
| | | delete[] value; |
| | | delete[] version; |
| | | } |
| | | |
| | | delete[] device; |
| | | } |
| | | cout << endl; |
| | | } |
| | | } |
| | | |
| | | delete[] platforms; |
| | | } |