OpenCl no puede compilar el kernel con 'printf'

Sep 20 2020

Recibo el error error: implicit declaration of function 'printf' is invalid in OpenCLcuando intento compilar un kernel OpenCL. El código del kernel es 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);   

Esto me da el siguiente error

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

Recibo un código de retorno negativo de esta función err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);

Ya probé las soluciones de estas preguntas El uso de printf () en el kernel OpenCL y la función printf no funciona en el kernel OpenCL , y ninguna de estas soluciones lo soluciona. Cuando pruebo estas soluciones, veo una advertencia comoinput.cl:1:26: warning: unknown OpenCL extension 'cl_amd_printf' - ignoring

Conclusión

Parece que mi sistema no admite las extensiones printf. El código a continuación (robando la respuesta de pmdj) me da el siguiente resultado. Parece una historia clásica de no depender de extensiones específicas del proveedor para un estándar.

#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'

Respuestas

2 pmdj Sep 20 2020 at 16:42

Como ha descubierto, printfno forma parte de OpenCL estándar, pero algunas implementaciones ofrecen extensiones que lo habilitan.

Para verificar las extensiones compatibles con su implementación, intente algo como esto:

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);

Si no hay ninguna cl_*_printfextensión en la lista, probablemente no tenga suerte. Si aparece uno, deberá habilitarlo como se describe en las otras respuestas que vinculó. También es posible que desee verificar la especificación de la extensión específica que admite el suyo en caso de que presente alguna peculiaridad en particular.