1
votes

I am getting the error error: implicit declaration of function 'printf' is invalid in OpenCL when I try to build an OpenCL kernel. The kernel code is this

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

This gives me the error below

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

I am getting a negative return code from this function err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);

I have already tried the solutions from these questions Using printf() in OpenCL kernel and printf function doesn't work in OpenCL kernel, and neither of these solutions fix it. When I try these solutions, I see a warning such as input.cl:1:26: warning: unknown OpenCL extension 'cl_amd_printf' - ignoring

Conclusion

Looks like my system does not support the printf extensions. The code below (stealing from pmdj's answer) gives me the following output. Looks like a classic story of don't depend on vendor specific extensions to a standard.

#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'
1
OpenCL does not support printf. Some implementations support it as an extension, others maybe don't. Printing from a kernel doesn't generally make much sense. - n. 1.8e9-where's-my-share m.

1 Answers

2
votes

As you've found, printf isn't part of standard OpenCL, but some implementations offer extensions which enable it.

To check for extensions supported by your implementation, try something like this:

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

If there aren't any cl_*_printf extensions listed, you are probably out of luck. If one is listed, you'll need to enable it as described in the other answers you linked. You might also want to check the specification for the specific extension yours supports in case it exhibits any particular quirks.