【问题标题】:OpenCl cannot compile kernel with 'printf'OpenCl 无法使用“printf”编译内核
【发布时间】:2020-09-19 23:32:05
【问题描述】:

我在尝试构建 OpenCL 内核时收到错误 error: implicit declaration of function 'printf' is invalid in OpenCL。内核代码是这样的

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

这给了我下面的错误

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

我从这个函数err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);得到一个否定的返回码

我已经尝试了Using printf() in OpenCL kernelprintf function doesn't work in OpenCL kernel这些问题的解决方案,但这些解决方案都没有解决它。当我尝试这些解决方案时,我会看到一个警告,例如 input.cl:1:26: warning: unknown OpenCL extension 'cl_amd_printf' - ignoring

结论

看来我的系统不支持 printf 扩展。下面的代码(从 pmdj 的答案中窃取)给了我以下输出。看起来像是不依赖于供应商特定的标准扩展的经典故事。

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

【问题讨论】:

标签: opencl amd


【解决方案1】:

如您所见,printf 不是标准 OpenCL 的一部分,但一些实现提供了启用它的扩展。

要检查您的实施支持的扩展,请尝试以下操作:

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

如果没有列出任何 cl_*_printf 扩展名,那么您可能不走运。如果列出了一个,您需要按照您链接的其他答案中的说明启用它。您可能还想检查您所支持的特定扩展的规范,以防它出现任何特定的怪癖。

【讨论】:

  • 这当然更准确。你建议我删除我的吗?
  • @APJo 老实说,我认为您的回答并没有增加任何特别有用的东西,但这当然取决于您。
  • 感谢诚实,我会删除我的,我不打算给出不好的答案:)
  • @APJo 听起来很明智。我试图对人们在此站点上的贡献持积极态度,但回答有关您从未使用过的技术的问题通常无济于事,至少在没有深入研究的情况下不会。公平地说,提问者可能用c 标记错误地标记了问题,这可能导致您认为这是关于常规C 代码的。 (FWIW,我偶尔会尝试回答我不立即知道确切答案的问题 - 这可能是一种很好的学习方式 - 所以不要气馁。有时它会奏效,我可以帮助和学习,有时我发现自己超出了我的深度。)
  • 感谢您的帮助!受支持的 OpenCL 扩展是设备特定的,还是仅取决于驱动程序?
猜你喜欢
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多