代码在Eclipse上说COULD NOT CREATE KERNEL后终止

我正在尝试将MJPEG解码器的顺序C代码转换为OpenCL。 我从这个 github项目中获得了C代码。

我现在正在尝试将IDCT的原始C代码转换为OpenCL。

我复制并粘贴了IDC的.c文件中的代码并粘贴到我命名为invCosine.cl .cl文件中。

invCosine.cl

  #define IDCT_INT_MIN (- IDCT_INT_MAX - 1) #define IDCT_INT_MAX 2147483647 /* * Useful constants: */ /* * ck = cos(k*pi/16) = s8-k = sin((8-k)*pi/16) times 1 << C_BITS and * rounded */ #define c0_1 16384 #define c0_s2 23170 #define c1_1 16069 #define c1_s2 22725 .... .... .... .... .... .... __kernel void idct1D(__global cl_int *Y) { cl_int z1[8], z2[8], z3[8]; /* * Stage 1: */ but(Y[0], Y[4], z1[1], z1[0]); rot(1, 6, Y[2], Y[6], &z1[2], &z1[3]); but(Y[1], Y[7], z1[4], z1[7]); z1[5] = CMUL(sqrt2, Y[3]); z1[6] = CMUL(sqrt2, Y[5]); /* * Stage 2: */ but(z1[0], z1[3], z2[3], z2[0]); but(z1[1], z1[2], z2[2], z2[1]); but(z1[4], z1[6], z2[6], z2[4]); but(z1[7], z1[5], z2[5], z2[7]); /* * Stage 3: */ z3[0] = z2[0]; z3[1] = z2[1]; z3[2] = z2[2]; z3[3] = z2[3]; rot(0, 3, z2[4], z2[7], &z3[4], &z3[7]); rot(0, 1, z2[5], z2[6], &z3[5], &z3[6]); /* * Final stage 4: */ but(z3[0], z3[7], Y[7], Y[0]); but(z3[1], z3[6], Y[6], Y[1]); but(z3[2], z3[5], Y[5], Y[2]); but(z3[3], z3[4], Y[4], Y[3]); } 

我基本上复制并粘贴了名为idct.c原始文件中的#define语句。 我还从同一个.c文件中复制并粘贴了内核的代码,并将关键字__kernel__globalcl_int添加到此内核中。 目前,我不想编写优化的OpenCL代码。 我只是想将IDCT计算卸载到GPU。

我在主文件中的主机代码如下:

 //////////////OpenCL parameters///////////////////////////// int out; cl_platform_id platform_id; cl_uint ret_num_platforms; cl_device_id device_id; cl_uint ret_num_devices; cl_context context; cl_command_queue command_queue; cl_program program; //size_t kernel_code_size; int *result; cl_int ret; cl_kernel kernel; int storeResult; FILE *fp; const char fileName[] = "/root/Downloads/tima_seq_version/src/invCosine.cl"; size_t source_size; char *source_str; /* Load kernel source file */ fp = fopen(fileName, "rb"); if (!fp) { fprintf(stderr, "Failed to load kernel.\n"); exit(1); } source_str = (char *)malloc(MAX_SOURCE_SIZE); source_size = fread(source_str, 1, MAX_SOURCE_SIZE, fp); fclose(fp); /////////Set platform, context, command-queue...........///////////////////////// /* Get Platform */ ret= clGetPlatformIDs(1, &platform_id, &ret_num_platforms); if (ret_num_platforms == 0) { printf("Found 0 platforms!\n"); return EXIT_FAILURE; } /* Get Device */ ret= clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, &ret_num_devices); printf("Number of devices: %d\n", ret_num_devices); /* Create Context */ context = clCreateContext(0, 1, &device_id, NULL, NULL, &ret); if (!context) { printf("NO cCONTEXT\n"); return EXIT_FAILURE; } /* Create Command Queue */ command_queue = clCreateCommandQueue(context, device_id, 0, &ret); if (!command_queue) { printf("NO command queue\n"); return EXIT_FAILURE; } /* Create kernel from source */ program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret); if (!program) { printf("NO PROGRAM!!!!\n"); return EXIT_FAILURE; } clBuildProgram(program, 1, &device_id, "", NULL, NULL); if (ret != CL_SUCCESS) { printf("building program failed\n"); if (ret == CL_BUILD_PROGRAM_FAILURE) { size_t log_size; clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size); char *log = (char *) malloc(log_size); clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, log_size, log, NULL); printf("%s\n", log); } } kernel= clCreateKernel(program, "idct1D", &ret); if( !kernel || ret != CL_SUCCESS) { printf("-----COULD NOT CREATE KERNEL!!---\n"); exit(1); } 

当我运行应用程序时,我得到以下输出:

 Number of devices: 2 -----COULD NOT CREATE KERNEL!!--- 

为了理解为什么没有检测到内核,我删除了所有的idct代码,并将此链接中的内核代码复制并粘贴到我的.cl文件中:

 __kernel void taskParallelAdd(__global float* A, __global float* B, __global float* C) { int base = 0; C[base+0] = A[base+0] + B[base+0]; C[base+4] = A[base+4] + B[base+4]; C[base+8] = A[base+8] + B[base+8]; C[base+12] = A[base+12] + B[base+12]; } 

当我再次运行应用程序时,它运行顺利,并没有产生相同的错误。

为什么我的idct内核没被检测到?

PS我正在使用Eclipse IDE编写和运行我的代码。

您收到内核错误的原因是,您实际上没有检查clBuildProgram调用中的错误代码。 如果你运行ret = clBuildProgram(program, 1, &device_id, "", NULL, NULL); 相反,你会在clBuildProgram调用中得到一个错误。

您收到该错误的原因是,OpenCL C语言没有cl_int数据类型。 这意味着你不能在内核中使用它。 cl_ *类型用于主机端使用。 在像你这样的.cl文件中,你需要使用常规类型,如int,float,char等。

假设您提供的代码具有所有必要的定义butrot宏,将内核更改为使用int而不是cl_int应该可以解决您的问题。