OpenCl 无法使用 'printf' 编译内核
OpenCl cannot compile kernel with 'printf'
我在尝试构建 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
我从这个函数中得到一个否定的 return 代码 err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
我已经尝试了这些问题的解决方案Using printf() in OpenCL kernel and printf 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'
如您所见,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
扩展程序,您可能运气不好。如果列出了一个,您需要按照您链接的其他答案中的描述启用它。您可能还想检查您所支持的特定扩展的规范,以防它表现出任何特殊的怪癖。
我在尝试构建 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
我从这个函数中得到一个否定的 return 代码 err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
我已经尝试了这些问题的解决方案Using printf() in OpenCL kernel and printf 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'
如您所见,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
扩展程序,您可能运气不好。如果列出了一个,您需要按照您链接的其他答案中的描述启用它。您可能还想检查您所支持的特定扩展的规范,以防它表现出任何特殊的怪癖。