1

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'
Kyle
  • 190
  • 2
  • 9
  • Does this - https://stackoverflow.com/a/5786682/13929340 and this - https://stackoverflow.com/a/58621074/13929340 help ? – A P Jo Sep 20 '20 at 07:46
  • 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. m. could be an AI Sep 20 '20 at 09:08

1 Answers1

3

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.

pmdj
  • 22,018
  • 3
  • 52
  • 103
  • This is certainly more accurate. Do you reccommend I delete mine ? – A P Jo Sep 20 '20 at 09:45
  • @APJo Honestly, I don't think your answer adds anything particularly useful, but it's up to you of course. – pmdj Sep 20 '20 at 09:46
  • Appreciate the honesty, I'll remove mine, I don't intend to give bad answers :) – A P Jo Sep 20 '20 at 09:47
  • @APJo Sounds sensible. I try to be positive about people's contributions on this site, but it's usually not helpful to answer questions about technology you've never used, at least not without some deeper research. To be fair, the asker probably mis-tagged the question with the `c` tag, which perhaps led you to think it was about regular C code. (FWIW, I will occasionally try to answer questions I don't immediately know the exact answer to - it can be a great way of learning - so don't be discouraged. Sometimes it works out and I can help AND learn, sometimes I find myself out of my depth.) – pmdj Sep 20 '20 at 09:51
  • Thanks for the help! Are the supported OpenCL extensions device specific, or is it simply up to the driver? – Kyle Sep 20 '20 at 23:03
  • It's conceivable that some drivers make the feature available on some devices but not others, but I'd expect that in most cases, if a driver supports the feature, it will expose it for all devices it supports. Support may vary from version to version of course. – pmdj Sep 21 '20 at 08:52