#include "OpenCLExcuter.h" #include void OpenCLExcuter::init() { //»ñȡƽ̨ error = clGetPlatformIDs(1, &platforms, &num_of_platforms); if (error != 0) { throw("Get platform failed!"); } //»ñÈ¡É豸 error = clGetDeviceIDs(platforms, CL_DEVICE_TYPE_GPU, 1, &devices, NULL); if (error != 0) { throw("Get device failed!"); } //´´½¨ÉÏÏÂÎÄ context = clCreateContext(NULL, 1, &devices, NULL, NULL, &error); if (error != 0) { throw("Creat context failed!"); } //´´½¨³ÌÐò£»×¢ÒâÒªÓÃ"rb" fopen_s(&program_handle, "D:\\workspace\\CPlusTest\\ConsoleApplication\\ConsoleApplication\\kernel.cl", "rb"); if (program_handle == NULL) { throw("The kernle can not be opened!"); } 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) { throw("Read kernel failed!"); } fclose(program_handle); program = clCreateProgramWithSource(context, 1, (const char**)&program_buffer, &program_size, &error); if (error < 0) { throw("Couldn't create the program!"); } //±àÒë³ÌÐò 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); throw("Build Program Failed"); } free(program_buffer); //´´½¨ÃüÁî¶ÓÁÐ queue = clCreateCommandQueue(context, devices, CL_QUEUE_PROFILING_ENABLE, &error); if (error < 0) { throw("Coudn't create the command queue"); } } unsigned char** OpenCLExcuter::recognition_numbers(unsigned char* data, unsigned char* b_in, const int rows, const int cols,const int num_width, const int num_height, const int num_count) throw(std::string) { //----------³ÌÐòÕýÎÄ¿ªÊ¼--------- auto startexectime = std::chrono::steady_clock::now(); const int resultSize = rows * cols / (num_width * num_height); const int inputSize = rows * cols; //´´½¨ÄÚºË kernel = clCreateKernel(program, "recognition_numbers_1", &error); if (kernel == NULL) { throw("Couldn't create kernel!\n"); } //³õʼ»¯²ÎÊý unsigned char* result = (unsigned char*)malloc(sizeof(unsigned char) * resultSize); //´´½¨»º´æ¶ÔÏó cl_mem memObject1 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(unsigned char) * inputSize, data, &error); if (error < 0) { throw("Creat memObject1 failed!\n"); } cl_mem memObject2 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(unsigned char) * inputSize, b_in, &error); if (error < 0) { throw("Creat memObject2 failed!\n"); } cl_mem memObject4 = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(unsigned char) * resultSize, NULL, &error); if (error < 0) { throw("Creat memObject4 failed!\n"); } int width = cols / num_width; //ÉèÖÃÄں˲ÎÊý error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObject1); error |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &memObject2); error |= clSetKernelArg(kernel, 2, sizeof(int), &width); error |= clSetKernelArg(kernel, 3, sizeof(int), &num_width); error |= clSetKernelArg(kernel, 4, sizeof(int), &num_height); error |= clSetKernelArg(kernel, 5, sizeof(int), &num_count); error |= clSetKernelArg(kernel, 6, sizeof(cl_mem), &memObject4); if (error != CL_SUCCESS) { throw("Error setting kernel arguments!\n"); } //Ö´ÐÐÄÚºË size_t globalWorkSize[1] = { resultSize }; size_t localWorkSize[1] = { 1 }; const int work_dim = 1; error = clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error queuing kernel for execution!\n"); } //¶ÁȡִÐнá¹û error = clEnqueueReadBuffer(queue, memObject4, CL_TRUE, 0, resultSize * sizeof(unsigned char), result, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error reading result buffer!\n"); } /* printf("½á¹û1£º\n"); for (int r = 0; r < rows / 8; r++) { for (int c = 0; c < cols / 5 ; c++) { printf("%d ", result[r * cols/5 + c]); } printf("\n-------\n"); } */ //¿ªÊ¼µÚ¶þ½×¶ÎµÄ¼ÆËã int resultSize2 = resultSize / 10; unsigned char* result2 = (unsigned char*)malloc(sizeof(unsigned char) * resultSize2); kernel = clCreateKernel(program, "recognition_numbers_2", &error); if (kernel == NULL) { throw("Couldn't create kernel!\n"); } cl_mem memObject21 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(unsigned char) * resultSize, result, &error); if (error < 0) { throw("Creat memObject1 failed!\n"); } cl_mem memObject22 = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(unsigned char) * resultSize2, NULL, &error); error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObject21); error |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &memObject22); if (error != CL_SUCCESS) { throw("Error setting kernel arguments!\n"); } size_t globalWorkSize2[1] = { resultSize2 }; error = clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, globalWorkSize2, localWorkSize, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error queuing kernel for execution!\n"); } //¶ÁȡִÐнá¹û error = clEnqueueReadBuffer(queue, memObject22, CL_TRUE, 0, resultSize2 * sizeof(unsigned char), result2, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error reading result buffer!\n"); } //ÏÔʾ½á¹û /* printf("½á¹û2£º\n"); for (int r = 0; r < rows/8; r++) { for (int c = 0; c < cols/(5*10); c++) { printf("%d ", result2[r*cols/(5*10)+c]); } printf("\n-------\n"); } */ clReleaseKernel(kernel); clReleaseMemObject(memObject1); clReleaseMemObject(memObject2); clReleaseMemObject(memObject4); clReleaseMemObject(memObject21); clReleaseMemObject(memObject22); //¸´ÖÆ×îºóµÄ¼ÆËã½á¹û int fcol = num_count; int frow = rows / num_height; unsigned char** fresult = (unsigned char**)malloc(sizeof(unsigned char*) * frow); for (int r = 0; r < frow; r++) { fresult[r] = (unsigned char*)malloc(sizeof(unsigned char) * fcol); for (int c = 0; c < fcol; c++) { fresult[r][c] = result2[r * fcol + c]; } } free(result); free(result2); //std::cout << " Ö´ÐнáÊø£º" << std::chrono::duration_cast(std::chrono::steady_clock::now() - startexectime).count() << std::endl; return fresult; } void OpenCLExcuter::splitL2Num(unsigned char* img, int img_width, int img_height, int* pos, int pos_count, unsigned char* zero, int num_width,int num_height,int num_count, unsigned char* result) { clock_t time_0 = clock(); kernel = clCreateKernel(program, "split_num", &error); if (kernel == NULL) { throw("Couldn't create kernel!\n"); } int inputSize = (img_width * img_height); int resultSize = (pos_count / 4) * (num_count * num_width * num_height * 10); //´´½¨»º´æ¶ÔÏó cl_mem memObject1 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(unsigned char) * inputSize, img, &error); if (error < 0) { throw("Creat memObject1 failed!\n"); } cl_mem memObject2 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(int) * pos_count * 4, pos, &error); if (error < 0) { throw("Creat memObject2 failed!\n"); } cl_mem memObject3 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(unsigned char) * num_width * num_height, zero, &error); if (error < 0) { throw("Creat memObject3 failed!\n"); } cl_mem memObject4 = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(unsigned char) * resultSize, NULL, &error); if (error < 0) { throw("Creat memObject4 failed!\n"); } //ÉèÖÃÄں˲ÎÊý error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObject1); error |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &memObject2); error |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &memObject3); error |= clSetKernelArg(kernel, 3, sizeof(int), &img_width); error |= clSetKernelArg(kernel, 4, sizeof(int), &num_width); error |= clSetKernelArg(kernel, 5, sizeof(int), &num_height); error |= clSetKernelArg(kernel, 6, sizeof(int), &num_count); error |= clSetKernelArg(kernel, 7, sizeof(cl_mem), &memObject4); if (error != CL_SUCCESS) { throw("Error setting kernel arguments!\n"); } //Ö´ÐÐÄÚºË size_t globalWorkSize[1] = { pos_count }; size_t localWorkSize[1] = { 1 }; const int work_dim = 1; error = clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error queuing kernel for execution!\n"); } //¶ÁȡִÐнá¹û error = clEnqueueReadBuffer(queue, memObject4, CL_TRUE, 0, resultSize * sizeof(unsigned char), result, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error reading result buffer!\n"); } clReleaseKernel(kernel); clReleaseMemObject(memObject1); clReleaseMemObject(memObject2); clReleaseMemObject(memObject3); clReleaseMemObject(memObject4); std::cout << " ºÄʱ£º" << (clock() - time_0) << std::endl; } void OpenCLExcuter::createNumberTemplates(int lines,int num_width,int num_height,int num_count, uchar* numsOneLevelData, unsigned char* result) { kernel = clCreateKernel(program, "createTemplateNumbers", &error); if (kernel == NULL) { throw("Couldn't create kernel!\n"); } int inputSize = num_height * num_width * 10; int resultSize = lines * num_count * 10 * num_height * num_width; //´´½¨»º´æ¶ÔÏó cl_mem memObject1 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(uchar) * inputSize, numsOneLevelData, &error); if (error < 0) { throw("Creat memObject1 failed!\n"); } cl_mem memObject2 = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(unsigned char) * resultSize, NULL, &error); if (error < 0) { throw("Creat memObject2 failed!\n"); } //ÉèÖÃÄں˲ÎÊý error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObject1); error |= clSetKernelArg(kernel, 1, sizeof(int), &num_width); error |= clSetKernelArg(kernel, 2, sizeof(int), &num_height); error |= clSetKernelArg(kernel, 3, sizeof(int), &num_count); error |= clSetKernelArg(kernel, 4, sizeof(cl_mem), &memObject2); if (error != CL_SUCCESS) { throw("Error setting kernel arguments!\n"); } //Ö´ÐÐÄÚºË size_t globalWorkSize[1] = { lines }; size_t localWorkSize[1] = { 1 }; const int work_dim = 1; error = clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error queuing kernel for execution!\n"); } //¶ÁȡִÐнá¹û error = clEnqueueReadBuffer(queue, memObject2, CL_TRUE, 0, resultSize * sizeof(unsigned char), result, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error reading result buffer!\n"); } clReleaseKernel(kernel); clReleaseMemObject(memObject1); clReleaseMemObject(memObject2); } void OpenCLExcuter::splitL2RowData(unsigned char* imgs, int imgWidth, int imgHeight, int* rowIndexs, int lines, int* result) { kernel = clCreateKernel(program, "splitRowData", &error); if (kernel == NULL) { throw("Couldn't create kernel!\n"); } int inputSize = imgWidth * imgHeight; int resultSize = lines * 7 * 4; //´´½¨»º´æ¶ÔÏó cl_mem memObject1 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(uchar) * inputSize, imgs, &error); if (error < 0) { throw("Creat memObject1 failed!\n"); } cl_mem memObject2 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(int) * lines * 4, rowIndexs, &error); if (error < 0) { throw("Creat memObject2 failed!\n"); } cl_mem memObject3 = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(int) * resultSize, NULL, &error); if (error < 0) { throw("Creat memObject3 failed!\n"); } //ÉèÖÃÄں˲ÎÊý error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObject1); error = clSetKernelArg(kernel, 1, sizeof(cl_mem), &memObject2); error |= clSetKernelArg(kernel, 2, sizeof(int), &imgWidth); error |= clSetKernelArg(kernel, 3, sizeof(cl_mem), &memObject3); if (error != CL_SUCCESS) { throw("Error setting kernel arguments!\n"); } //Ö´ÐÐÄÚºË size_t globalWorkSize[1] = { lines }; size_t localWorkSize[1] = { 1 }; const int work_dim = 1; error = clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error queuing kernel for execution!\n"); } //¶ÁȡִÐнá¹û error = clEnqueueReadBuffer(queue, memObject3, CL_TRUE, 0, resultSize * sizeof(int), result, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error reading result buffer!\n"); } //printf("%d %d %d %d \n", result[0], result[1], result[2], result[3]); clReleaseKernel(kernel); clReleaseMemObject(memObject1); clReleaseMemObject(memObject2); clReleaseMemObject(memObject3); } void OpenCLExcuter::recognitionNotNum(unsigned char* imgs, int imgWidth, int imgHeight, int* rowIndexs,int colCount, int lines, int* result) { clock_t time_1 = clock(); kernel = clCreateKernel(program, "recognition_not_num", &error); if (kernel == NULL) { throw("Couldn't create kernel!\n"); } int inputSize = imgWidth * imgHeight; int resultSize = lines * 3; //´´½¨»º´æ¶ÔÏó cl_mem memObject1 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(uchar) * inputSize, imgs, &error); if (error < 0) { throw("Creat memObject1 failed!\n"); } cl_mem memObject2 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(int) * lines * 4 * colCount, rowIndexs, &error); if (error < 0) { throw("Creat memObject2 failed!\n"); } cl_mem memObject3 = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(int) * resultSize, NULL, &error); if (error < 0) { throw("Creat memObject3 failed!\n"); } //ÉèÖÃÄں˲ÎÊý error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObject1); error = clSetKernelArg(kernel, 1, sizeof(cl_mem), &memObject2); error |= clSetKernelArg(kernel, 2, sizeof(int), &imgWidth); error |= clSetKernelArg(kernel, 3, sizeof(cl_mem), &memObject3); if (error != CL_SUCCESS) { throw("Error setting kernel arguments!\n"); } //Ö´ÐÐÄÚºË size_t globalWorkSize[1] = { resultSize }; size_t localWorkSize[1] = { 1 }; const int work_dim = 1; error = clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error queuing kernel for execution!\n"); } //¶ÁȡִÐнá¹û error = clEnqueueReadBuffer(queue, memObject3, CL_TRUE, 0, resultSize * sizeof(int), result, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error reading result buffer!\n"); } //printf("%d %d %d %d \n", result[0], result[1], result[2], result[3]); clReleaseKernel(kernel); clReleaseMemObject(memObject1); clReleaseMemObject(memObject2); clReleaseMemObject(memObject3); } void OpenCLExcuter::rgb2Gray(unsigned char* imgs, int imgWidth, int imgHeight, unsigned char* result) { kernel = clCreateKernel(program, "rgb2GrayImg", &error); if (kernel == NULL) { throw("Couldn't create kernel!\n"); } int inputSize = imgWidth * imgHeight * 3; int resultSize = imgWidth * imgHeight; //´´½¨»º´æ¶ÔÏó cl_mem memObject1 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(uchar) * inputSize, imgs, &error); if (error < 0) { throw("Creat memObject1 failed!\n"); } cl_mem memObject2 = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(uchar) * resultSize, NULL, &error); if (error < 0) { throw("Creat memObject2 failed!\n"); } //ÉèÖÃÄں˲ÎÊý error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObject1); error |= clSetKernelArg(kernel, 1, sizeof(int), &imgWidth); error = clSetKernelArg(kernel, 2, sizeof(cl_mem), &memObject2); if (error != CL_SUCCESS) { throw("Error setting kernel arguments!\n"); } //Ö´ÐÐÄÚºË size_t globalWorkSize[1] = { imgHeight }; size_t localWorkSize[1] = { 1 }; const int work_dim = 1; error = clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error queuing kernel for execution!\n"); } //¶ÁȡִÐнá¹û error = clEnqueueReadBuffer(queue, memObject2, CL_TRUE, 0, resultSize * sizeof(uchar), result, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error reading result buffer!\n"); } clReleaseKernel(kernel); clReleaseMemObject(memObject1); clReleaseMemObject(memObject2); } void OpenCLExcuter::rgba2Gray(unsigned char* imgs, int imgWidth, int imgHeight, unsigned char* result) { kernel = clCreateKernel(program, "rgba2GrayImg", &error); if (kernel == NULL) { throw("Couldn't create kernel!\n"); } int inputSize = imgWidth * imgHeight * 4; int resultSize = imgWidth * imgHeight; //´´½¨»º´æ¶ÔÏó cl_mem memObject1 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(uchar) * inputSize, imgs, &error); if (error < 0) { throw("Creat memObject1 failed!\n"); } cl_mem memObject2 = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(uchar) * resultSize, NULL, &error); if (error < 0) { throw("Creat memObject2 failed!\n"); } //ÉèÖÃÄں˲ÎÊý error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObject1); error |= clSetKernelArg(kernel, 1, sizeof(int), &imgWidth); error = clSetKernelArg(kernel, 2, sizeof(cl_mem), &memObject2); if (error != CL_SUCCESS) { throw("Error setting kernel arguments!\n"); } //Ö´ÐÐÄÚºË size_t globalWorkSize[1] = { imgHeight }; size_t localWorkSize[1] = { 1 }; const int work_dim = 1; error = clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error queuing kernel for execution!\n"); } //¶ÁȡִÐнá¹û error = clEnqueueReadBuffer(queue, memObject2, CL_TRUE, 0, resultSize * sizeof(uchar), result, 0, NULL, NULL); if (error != CL_SUCCESS) { throw("Error reading result buffer!\n"); } clReleaseKernel(kernel); clReleaseMemObject(memObject1); clReleaseMemObject(memObject2); } void OpenCLExcuter::destory() { //ÊÍ·Å×ÊÔ´ clReleaseDevice(devices); clReleaseContext(context); clReleaseProgram(program); clReleaseCommandQueue(queue); }