115 size_t *param_value_size)
117 *param_value_size = SIZE_MAX;
121 if(err != CL_SUCCESS)
124 "[dt_opencl_get_device_info] could not query the actual size in bytes of info %d: %i\n", param_name, err);
129 if(*param_value_size == SIZE_MAX || *param_value_size == 0)
133 "[dt_opencl_get_device_info] ERROR: no size returned, or zero size returned for data %d: %" G_GSIZE_FORMAT
"\n",
134 param_name, *param_value_size);
135 err = CL_INVALID_VALUE;
141 void *ptr = realloc(*param_value, *param_value_size);
145 "[dt_opencl_get_device_info] memory allocation failed! tried to allocate %" G_GSIZE_FORMAT
" bytes for data %d: %i",
146 *param_value_size, param_name, err);
147 err = CL_OUT_OF_HOST_MEMORY;
157 if(err != CL_SUCCESS)
167 *param_value_size = 0;
193 return (
flags & CL_MEM_USE_HOST_PTR) || (
flags & CL_MEM_ALLOC_HOST_PTR);
198 if(devid < 0)
return;
200 gchar buf[256] = { 0 };
201 gchar key_device[256] = { 0 };
204 g_snprintf(buf,
sizeof(buf),
"%s/avoid_atomics", key_device);
207 g_snprintf(buf,
sizeof(buf),
"%s/micro_nap", key_device);
210 g_snprintf(buf,
sizeof(buf),
"%s/pinned_memory", key_device);
213 g_snprintf(buf,
sizeof(buf),
"%s/wd", key_device);
216 g_snprintf(buf,
sizeof(buf),
"%s/ht", key_device);
219 g_snprintf(buf,
sizeof(buf),
"%s/event_handles", key_device);
222 g_snprintf(buf,
sizeof(buf),
"%s/disabled", key_device);
225 g_snprintf(buf,
sizeof(buf),
"%s/id%i/forced_headroom", key_device, devid);
232 gchar *
key = g_strconcat(key_device,
"/", conf_name, NULL);
248 if(devid < 0)
return FALSE;
250 gchar key_device[256] = { 0 };
252 gboolean safety_ok =
TRUE;
263 safety_ok |= (wd > 1) && (wd < 513) && (ht > 1) && (ht < 513);
331 gchar
key[256] = { 0 };
344 gchar
key[256] = { 0 };
352 gboolean opencl_enabled = enabled;
357 for(
int dev = 0; dev < cl->num_detected_devs; dev++)
361 opencl_enabled =
TRUE;
376 gchar
key[256] = { 0 };
389 gchar
key[256] = { 0 };
410 gchar
key[256] = { 0 };
422 gchar
key[256] = { 0 };
425 const int clamped_headroom = (int)
MIN(headroom, (
size_t)G_MAXINT);
447 gboolean lock_initialized =
FALSE;
487 cl_device_id devid = cl->
dev[dev].
devid = devices[
k];
489 char *infostr = NULL;
498 char *driverversion = NULL;
499 size_t driverversion_size;
501 char *deviceversion = NULL;
502 size_t deviceversion_size;
505 size_t *infointtab = NULL;
507 cl_bool image_support = 0;
508 cl_bool device_available = 0;
509 cl_uint vendor_id = 0;
510 cl_bool little_endian = 0;
511 cl_platform_id platform_id = 0;
513 char *dtcache = calloc(
PATH_MAX,
sizeof(
char));
514 char *cachedir = calloc(
PATH_MAX,
sizeof(
char));
521 char *filename = calloc(
PATH_MAX,
sizeof(
char));
522 char *confentry = calloc(
PATH_MAX,
sizeof(
char));
523 char *binname = calloc(
PATH_MAX,
sizeof(
char));
531 cl_bool host_unified_memory = CL_FALSE;
533 &host_unified_memory, NULL);
537 if(err != CL_SUCCESS)
547 if(err != CL_SUCCESS)
555 cname_size = infostr_size;
556 cname = malloc(cname_size);
558 cl->
dev[dev].
name = strdup(infostr);
562 cl->
crc = crc32(cl->
crc, (
const unsigned char *)infostr, strlen(infostr));
565 if(err != CL_SUCCESS)
574 if(err != CL_SUCCESS)
581 if(err != CL_SUCCESS)
594 if(err != CL_SUCCESS)
603 if(err != CL_SUCCESS)
612 cl->
crc = crc32(cl->
crc, (
const unsigned char *)deviceversion, deviceversion_size);
627 if(!strncasecmp(vendor,
"NVIDIA", 6))
634 const gboolean is_cpu_device = (
type & CL_DEVICE_TYPE_CPU) == CL_DEVICE_TYPE_CPU;
644 ((
type & CL_DEVICE_TYPE_CPU) == CL_DEVICE_TYPE_CPU) ?
"CPU" :
"",
645 ((
type & CL_DEVICE_TYPE_GPU) == CL_DEVICE_TYPE_GPU) ?
"GPU" :
"",
646 (
type & CL_DEVICE_TYPE_ACCELERATOR) ?
", Accelerator" :
"" );
648 if(is_cpu_device && newdevice)
656 if(!device_available)
695 if(newdevice && is_blacklisted)
698 const gboolean old_blacklist =
dt_conf_get_bool(
"opencl_disable_drivers_blacklist");
714 size_t infointtab_size;
716 if(err == CL_SUCCESS)
741 if(
type & CL_DEVICE_TYPE_GPU)
770 lock_initialized =
TRUE;
773 if(err != CL_SUCCESS)
782 if(err != CL_SUCCESS)
792 double tstart, tend, tdiff;
795 int len =
MIN(strlen(infostr),1024 *
sizeof(
char));;
798 for(
int i = 0;
i < len;
i++)
799 if(isalnum(infostr[
i])) devname[j++] = infostr[
i];
801 len =
MIN(strlen(driverversion), 1024 *
sizeof(
char));
804 for(
int i = 0;
i < len;
i++)
805 if(isalnum(driverversion[
i])) drvversion[j++] = driverversion[
i];
807 snprintf(cachedir,
PATH_MAX *
sizeof(
char),
"%s" G_DIR_SEPARATOR_S
"cached_kernels_for_%s_%s", dtcache, devname, drvversion);
811 if(g_mkdir_with_parents(cachedir, 0700) == -1)
820 char *escapedkerneldir = NULL;
822 escapedkerneldir = g_strdup_printf(
"\"%s\"", kerneldir);
828 const char* compile_opt = NULL;
849 gchar *my_option = g_strdup(compile_opt);
852 cl->
dev[dev].
options = g_strdup_printf(
"-w %s %s -D%s=1 -I%s",
857 const char *kerneldir_token =
"<ansel-kernels>";
858 char *escapedkerneldir_md5 = NULL;
860 escapedkerneldir_md5 = g_strdup_printf(
"\"%s\"", kerneldir_token);
862 escapedkerneldir_md5 = g_strdup(kerneldir_token);
864 cl->
dev[dev].
options_md5 = g_strdup_printf(
"-w %s %s -D%s=1 -I%s",
871 dt_free(compile_option_name_cname);
875 escapedkerneldir = NULL;
877 const char *clincludes[
DT_OPENCL_MAX_INCLUDES] = {
"rgb_norms.h",
"noise_generator.h",
"color_conversion.h",
"colorspaces.cl",
"colorspace.h",
"common.h", NULL };
890 FILE *
f = g_fopen(filename,
"rb");
896 gchar *confline_pattern = g_strdup_printf(
"%%%" G_GSIZE_FORMAT
"[^\n]\n",
PATH_MAX *
sizeof(
char) - 1);
897 int rd = fscanf(
f, confline_pattern, confentry);
899 if(rd != 1)
continue;
901 size_t end = strlen(confentry);
902 for(
size_t pos = 0; pos < end; pos++)
903 if(confentry[pos] ==
'#')
905 confentry[pos] =
'\0';
906 for(
int l = pos - 1; l >= 0; l--)
908 if(confentry[l] ==
' ')
915 if(confentry[0] ==
'\0')
continue;
917 const char *programname = NULL, *programnumber = NULL;
918 gchar **tokens = g_strsplit_set(confentry,
" \t", 2);
921 programname = tokens[0];
923 programnumber = tokens[1];
926 prog = programnumber ? strtol(programnumber, NULL, 10) : -1;
928 if(
IS_NULL_PTR(programname) || programname[0] ==
'\0' || prog < 0)
930 dt_print(
DT_DEBUG_OPENCL,
"[dt_opencl_device_init] malformed entry in programs.conf `%s'; ignoring it!\n", confentry);
934 gchar *program_bin = g_strdup_printf(
"%s.bin", programname);
961 tdiff = tend - tstart;
1025 cl->
mem_sizes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
1036 char *locale = strdup(setlocale(LC_ALL, NULL));
1037 setlocale(LC_ALL,
"C");
1048 if(exclude_opencl)
return;
1050 cl_platform_id *all_platforms = NULL;
1051 cl_uint *all_num_devices = NULL;
1068 "[opencl_init] no working opencl library found. Continue with opencl disabled\n");
1082 if(err != CL_SUCCESS)
1088 if(num_platforms == 0)
1094 num_platforms > 1 ?
"s" :
"");
1096 for(
int n = 0;
n < num_platforms;
n++)
1098 cl_platform_id platform = all_platforms[
n];
1102 if(err != CL_SUCCESS)
1106 if((errn == CL_SUCCESS) && (errv == CL_SUCCESS))
1111 all_num_devices[
n] = 0;
1115 char profile[64] = { 0 };
1116 size_t profile_size;
1118 if(err != CL_SUCCESS)
1120 all_num_devices[
n] = 0;
1126 if(strcmp(
"FULL_PROFILE", profile) != 0)
1128 all_num_devices[
n] = 0;
1135 cl_uint num_devices = 0;
1136 for(
int n = 0;
n < num_platforms;
n++) num_devices += all_num_devices[
n];
1139 cl_device_id *devices = 0;
1143 devices = (cl_device_id *)malloc(
sizeof(cl_device_id) * num_devices);
1153 cl_device_id *devs = devices;
1154 for(
int n = 0;
n < num_platforms;
n++)
1156 if(all_num_devices[
n])
1158 cl_platform_id platform = all_platforms[
n];
1161 if(err != CL_SUCCESS)
1163 num_devices -= all_num_devices[
n];
1166 devs += all_num_devices[
n];
1172 if(num_devices == 0)
1182 for(
int k = 0;
k < num_devices;
k++)
1219 cl->
inited ?
"" :
"NOT ");
1224 snprintf(checksum,
sizeof(checksum),
"%u", cl->
crc);
1254 setlocale(LC_ALL, locale);
1275 dt_print_nts(
DT_DEBUG_OPENCL,
" [opencl_summary_statistics] device '%s' (%d): peak memory usage %" G_GSIZE_FORMAT
" bytes (%.1f MB)\n",
1284 "successful and %d events lost. max event=%d%s\n",
1386 return (err == CL_SUCCESS && success == CL_COMPLETE);
1392 if(!cl->
inited || devid < 0)
return -1;
1400 while(*list != -1 && *list !=
value) list++;
1405 *list = *(list + 1);
1417 char tmp[2048] = { 0 };
1422 for(
int i = 0;
i < devs;
i++)
1439 maxlen = strlen(in) + 1;
1440 out = malloc(maxlen);
1446 while(*in !=
'\0' && len < maxlen - 1)
1448 int n = strcspn(in,
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
1450 if(
n != 0)
continue;
1451 out[len] = tolower(*in);
1465 int *full = malloc(
sizeof(
int) * (devs + 1));
1471 priority_list[0] = -1;
1478 if(configstr[0] ==
'+')
1485 for(
int i = 0;
i < devs;
i++) full[
i] =
i;
1488 gchar **tokens = g_strsplit(configstr,
",", 0);
1489 gchar **tokens_ptr = tokens;
1493 gchar *str = *tokens_ptr;
1504 while(*str ==
'!') str++;
1511 for(
int i = 0;
i < devs && full[
i] != -1;
i++)
1513 priority_list[count] = full[
i];
1518 else if(*str !=
'\0')
1520 char *endptr = NULL;
1526 if(number < 0) number = strtol(str, &endptr, 10);
1529 if(number < 0 || (number == 0 && endptr == str)) number = -1;
1534 if(!not&&dev_number != -1)
1536 priority_list[count] = dev_number;
1547 while(count < devs + 1) priority_list[count++] = -1;
1550 *mandatory = (priority_list[0] != -1) ? mnd : 0;
1594 if(!cl->
inited)
return -1;
1599 size_t prio_size =
sizeof(int) * (cl->
num_devs + 1);
1600 int *priority = (
int *)malloc(prio_size);
1630 const int usec = 5000;
1634 for(
int n = 0;
n < nloop;
n++)
1636 const int *prio = priority;
1657 dt_print(
DT_DEBUG_OPENCL,
"[opencl_lock_device] reached opencl_mandatory_timeout trying to lock mandatory device, fallback to CPU\n");
1662 for(
int try_dev = 0; try_dev < cl->
num_devs; try_dev++)
1680 if(dev < 0 || dev >= cl->
num_devs)
return;
1686 FILE *
f = g_fopen(filename,
"rb");
1693 if(fstat(fd, st) < 0)
1718 struct stat filestat;
1728 size_t filesize = filestat.st_size;
1729 char *file = (
char *)malloc(filesize);
1739 size_t rd = fread(file,
sizeof(
char), filesize,
f);
1750 *md5sums = g_compute_checksum_for_data(G_CHECKSUM_MD5, (guchar *)file, filesize);
1757 const char *cachedir,
char *md5sum,
char **includemd5,
int *loaded_cached)
1762 struct stat filestat, cachedstat;
1775 "[opencl_load_source] program number `%d' already in use when loading file `%s'!\n", prog,
1783 size_t filesize = filestat.st_size;
1784 char *file = (
char *)malloc(filesize + 2048);
1785 size_t rd = fread(file,
sizeof(
char), filesize,
f);
1794 char *start = file + filesize;
1795 char *end = start + 2048;
1798 cl_device_id devid = cl->
dev[dev].
devid;
1802 cl_platform_id platform;
1809 len = g_strlcpy(start, options_md5, end - start);
1815 if(!includemd5[
n])
continue;
1816 len = g_strlcpy(start, includemd5[
n], end - start);
1820 char *source_md5 = g_compute_checksum_for_data(G_CHECKSUM_MD5, (guchar *)file, start - file);
1821 g_strlcpy(md5sum, source_md5, 33);
1824 file[filesize] =
'\0';
1827 ssize_t linkedfile_len = 0;
1833 snprintf(dup,
sizeof(dup),
"%s.%s", binname, md5sum);
1835 g_strlcpy(linkedfile, md5sum,
sizeof(linkedfile));
1836 linkedfile_len = strlen(md5sum);
1838 FILE *cached =
fopen_stat(binname, &cachedstat);
1844 linkedfile_len = readlink(binname, linkedfile,
sizeof(linkedfile) - 1);
1846 if(linkedfile_len > 0)
1848 linkedfile[linkedfile_len] =
'\0';
1850 if(strncmp(linkedfile, md5sum, 33) == 0)
1853 size_t cached_filesize = cachedstat.st_size;
1855 unsigned char *cached_content = (
unsigned char *)malloc(cached_filesize + 1);
1856 rd = fread(cached_content,
sizeof(
char), cached_filesize, cached);
1857 if(rd != cached_filesize)
1859 dt_print(
DT_DEBUG_OPENCL,
"[opencl_load_program] could not read all of file '%s' MD5: %s!\n", binname, md5sum);
1865 (
const unsigned char **)&cached_content, NULL, &err);
1866 if(err != CL_SUCCESS)
1869 "[opencl_load_program] could not load cached binary program from file '%s' MD5: '%s'! (%i)\n",
1870 binname, md5sum, err);
1885 if(*loaded_cached == 0)
1890 if(linkedfile_len > 0)
1894 g_unlink(link_dest);
1903 "[opencl_load_program] could not load cached binary program, trying to compile source\n");
1906 cl->
dev[dev].
context, 1, (
const char **)&file, &filesize, &err);
1908 if((err != CL_SUCCESS) || (cl->
dev[dev].
program[prog] == NULL))
1922 dt_vprint(
DT_DEBUG_OPENCL,
"[opencl_load_program] loaded cached binary program from file '%s' MD5: '%s' \n", binname, md5sum);
1925 dt_vprint(
DT_DEBUG_OPENCL,
"[opencl_load_program] successfully loaded program from '%s' MD5: '%s'\n", filename, md5sum);
1931 char *md5sum,
int loaded_cached)
1935 cl_program program = cl->
dev[dev].
program[prog];
1938 if(err != CL_SUCCESS)
1943 cl_build_status build_status;
1945 sizeof(cl_build_status), &build_status, NULL);
1949 size_t ret_val_size;
1952 if(ret_val_size != SIZE_MAX)
1954 build_log = (
char *)malloc(
sizeof(
char) * (ret_val_size + 1));
1958 ret_val_size, build_log, NULL);
1960 build_log[ret_val_size] =
'\0';
1969 if(err != CL_SUCCESS)
1980 if(err != CL_SUCCESS)
1986 cl_device_id *devices = malloc(
sizeof(cl_device_id) * numdev);
1988 sizeof(cl_device_id) * numdev, devices, NULL);
1989 if(err != CL_SUCCESS)
1996 size_t *binary_sizes = malloc(
sizeof(
size_t) * numdev);
1998 sizeof(
size_t) * numdev, binary_sizes, NULL);
1999 if(err != CL_SUCCESS)
2007 unsigned char **binaries = malloc(
sizeof(
unsigned char *) * numdev);
2008 for(
int i = 0;
i < numdev;
i++) binaries[
i] = (
unsigned char *)malloc(binary_sizes[
i]);
2010 sizeof(
unsigned char *) * numdev, binaries, NULL);
2011 if(err != CL_SUCCESS)
2017 for(
int i = 0;
i < numdev;
i++)
2022 snprintf(link_dest,
sizeof(link_dest),
"%s" G_DIR_SEPARATOR_S
"%s", cachedir, md5sum);
2023 FILE *
f = g_fopen(link_dest,
"wb");
2025 size_t bytes_written = fwrite(binaries[
i],
sizeof(
char), binary_sizes[
i],
f);
2026 if(bytes_written != binary_sizes[
i])
goto ret;
2031 if(!getcwd(cwd,
sizeof(cwd)))
goto ret;
2032 if(chdir(cachedir) != 0)
goto ret;
2034 g_strlcpy(dup, binname,
sizeof(dup));
2035 char *bname = basename(dup);
2039 char finalfilename[
PATH_MAX] = { 0 };
2040 snprintf(finalfilename,
sizeof(finalfilename),
"%s" G_DIR_SEPARATOR_S
"%s.%s", cachedir, bname, md5sum);
2041 rename(link_dest, finalfilename);
2043 if(symlink(md5sum, bname) != 0)
goto ret;
2045 if(chdir(cwd) != 0)
goto ret;
2049 for(
int i = 0;
i < numdev;
i++)
dt_free(binaries[
i]);
2061 if(!cl->
inited)
return -1;
2065 for(
int dev = 0; dev < cl->
num_devs; dev++)
2074 if(err != CL_SUCCESS)
2107 for(
int dev = 0; dev < cl->
num_devs; dev++)
2118 if(!cl->
inited || dev < 0)
return -1;
2120 sizeof(size_t) * 3, sizes, NULL);
2124 unsigned long *localmemsize)
2127 if(!cl->
inited || dev < 0)
return -1;
2130 sizeof(cl_ulong), &lmemsize, NULL);
2131 if(err != CL_SUCCESS)
return err;
2133 *localmemsize = lmemsize;
2136 sizeof(
size_t), workgroupsize, NULL);
2137 if(err != CL_SUCCESS)
return err;
2146 if(!cl->
inited || dev < 0)
return -1;
2150 CL_KERNEL_WORK_GROUP_SIZE,
sizeof(size_t),
2151 kernelworkgroupsize, NULL);
2159 if(!cl->
inited || dev < 0)
return -1;
2171 const size_t *local)
2174 if(!cl->
inited || dev < 0)
return -1;
2183 2, NULL, sizes, local, 0, NULL, eventp);
2185 if(err != CL_SUCCESS)
2204 const int height,
const int rowpitch)
2207 const size_t origin[] = { 0, 0, 0 };
2225 const size_t origin[] = { 0, 0, 0 };
2233 const size_t *region,
const int rowpitch,
const int blocking)
2240 device, blocking ? CL_TRUE : CL_FALSE, origin, region, rowpitch,
2241 0, host, 0, NULL, eventp);
2251 const int height,
const int rowpitch)
2254 const size_t origin[] = { 0, 0, 0 };
2271 const size_t origin[] = { 0, 0, 0 };
2278 const size_t *region,
const int rowpitch,
const int blocking)
2285 device, blocking ? CL_TRUE : CL_FALSE, origin, region,
2286 rowpitch, 0, host, 0, NULL, eventp);
2296 if(err != CL_SUCCESS)
dt_print(
DT_DEBUG_OPENCL,
"[opencl copy_image] could not copy image on device %d: %i\n", devid, err);
2301 size_t *origin,
size_t *region,
size_t offset)
2307 if(err != CL_SUCCESS)
2308 dt_print(
DT_DEBUG_OPENCL,
"[opencl copy_image_to_buffer] could not copy image on device %d: %i\n", devid, err);
2313 size_t offset,
size_t *origin,
size_t *region)
2319 if(err != CL_SUCCESS)
2320 dt_print(
DT_DEBUG_OPENCL,
"[opencl copy_buffer_to_image] could not copy buffer on device %d: %i\n", devid, err);
2325 size_t srcoffset,
size_t dstoffset,
size_t size)
2330 src_buffer, dst_buffer, srcoffset,
2331 dstoffset,
size, 0, NULL, eventp);
2332 if(err != CL_SUCCESS)
2333 dt_print(
DT_DEBUG_OPENCL,
"[opencl copy_buffer_to_buffer] could not copy buffer on device %d: %i\n", devid, err);
2338 const size_t size,
const int blocking)
2349 const size_t size,
const int blocking)
2366 if(err != CL_SUCCESS)
2368 "[opencl copy_host_to_device_constant] could not alloc buffer on device %d: %i\n", devid, err);
2382 const int bpp,
const int rowpitch)
2386 cl_image_format fmt;
2388 if(
bpp == 4 *
sizeof(
float))
2389 fmt = (cl_image_format){ CL_RGBA, CL_FLOAT };
2390 else if(
bpp ==
sizeof(
float))
2391 fmt = (cl_image_format){ CL_R, CL_FLOAT };
2392 else if(
bpp ==
sizeof(uint16_t))
2393 fmt = (cl_image_format){ CL_R, CL_UNSIGNED_INT16 };
2400 rowpitch, host, &err);
2401 if(err != CL_SUCCESS)
2403 "[opencl copy_host_to_device] could not alloc/copy img buffer on device %d: %i\n", devid, err);
2405 if(err == CL_SUCCESS)
2407 const size_t bytes = (size_t)(rowpitch ? rowpitch :
width *
bpp) *
height;
2437 if(err != CL_SUCCESS)
dt_print(
DT_DEBUG_OPENCL,
"[opencl map buffer] could not map buffer on device %d: %i\n", devid, err);
2448 size_t origin[3] = {0, 0, 0};
2450 size_t mapped_row_pitch;
2454 &mapped_row_pitch, NULL, 0, NULL, eventp, &err);
2456 if(err != CL_SUCCESS)
2468 if(err != CL_SUCCESS)
2469 dt_print(
DT_DEBUG_OPENCL,
"[opencl unmap mem object] could not unmap mem object on device %d: %i\n", devid, err);
2474 const size_t bytes,
const cl_mem_flags
flags,
2475 const cl_image_format fmt,
void *host,
2476 const char *
const context)
2481 for(
int attempt = 0; attempt < 2; attempt++)
2485 if(err == CL_SUCCESS)
break;
2486 if(attempt == 0 && (err == CL_MEM_OBJECT_ALLOCATION_FAILURE || err == CL_OUT_OF_RESOURCES))
2489 "[opencl %s] out of memory on device %d, flushing cached pinned buffers and retrying\n",
2497 if(err != CL_SUCCESS)
2508 cl_image_format fmt;
2510 if(rgba8 && effective_bpp == 4 *
sizeof(uint8_t))
2511 fmt = (cl_image_format){ CL_RGBA, CL_UNSIGNED_INT8 };
2512 else if(effective_bpp == 4 *
sizeof(
float))
2513 fmt = (cl_image_format){ CL_RGBA, CL_FLOAT };
2514 else if(effective_bpp ==
sizeof(
float))
2515 fmt = (cl_image_format){ CL_R, CL_FLOAT };
2516 else if(effective_bpp ==
sizeof(uint16_t))
2517 fmt = (cl_image_format){ CL_R, CL_UNSIGNED_INT16 };
2518 else if(effective_bpp ==
sizeof(uint8_t))
2519 fmt = (cl_image_format){ CL_R, CL_UNSIGNED_INT8 };
2523 const size_t bytes = (size_t)
width *
height * effective_bpp;
2528 const int bpp,
void *host,
const int flags)
2532 cl_image_format fmt;
2534 if(rgba8 && effective_bpp == 4 *
sizeof(uint8_t))
2535 fmt = (cl_image_format){ CL_RGBA, CL_UNSIGNED_INT8 };
2536 else if(effective_bpp == 4 *
sizeof(
float))
2537 fmt = (cl_image_format){ CL_RGBA, CL_FLOAT };
2538 else if(effective_bpp ==
sizeof(
float))
2539 fmt = (cl_image_format){ CL_R, CL_FLOAT };
2540 else if(effective_bpp ==
sizeof(uint16_t))
2541 fmt = (cl_image_format){ CL_R, CL_UNSIGNED_INT16 };
2545 const size_t bytes = (size_t)
width *
height * effective_bpp;
2547 "alloc_device_use_host_pointer");
2555 for(
int attempt = 0; attempt < 2; attempt++)
2559 if(err == CL_SUCCESS)
break;
2560 if(attempt == 0 && (err == CL_MEM_OBJECT_ALLOCATION_FAILURE || err == CL_OUT_OF_RESOURCES))
2563 "[opencl alloc_device_buffer] out of memory on device %d, flushing cached pinned buffers and retrying\n",
2570 if(err != CL_SUCCESS)
2593 return (err == CL_SUCCESS) ?
size : 0;
2602 if(err != CL_SUCCESS)
2617 cl_mem_flags
flags = 0;
2619 if(err != CL_SUCCESS)
return 0;
2631 return (err == CL_SUCCESS) ? (int)
size : 0;
2642 return (err == CL_SUCCESS) ? (int)
size : 0;
2654 return (err == CL_SUCCESS) ? (int)
size : 0;
2671 if(devid < 0)
return;
2726 if(!cl->
inited || devid < 0)
return;
2735 "[dt_opencl_check_tuning] use %" G_GSIZE_FORMAT
" MiB on device `%s' id=%i\n",
2745 return (limit > in_use) ? (limit - in_use) : 0;
2761 const size_t overhead,
size_t *needed,
size_t *limit)
2763 size_t n = 0, l = 0;
2767 if(!cl->
inited || devid < 0)
2774 const size_t total = (size_t)ceilf((
float)required *
factor) + overhead;
2786 "[opencl] trying to allocate %" PRIu64
" MiB of memory while the vRAM has %" PRIu64
2796 "[opencl] trying to allocate %" PRIu64
" MiB of memory while the vRAM has %" PRIu64
2803 if(needed) *needed =
n;
2804 if(limit) *limit = l;
2809 const float factor,
const size_t overhead)
2819 return (
size % roundup == 0 ?
size : (
size / roundup + 1) * roundup);
2824 return (
size % roundup == 0 ?
size : (
size / roundup + 1) * roundup);
2894 if(!cl->
inited || devid < 0)
return NULL;
2897 static const cl_event zeroevent[1];
2911 *eventlist = calloc(newevents,
sizeof(cl_event));
2913 if(!*eventlist || !*eventtags)
2922 *maxevents = newevents;
2926 if(*numevents > 0 && !memcmp((*eventlist) + *numevents - 1, zeroevent,
sizeof(cl_event)))
2936 (*eventtags)[*numevents - 1].tag[0] =
'\0';
2940 return (*eventlist) + *numevents - 1;
2944 if((*numevents - *eventsconsolidated + 1 > cl->
dev[devid].
event_handles) || (*numevents == *maxevents))
2948 if(*numevents == *maxevents)
2951 cl_event *neweventlist = calloc(newevents,
sizeof(cl_event));
2961 memcpy(neweventlist, *eventlist,
sizeof(cl_event) * *maxevents);
2965 *eventlist = neweventlist;
2966 *eventtags = neweventtags;
2967 *maxevents = newevents;
2972 memcpy((*eventlist) + *numevents - 1, zeroevent,
sizeof(cl_event));
2979 (*eventtags)[*numevents - 1].tag[0] =
'\0';
2983 *maxeventslot =
MAX(*maxeventslot, *numevents - 1);
2984 return (*eventlist) + *numevents - 1;
2992 if(!cl->
inited || devid < 0)
return;
3003 if(
IS_NULL_PTR(*eventlist) || *numevents == 0)
return;
3005 static const cl_event zeroevent[1];
3010 for(
int k = *eventsconsolidated;
k < *numevents;
k++)
3012 if(memcmp((*eventlist) +
k, zeroevent,
sizeof(cl_event)))
3018 *eventsconsolidated = 0;
3020 *summary = CL_COMPLETE;
3030 if(!cl->
inited || devid < 0)
return;
3033 static const cl_event zeroevent[1];
3040 if(
IS_NULL_PTR(*eventlist) || *numevents == 0)
return;
3043 if(!memcmp((*eventlist) + *numevents - 1, zeroevent,
sizeof(cl_event)))
3050 if(*numevents == *eventsconsolidated)
return;
3052 assert(*numevents > *eventsconsolidated);
3065 for(
int k = *eventsconsolidated;
k < *numevents;
k++)
3067 if(!memcmp((*eventlist) +
k, zeroevent,
sizeof(cl_event)))
3071 if((err != CL_SUCCESS) && (err != CL_INVALID_VALUE))
3099 static const cl_event zeroevent[1];
3101 if(
IS_NULL_PTR(*eventlist) || *numevents == 0)
return CL_COMPLETE;
3107 for(
int k = *eventsconsolidated;
k < *numevents;
k++)
3114 if(!memcmp((*eventlist) +
k, zeroevent,
sizeof(cl_event)))
3117 (*eventsconsolidated)++;
3122 char *tag = (*eventtags)[
k].tag;
3123 cl_int *retval = &((*eventtags)[
k].retval);
3127 sizeof(cl_int), retval, NULL);
3128 if(err != CL_SUCCESS)
3131 tag[0] ==
'\0' ?
"<?>" : tag, err);
3133 else if(*retval != CL_COMPLETE)
3136 tag[0] ==
'\0' ?
"<?>" : tag, *retval == CL_COMPLETE ?
"was successful" :
"failed", *retval);
3148 (*eventlist)[
k], CL_PROFILING_COMMAND_START,
sizeof(cl_ulong), &start, NULL);
3150 sizeof(cl_ulong), &end, NULL);
3151 if(errs == CL_SUCCESS && erre == CL_SUCCESS)
3153 (*eventtags)[
k].timelapsed = end - start;
3157 (*eventtags)[
k].timelapsed = 0;
3162 (*eventtags)[
k].timelapsed = 0;
3166 (*eventsconsolidated)++;
3169 cl_int result = *summary;
3181 return result == CL_COMPLETE ? 0 : result;
3190 if(!cl->
inited || devid < 0)
return;
3202 char **tags = malloc(
sizeof(
char *) * (*eventsconsolidated + 1));
3203 float *timings = malloc(
sizeof(
float) * (*eventsconsolidated + 1));
3209 for(
int k = 0;
k < *eventsconsolidated;
k++)
3229 timings[tagfound] += (*eventtags)[
k].timelapsed * 1e-9;
3235 tags[
items - 1] = (*eventtags)[
k].tag;
3236 timings[
items - 1] = (*eventtags)[
k].timelapsed * 1e-9;
3243 tags[
items - 1] = (*eventtags)[
k].tag;
3244 timings[
items - 1] = (*eventtags)[
k].timelapsed * 1e-9;
3250 "[opencl_profiling] profiling device %d ('%s'):\n", devid, cl->
dev[devid].
name);
3256 tags[
i][0] ==
'\0' ?
"<?>" : tags[
i]);
3257 total += timings[
i];
3260 if(timings[0] != 0.0f)
3263 total += timings[0];
3267 "[opencl_profiling] spent %7.4f seconds totally in command queue (with %d event%s missing)\n",
3268 (
double)total, *lostevents, *lostevents == 1 ?
"" :
"s");
3291 size_t maxsizes[3] = { 0 };
3292 size_t workgroupsize = 0;
3293 unsigned long localmemsize = 0;
3294 size_t kernelworkgroupsize = 0;
3296 int *blocksizex = &factors->
sizex;
3297 int *blocksizey = &factors->
sizey;
3301 *blocksizex = CLAMP(
nextpow2(*blocksizex), 1, 1 << 16);
3302 *blocksizey = CLAMP(
nextpow2(*blocksizey), 1, 1 << 16);
3307 while(maxsizes[0] < *blocksizex || maxsizes[1] < *blocksizey
3308 || localmemsize < ((factors->
xfactor * (*blocksizex) + factors->
xoffset) *
3310 || workgroupsize < (
size_t)(*blocksizex) * (*blocksizey) || kernelworkgroupsize < (
size_t)(*blocksizex) * (*blocksizey))
3312 if(*blocksizex == 1 && *blocksizey == 1)
return FALSE;
3314 if(*blocksizex > *blocksizey)
3322 dt_print(
DT_DEBUG_OPENCL,
"[dt_opencl_local_buffer_opt] can not identify resource limits for device %d\n", devid);
static void error(char *msg)
dt_bilateral_cl_global_t * dt_bilateral_init_cl_global()
void dt_bilateral_free_cl_global(dt_bilateral_cl_global_t *b)
dt_blendop_cl_global_t * dt_develop_blend_init_cl_global(void)
void dt_develop_blend_free_cl_global(dt_blendop_cl_global_t *b)
const dt_aligned_pixel_t f
const dt_colormatrix_t dt_aligned_pixel_t out
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_conf_set_bool(const char *name, int val)
int dt_conf_get_bool(const char *name)
int dt_conf_key_exists(const char *key)
gchar * dt_conf_get_string(const char *name)
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
int64_t dt_conf_get_int64(const char *name)
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
void dt_conf_save(dt_conf_t *cf)
gboolean dt_conf_key_not_empty(const char *name)
void reset(dt_view_t *self)
void dt_vprint(dt_debug_thread_t thread, const char *msg,...)
void dt_concat_path_file(char destination[PATH_MAX], const char path[PATH_MAX], const char *const file)
void dt_print_nts(dt_debug_thread_t thread, const char *msg,...)
void dt_capabilities_add(char *capability)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
static const dt_aligned_pixel_simd_t value
static double dt_get_wtime(void)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
dt_dlopencl_t * dt_dlopencl_init(const char *name)
static int dt_pthread_mutex_BAD_trylock(dt_pthread_mutex_t *mutex)
static int dt_pthread_mutex_BAD_unlock(dt_pthread_mutex_t *mutex)
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
dt_dwt_cl_global_t * dt_dwt_init_cl_global()
void dt_dwt_free_cl_global(dt_dwt_cl_global_t *g)
void dt_loc_get_user_cache_dir(char *cachedir, size_t bufsize)
void dt_loc_get_kerneldir(char *kerneldir, size_t bufsize)
const dt_collection_sort_t items[]
void dt_gaussian_free_cl_global(dt_gaussian_cl_global_t *g)
dt_gaussian_cl_global_t * dt_gaussian_init_cl_global()
dt_guided_filter_cl_global_t * dt_guided_filter_init_cl_global()
void dt_guided_filter_free_cl_global(dt_guided_filter_cl_global_t *g)
void dt_heal_free_cl_global(dt_heal_cl_global_t *g)
dt_heal_cl_global_t * dt_heal_init_cl_global()
void dt_iop_nap(int32_t usec)
void dt_interpolation_free_cl_global(dt_interpolation_cl_global_t *g)
dt_interpolation_cl_global_t * dt_interpolation_init_cl_global()
static float kernel(const float *x, const float *y)
void dt_colorspaces_free_cl_global(dt_colorspaces_cl_global_t *g)
dt_colorspaces_cl_global_t * dt_colorspaces_init_cl_global()
dt_local_laplacian_cl_global_t * dt_local_laplacian_init_cl_global()
void dt_local_laplacian_free_cl_global(dt_local_laplacian_cl_global_t *g)
float *const restrict const size_t k
dt_mipmap_buffer_dsc_flags flags
static int dt_nvidia_gpu_supports_sm_20(const char *model)
cl_ulong dt_opencl_get_device_available(const int devid)
int dt_opencl_get_kernel_work_group_size(const int dev, const int kernel, size_t *kernelworkgroupsize)
cl_event * dt_opencl_events_get_slot(const int devid, const char *tag)
static void * _dt_opencl_alloc_image2d(const int devid, const int width, const int height, const size_t bytes, const cl_mem_flags flags, const cl_image_format fmt, void *host, const char *const context)
int dt_opencl_local_buffer_opt(const int devid, const int kernel, dt_opencl_local_buffer_t *factors)
void dt_opencl_unlock_device(const int dev)
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
static void dt_opencl_update_priorities()
void * dt_opencl_alloc_device_buffer(const int devid, const size_t size)
dt_opencl_fit_reason_t dt_opencl_image_fits_device_reason(const int devid, const size_t width, const size_t height, const unsigned bpp, const float factor, const size_t overhead, size_t *needed, size_t *limit)
int dt_opencl_read_host_from_device_rowpitch(const int devid, void *host, void *device, const int width, const int height, const int rowpitch)
void * dt_opencl_alloc_device_use_host_pointer(const int devid, const int width, const int height, const int bpp, void *host, const int flags)
size_t dt_opencl_get_mem_object_size(cl_mem mem)
gboolean dt_opencl_is_pinned_memory(cl_mem mem)
static char * _ascii_str_canonical(const char *in, char *out, int maxlen)
void dt_opencl_cleanup_device(dt_opencl_t *cl, int i)
int dt_opencl_enqueue_copy_buffer_to_image(const int devid, cl_mem src_buffer, cl_mem dst_image, size_t offset, size_t *origin, size_t *region)
void dt_opencl_init(dt_opencl_t *cl, const gboolean exclude_opencl, const gboolean print_statistics)
void dt_opencl_events_reset(const int devid)
cl_int dt_opencl_events_flush(const int devid, const int reset)
int dt_opencl_copy_device_to_host(const int devid, void *host, void *device, const int width, const int height, const int bpp)
int dt_opencl_lock_device(const int pipetype)
gboolean dt_opencl_read_device_config(const int devid)
void dt_opencl_check_tuning(const int devid)
void * dt_opencl_alloc_device(const int devid, const int width, const int height, const int bpp)
int dt_opencl_is_inited(void)
int dt_opencl_create_kernel(const int prog, const char *name)
void * dt_opencl_copy_host_to_device_constant(const int devid, const size_t size, void *host)
int dt_opencl_dev_roundup_height(int size, const int devid)
void * dt_opencl_copy_host_to_device_rowpitch(const int devid, void *host, const int width, const int height, const int bpp, const int rowpitch)
int dt_opencl_write_host_to_device_rowpitch(const int devid, void *host, void *device, const int width, const int height, const int rowpitch)
int dt_opencl_dev_roundup_width(int size, const int devid)
void dt_opencl_write_device_config(const int devid)
static void dt_opencl_set_synchronization_timeout(int value)
static int dt_opencl_device_init(dt_opencl_t *cl, const int dev, cl_device_id *devices, const int k)
int dt_opencl_get_mem_context_id(cl_mem mem)
int dt_opencl_write_host_to_device_non_blocking(const int devid, void *host, void *device, const int width, const int height, const int bpp)
int dt_opencl_load_program(const int dev, const int prog, const char *filename, const char *binname, const char *cachedir, char *md5sum, char **includemd5, int *loaded_cached)
void * dt_opencl_map_buffer(const int devid, cl_mem buffer, const int blocking, const int flags, size_t offset, size_t size)
static void dt_opencl_apply_scheduling_profile()
static int _dt_opencl_get_conf_int(const gchar *key_device, const gchar *conf_name, gboolean *safety_ok)
int dt_opencl_get_image_height(cl_mem mem)
int dt_opencl_read_host_from_device_rowpitch_non_blocking(const int devid, void *host, void *device, const int width, const int height, const int rowpitch)
int dt_opencl_write_buffer_to_device(const int devid, void *host, void *device, const size_t offset, const size_t size, const int blocking)
int dt_opencl_micro_nap(const int devid)
static cl_ulong _opencl_get_device_memalloc(const int devid)
int dt_opencl_enqueue_copy_image(const int devid, cl_mem src, cl_mem dst, size_t *orig_src, size_t *orig_dst, size_t *region)
static int _take_from_list(int *list, int value)
int dt_opencl_set_detected_device_enabled(const int detected, const gboolean enabled)
int dt_opencl_read_buffer_from_device(const int devid, void *host, void *device, const size_t offset, const size_t size, const int blocking)
int dt_opencl_build_program(const int dev, const int prog, const char *binname, const char *cachedir, char *md5sum, int loaded_cached)
int dt_opencl_get_max_work_item_sizes(const int dev, size_t *sizes)
int dt_opencl_enqueue_barrier(const int devid)
static FILE * fopen_stat(const char *filename, struct stat *st)
gboolean dt_opencl_image_fits_device(const int devid, const size_t width, const size_t height, const unsigned bpp, const float factor, const size_t overhead)
int dt_opencl_unmap_mem_object(const int devid, cl_mem mem_object, void *mapped_ptr)
int dt_opencl_read_host_from_device_raw(const int devid, void *host, void *device, const size_t *origin, const size_t *region, const int rowpitch, const int blocking)
gboolean dt_opencl_detected_device_pinned_memory(const int detected)
int dt_opencl_set_detected_device_headroom(const int detected, const size_t headroom)
int dt_opencl_is_enabled(void)
void dt_opencl_memory_statistics(int devid, cl_mem mem, size_t size, dt_opencl_memory_t action)
void dt_opencl_md5sum(const char **files, char **md5sums)
static int nextpow2(int n)
void dt_opencl_free_kernel(const int kernel)
static gboolean _opencl_splash_active
gboolean dt_opencl_use_pinned_memory(const int devid)
void dt_opencl_cleanup(dt_opencl_t *cl)
int dt_opencl_get_image_width(cl_mem mem)
cl_ulong dt_opencl_get_device_memalloc(const int devid)
int dt_opencl_read_host_from_device_non_blocking(const int devid, void *host, void *device, const int width, const int height, const int bpp)
int dt_opencl_get_detected_device_count(void)
void * dt_opencl_map_image(const int devid, cl_mem buffer, const int blocking, const int flags, size_t width, size_t height, int bpp)
void * dt_opencl_alloc_device_buffer_with_flags(const int devid, const size_t size, const int flags, void *host_ptr)
int dt_opencl_write_host_to_device_rowpitch_non_blocking(const int devid, void *host, void *device, const int width, const int height, const int rowpitch)
static void dt_opencl_priority_parse(dt_opencl_t *cl, char *configstr, int *priority_list, int *mandatory)
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
gboolean dt_opencl_finish(const int devid)
int dt_opencl_enqueue_copy_image_to_buffer(const int devid, cl_mem src_image, cl_mem dst_buffer, size_t *origin, size_t *region, size_t offset)
static void _opencl_splash_update_compile(const char *programname)
int dt_opencl_update_settings(void)
void dt_opencl_events_wait_for(const int devid)
int dt_opencl_set_detected_device_pinned_memory(const int detected, const gboolean enabled)
int dt_opencl_read_host_from_device(const int devid, void *host, void *device, const int width, const int height, const int bpp)
void dt_opencl_events_profiling(const int devid, const int aggregated)
int dt_opencl_get_work_group_limits(const int dev, size_t *sizes, size_t *workgroupsize, unsigned long *localmemsize)
int dt_opencl_enqueue_kernel_2d_with_local(const int dev, const int kernel, const size_t *sizes, const size_t *local)
cl_mem_flags dt_opencl_get_mem_flags(cl_mem mem)
int dt_opencl_enqueue_copy_buffer_to_buffer(const int devid, cl_mem src_buffer, cl_mem dst_buffer, size_t srcoffset, size_t dstoffset, size_t size)
const dt_opencl_detected_device_t * dt_opencl_get_detected_device(const int detected)
void * dt_opencl_copy_host_to_device(const int devid, void *host, const int width, const int height, const int bpp)
int dt_opencl_write_host_to_device_raw(const int devid, const void *host, void *device, const size_t *origin, const size_t *region, const int rowpitch, const int blocking)
size_t dt_opencl_detected_device_headroom(const int detected)
void dt_opencl_release_mem_object(cl_mem mem)
static int _device_by_cname(const char *name)
int dt_opencl_get_image_element_size(cl_mem mem)
gboolean dt_opencl_detected_device_enabled(const int detected)
static const char * dt_opencl_get_vendor_by_id(unsigned int id)
int dt_opencl_get_device_info(dt_opencl_t *cl, cl_device_id device, cl_device_info param_name, void **param_value, size_t *param_value_size)
int dt_opencl_avoid_atomics(const int devid)
int dt_opencl_write_host_to_device(const int devid, void *host, void *device, const int width, const int height, const int bpp)
void dt_opencl_disable(void)
#define DT_OPENCL_MAX_INCLUDES
#define DT_OPENCL_EVENTLISTSIZE
#define DT_OPENCL_BPP_DECODE(bpp)
@ DT_OPENCL_PINNING_DISABLED
@ DT_OPENCL_FIT_ALLOC_LIMIT
@ DT_OPENCL_FIT_AVAILABLE
@ DT_OPENCL_FIT_DIMENSION
#define DT_OPENCL_DEFAULT_COMPILE
#define DT_OPENCL_DEFAULT_COMPILE_INTEL
#define DT_OPENCL_BPP_IS_RGBA8(bpp)
#define DT_OPENCL_CBUFFSIZE
#define DT_OPENCL_EVENTNAMELENGTH
#define DT_OPENCL_VENDOR_INTEL
#define DT_OPENCL_MAX_PROGRAMS
#define DT_OPENCL_MAX_PLATFORMS
#define DT_OPENCL_DEFAULT_COMPILE_AMD
#define DT_OPENCL_DEFAULT_COMPILE_NVIDIA
#define DT_OPENCL_VENDOR_NVIDIA
#define DT_OPENCL_VENDOR_AMD
#define DT_OPENCL_MAX_KERNELS
static gboolean dt_opencl_check_driver_blacklist(const char *device_version)
@ DT_DEV_PIXELPIPE_THUMBNAIL
@ DT_DEV_PIXELPIPE_EXPORT
@ DT_DEV_PIXELPIPE_PREVIEW
void dt_dev_pixelpipe_cache_flush_clmem(dt_dev_pixelpipe_cache_t *cache, const int devid)
Release cached OpenCL buffers for a single device.
Pixelpipe cache for storing intermediate results in the pixelpipe.
void dt_gui_splash_init(void)
void dt_gui_splash_updatef(const char *format,...)
unsigned __int64 uint64_t
struct dt_dev_pixelpipe_cache_t * pixelpipe_cache
struct dt_gui_gtk_t * gui
struct dt_opencl_t * opencl
dt_clEnqueueReadImage_t dt_clEnqueueReadImage
dt_clGetEventInfo_t dt_clGetEventInfo
dt_clReleaseCommandQueue_t dt_clReleaseCommandQueue
dt_clEnqueueUnmapMemObject_t dt_clEnqueueUnmapMemObject
dt_clGetKernelInfo_t dt_clGetKernelInfo
dt_clGetEventProfilingInfo_t dt_clGetEventProfilingInfo
dt_clCreateCommandQueue_t dt_clCreateCommandQueue
dt_clCreateImage2D_t dt_clCreateImage2D
dt_clEnqueueCopyBuffer_t dt_clEnqueueCopyBuffer
dt_clGetPlatformInfo_t dt_clGetPlatformInfo
dt_clBuildProgram_t dt_clBuildProgram
dt_clEnqueueWriteBuffer_t dt_clEnqueueWriteBuffer
dt_clCreateContext_t dt_clCreateContext
dt_clGetDeviceIDs_t dt_clGetDeviceIDs
dt_clGetMemObjectInfo_t dt_clGetMemObjectInfo
dt_clEnqueueCopyImage_t dt_clEnqueueCopyImage
dt_clReleaseContext_t dt_clReleaseContext
dt_clFinish_t dt_clFinish
dt_clGetDeviceInfo_t dt_clGetDeviceInfo
dt_clEnqueueCopyImageToBuffer_t dt_clEnqueueCopyImageToBuffer
dt_clGetImageInfo_t dt_clGetImageInfo
dt_clCreateBuffer_t dt_clCreateBuffer
dt_clCreateProgramWithBinary_t dt_clCreateProgramWithBinary
dt_clReleaseKernel_t dt_clReleaseKernel
dt_clEnqueueWriteImage_t dt_clEnqueueWriteImage
dt_clSetKernelArg_t dt_clSetKernelArg
dt_clReleaseEvent_t dt_clReleaseEvent
dt_clEnqueueMapImage_t dt_clEnqueueMapImage
dt_clEnqueueBarrier_t dt_clEnqueueBarrier
dt_clGetPlatformIDs_t dt_clGetPlatformIDs
dt_clGetProgramInfo_t dt_clGetProgramInfo
dt_clGetKernelWorkGroupInfo_t dt_clGetKernelWorkGroupInfo
dt_clReleaseMemObject_t dt_clReleaseMemObject
dt_clGetProgramBuildInfo_t dt_clGetProgramBuildInfo
dt_clReleaseProgram_t dt_clReleaseProgram
dt_clEnqueueNDRangeKernel_t dt_clEnqueueNDRangeKernel
dt_clWaitForEvents_t dt_clWaitForEvents
dt_clEnqueueReadBuffer_t dt_clEnqueueReadBuffer
dt_clEnqueueCopyBufferToImage_t dt_clEnqueueCopyBufferToImage
dt_clEnqueueMapBuffer_t dt_clEnqueueMapBuffer
dt_clCreateKernel_t dt_clCreateKernel
dt_clCreateProgramWithSource_t dt_clCreateProgramWithSource
dt_dlopencl_symbols_t * symbols
gboolean host_unified_memory
gboolean host_unified_memory
cl_command_queue cmd_queue
dt_opencl_eventtag_t * eventtags
struct dt_gaussian_cl_global_t * gaussian
int opencl_synchronization_timeout
int * dev_priority_preview
struct dt_bilateral_cl_global_t * bilateral
struct dt_colorspaces_cl_global_t * colorspaces
struct dt_guided_filter_cl_global_t * guided_filter
struct dt_interpolation_cl_global_t * interpolation
struct dt_local_laplacian_cl_global_t * local_laplacian
struct dt_blendop_cl_global_t * blendop
struct dt_dwt_cl_global_t * dwt
int * dev_priority_export
dt_pthread_mutex_t mem_sizes_lock
dt_opencl_detected_device_t * detected_devs
int * dev_priority_thumbnail
struct dt_heal_cl_global_t * heal
gchar * dt_util_str_replace(const gchar *string, const gchar *pattern, const gchar *substitute)