OpenCl não pode compilar o kernel com 'printf'

Sep 20 2020

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

2 pmdj Sep 20 2020 at 16:42

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.