2012-06-06 158 views
0

你好,当我使用Mac OS + OpenCL Framework时,这段代码工作正常,但是当操作系统改为openSUSE 11.4 +(来自AMD的OpenCL实现)时,代码就会出现这样的错误。看来typedef float clfft_complex [2];造成这个错误。你可以说什么呢?OpenCL内核编译错误

错误:

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, 
           &param_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); 

回答

1

首先,我不知道为什么这段代码的工作,但假设你的输入是一个内核指针参数(cl_mem),具有全局特定的内存空间,那么我认为你不能只强制它有一个她的尺寸为2的二维数组,给出__global *input[2]作为参数,因为在调用内核之前已经设置了参数的类型。 (btw在哪里是你的clSetKernelArg()?)

其次,你为什么要这样做你的意见?

input[global_id][0] = 1.5f; 
input[global_id][1] = 5.5f; 

因为输入内存空间通常只应该是只读的,或者该内核只是您的内核的一部分?

,无论如何,我不知道你与内核做什么,所以:

  1. 如果这意味着你只想要一个恒定的浮动[2]变量,它适用 于所有的输入,然后你可以声明

    __constant float var[2] = {1.5f, 5.5f};

  2. 如果你通过input的意思其实就是你的output,你想 写两个浮动POI在一个工作项NTS,那么你就可以 类型,或做改变float2

    vstore2((float2)(1.5f,5.5f), 0, input[global_id]);

    但不要忘记除以2当地工作项..

+0

在内核的输入有clfft_complex(2个浮点数组)的数组,在主机上定义为typedef float clfft_complex [2] ;.由于内核必须知道这种类型,我在内核中定义了它。目前内核的内容绝对不重要,主要问题是“为什么它不能识别typedef float clfft_complex [2];作为类型来投射”。我没有显示clSetKernelArg(),因为在编译cl_program时执行失败。无论如何感谢您的帮助。 –

+0

编译器确认并编译了typedef行,没有任何问题。看看'http://www.khronos.org/message_boards/viewtopic.php?t = 4446'与你有同样的问题。 – ardiyu07

+0

很明显,谢谢。 –