OpenCl non può compilare il kernel con 'printf'
Ricevo l'errore error: implicit declaration of function 'printf' is invalid in OpenCLquando provo a creare un kernel OpenCL. Il codice del kernel è questo
__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);
Questo mi dà l'errore di seguito
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
Ricevo un codice di ritorno negativo da questa funzione err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
Ho già provato le soluzioni da queste domande L' utilizzo di printf () nel kernel OpenCL e la funzione printf non funziona nel kernel OpenCL e nessuna di queste soluzioni lo risolve. Quando provo queste soluzioni, vedo un avviso comeinput.cl:1:26: warning: unknown OpenCL extension 'cl_amd_printf' - ignoring
Conclusione
Sembra che il mio sistema non supporti le estensioni printf. Il codice seguente (rubando dalla risposta di pmdj) mi dà il seguente output. Sembra una classica storia di non dipendere da estensioni specifiche del fornitore per uno 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'
Risposte
Come hai scoperto, printfnon fa parte dell'OpenCL standard, ma alcune implementazioni offrono estensioni che lo abilitano.
Per verificare le estensioni supportate dalla tua implementazione, prova qualcosa di simile:
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);
Se non ci sono cl_*_printfestensioni elencate, probabilmente sei sfortunato. Se uno è elencato, dovrai abilitarlo come descritto nelle altre risposte che hai collegato. Potresti anche voler controllare le specifiche per l'estensione specifica supportata dal tuo nel caso in cui mostri particolari stranezze.