![](/img/trans.png)
[英]Cannot compile `enqueue_kernel` on opencl 2.1 NEO device
[英]An error of OpenCL kernel compile
您好,当我使用Mac OS + OpenCL Framework时,此代码正常工作,但是当OS更改为openSUSE 11.4 +(AMD的OpenCL实现)时,该代码将引发此类错误。 似乎是typedef float clfft_complex [2]; 导致此错误。 您能说些什么?
错误:
Err: "/tmp/OCLRS2tPp.cl", line 4: error: kernel pointer arguments must point to
addrSpace global, local, or constant
__kernel void linear_interp(__global clfft_complex *input,
^
1 error detected in the compilation of "/tmp/OCLRS2tPp.cl".
Internal error: clc compiler invocation failed.
内核代码:
typedef float clfft_complex[2];
__kernel void linear_interp(__global clfft_complex *input,
__global clfft_complex *output)
{
int global_id = get_global_id(0);
input[global_id][0] = 1.5f;
input[global_id][1] = 5.5f;
}
主机代码:
//////////////////////////////////
/* Preparing OpenCL Environment */
//////////////////////////////////
cl_uint cl_platformsN = 0;
cl_platform_id *cl_platformIDs = NULL;
clGetPlatformIDs (0, NULL, &cl_platformsN);
cl_platformIDs = (cl_platform_id*)malloc( cl_platformsN * sizeof(cl_platform_id));
clGetPlatformIDs(cl_platformsN, cl_platformIDs, NULL);
cl_int status = CL_SUCCESS;
cl_device_id device; // Compute device
cl_context context; // Compute context
CL_CHECK_ERROR(clGetDeviceIDs(cl_platformIDs[0], DEVICE_TYPE, 1, &device, NULL));
context = clCreateContext(NULL, 1, &device, NULL, NULL, &status);
////////////
/* Device */
////////////
cl_uint wavefronts_per_SIMD = 7;
cl_int device_max_cu;
size_t wg_count;
size_t global_work_size;
#if DEVICE_TYPE == CL_DEVICE_TYPE_GPU
size_t local_work_size = 64;
#else
size_t local_work_size = 1;
#endif
// Get info about the compute units on the device
CL_CHECK_ERROR(clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cl_uint), &device_max_cu, NULL));
wg_count = device_max_cu * wavefronts_per_SIMD;
global_work_size = wg_count * local_work_size;
/////////////////////
/* Input Data Part */
/////////////////////
/* Input a slice properties */
int bits_per_sample;
int samples_per_pixel;
int theta_size;
int slice_size;
/* Read the slice */
clfft_complex *data_tiff = tiff_read_complex(tiff_input,
&bits_per_sample,
&samples_per_pixel,
&slice_size,
&theta_size);
////////////////////////
/* OpenCL - DFI Part */
////////////////////////
/* Sync events */
const int events_num = 5;
cl_event event_list[events_num];
/* Command Queue */
cl_command_queue command_queue = clCreateCommandQueue(context, device, 0, &status);
/* Program */
const char* programSource = load_program_source(KERNELS_FILE_PATH);
if(programSource == NULL) {
fprintf(stderr, "Programm '%s' can not be created. File was not found.", KERNELS_FILE_PATH);
return;
}
cl_program program = clCreateProgramWithSource(context, 1,
(const char**)&programSource, NULL,
&status);
status = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
size_t paramValueSize = 1024 * 1024, param_value_size_ret;
char *paramValue;
paramValue = (char*)calloc(paramValueSize, sizeof(char));
status = clGetProgramBuildInfo( program,
device,
CL_PROGRAM_BUILD_LOG,
paramValueSize,
paramValue,
¶m_value_size_ret);
printf("Err: %s", paramValue);
char buf[0x10000];
clGetProgramBuildInfo(program,
device,
CL_PROGRAM_BUILD_LOG,
0x10000,
buf,
NULL);
if(status != CL_SUCCESS) {
fprintf(stderr, "Programm '%s' can not be build. (%s)", KERNELS_FILE_PATH, opencl_map_error(status));
return;
}
/* Kernels */
cl_kernel kernel_linear_interp = clCreateKernel(program, "linear_interp", &status);
首先,我不知道这段代码为什么起作用,但是假设您的输入是一个内核指针参数( cl_mem
),该参数在全局中具有特定的内存空间,那么我认为您不能仅仅强制它具有另一个大小为2的维数组给__global *input[2]
作为参数,因为在调用内核之前已经设置了参数类型。 (顺便说一下,您的clSetKernelArg()
在哪里?)
第二,为什么要对输入内容这样做?
input[global_id][0] = 1.5f;
input[global_id][1] = 5.5f;
因为输入存储空间通常只应该是只读的。或者该内核只是您的一部分?
无论如何,我不确定您正在使用该内核做什么,所以:
如果这意味着您只想要一个常量float [2]变量,该变量适用于所有输入,则只需声明
__constant float var[2] = {1.5f, 5.5f};
如果input
实际上是您的output
,并且您想在单个工作项中编写两个浮点,则可以将类型更改为float2
,或者执行以下操作:
vstore2((float2)(1.5f,5.5f), 0, input[global_id]);
但不要忘记将本地工作项除以2。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.