OpenCl não pode compilar o kernel com 'printf'
Estou recebendo o erro error: implicit declaration of function 'printf' is invalid in OpenCLquando tento construir um kernel OpenCL. O código do kernel é este
__kernel void conj_grad(int dim, int num_vals, __local float *r,
__local float *x, __local float* A_times_p, __local float *p,
__global int *rows, __global int *cols, __global float *A,
__global float *b, __global float *result) {
local float alpha, r_length, old_r_dot_r, new_r_dot_r;
local int iteration;
int id = get_local_id(0);
int start_index = -1;
int end_index = -1;
float Ap_dot_p;
printf("OpenCL Kernel ID: %d\n", id);
Isso me dá o erro abaixo
input.cl:14:4: error: implicit declaration of function 'printf' is invalid in OpenCL
input.cl:14:4: note: did you mean 'rint'?
/usr/include/clc/math/unary_decl.inc:1:39: note: 'rint' declared here
/usr/include/clc/math/rint.h:2:24: note: expanded from macro '__CLC_FUNCTION'
input.cl:46:45: warning: double precision constant requires cl_khr_fp64, casting to single precision
Estou recebendo um código de retorno negativo desta função err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
Já tentei as soluções para essas questões. Usar printf () no kernel OpenCL e a função printf não funciona no kernel OpenCL e nenhuma dessas soluções corrige isso. Quando tento essas soluções, vejo um aviso comoinput.cl:1:26: warning: unknown OpenCL extension 'cl_amd_printf' - ignoring
Conclusão
Parece que meu sistema não suporta as extensões printf. O código abaixo (roubado da resposta de pmdj) me dá a seguinte saída. Parece uma história clássica de não depender de extensões específicas do fornecedor para um padrão.
#include <stdio.h>
#include <CL/cl.h>
int main(void) {
char ext_str[1024] = "";
size_t ext_str_len = sizeof(ext_str) - 1;
cl_device_id device_id;
cl_int err;
cl_platform_id platform;
err = clGetPlatformIDs(1, &platform, NULL);
if(err < 0) {
perror("Couldn't identify a platform");
exit(1);
}
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
if(err < 0) {
perror("Couldn't access any devices");
exit(1);
}
err = clGetDeviceInfo(device_id, CL_DEVICE_EXTENSIONS, sizeof(ext_str), ext_str, &ext_str_len);
if(err < 0) {
perror("Couldn't get device info");
exit(1);
}
printf("CL extensions (%lu): '%s'\n", ext_str_len, ext_str);
return 0;
}
CL extensions (248): 'cl_khr_byte_addressable_store cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_int64_base_atomics cl_khr_int64_extended_atomics cl_khr_fp64 cl_khr_fp16'
Respostas
Como você descobriu, printfnão faz parte do OpenCL padrão, mas algumas implementações oferecem extensões que o permitem.
Para verificar se há extensões suportadas por sua implementação, tente algo assim:
char ext_str[1024] = "";
size_t ext_str_len = sizeof(ext_str) - 1;
err = clGetDeviceInfo(device_id, CL_DEVICE_EXTENSIONS, sizeof(ext_str), ext_str, &ext_str_len);
printf("CL extensions (%lu): '%s'\n", ext_str_len, ext_str);
Se não houver cl_*_printfextensões listadas, provavelmente você está sem sorte. Se algum estiver listado, você precisará ativá-lo conforme descrito nas outras respostas vinculadas. Você também pode querer verificar a especificação da extensão específica que você suporta, caso ela exiba alguma peculiaridade em particular.