2012-06-06 6 views
0

안녕하세요. Mac OS + OpenCL 프레임 워크를 사용했을 때이 코드가 제대로 작동했지만 OS가 openSUSE 11.4+ (OpenCL 구현은 AMD)로 바뀌면 코드가 이러한 오류를 발생시킵니다. 그것은 typedef 플로트 것 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를 작성 를 원하는 경우 하나의 작업 항목에서 국세청은, 당신은 , 또는 수행하여 float2에 유형을 변경할 수 있습니다 ..

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

    을하지만 2 로컬 작업 항목을 분할하는 것을 잊지 마세요

+0

에 커널의 입력 나는 typedef float clfft_complex [2];로 호스트에 정의 된 clfft_complex (2 float 배열) 배열을가집니다. 커널은이 유형을 알아야하기 때문에 커널 내부에 정의했습니다. 커널의 내용이 절대적으로 중요하지 않은 순간, 주된 이슈는 "typedef floft clfft_complex [2]를 캐스팅을위한 타입으로 인식 할 수없는 이유"입니다. cl_program을 컴파일 할 때 실행이 실패하기 때문에 clSetKernelArg()를 표시하지 않았습니다. 어쨌든 도움을 주셔서 감사합니다. –

+0

컴파일러는 인식하고 typedef 줄을 아무 문제없이 컴파일합니다. 'http : //www.khronos.org/message_boards/viewtopic.php? t = 4446'과 같은 문제가 생겼습니다. – ardiyu07

+0

감사합니다. –

관련 문제