86#include <glib/gstdio.h>
163 size_t *param_value_size)
165 *param_value_size = SIZE_MAX;
169 if(err != CL_SUCCESS)
172 "[dt_opencl_get_device_info] could not query the actual size in bytes of info %d: %i\n", param_name, err);
177 if(*param_value_size == SIZE_MAX || *param_value_size == 0)
181 "[dt_opencl_get_device_info] ERROR: no size returned, or zero size returned for data %d: %" G_GSIZE_FORMAT
"\n",
182 param_name, *param_value_size);
183 err = CL_INVALID_VALUE;
189 void *ptr = realloc(*param_value, *param_value_size);
193 "[dt_opencl_get_device_info] memory allocation failed! tried to allocate %" G_GSIZE_FORMAT
" bytes for data %d: %i",
194 *param_value_size, param_name, err);
195 err = CL_OUT_OF_HOST_MEMORY;
205 if(err != CL_SUCCESS)
215 *param_value_size = 0;
241 return (
flags & CL_MEM_USE_HOST_PTR) || (
flags & CL_MEM_ALLOC_HOST_PTR);
246 if(devid < 0)
return;
248 gchar buf[256] = { 0 };
249 gchar key_device[256] = { 0 };
252 g_snprintf(buf,
sizeof(buf),
"%s/avoid_atomics", key_device);
255 g_snprintf(buf,
sizeof(buf),
"%s/micro_nap", key_device);
258 g_snprintf(buf,
sizeof(buf),
"%s/pinned_memory", key_device);
261 g_snprintf(buf,
sizeof(buf),
"%s/wd", key_device);
264 g_snprintf(buf,
sizeof(buf),
"%s/ht", key_device);
267 g_snprintf(buf,
sizeof(buf),
"%s/event_handles", key_device);
270 g_snprintf(buf,
sizeof(buf),
"%s/disabled", key_device);
273 g_snprintf(buf,
sizeof(buf),
"%s/id%i/forced_headroom", key_device, devid);
280 gchar *
key = g_strconcat(key_device,
"/", conf_name, NULL);
296 if(devid < 0)
return FALSE;
298 gchar key_device[256] = { 0 };
300 gboolean safety_ok =
TRUE;
311 safety_ok |= (wd > 1) && (wd < 513) && (ht > 1) && (ht < 513);
359 gchar pin_default_key[256] = { 0 };
360 g_snprintf(pin_default_key,
sizeof(pin_default_key),
"%s/pinned_memory_default_applied", key_device);
367 "[dt_opencl_read_device_config] '%s' had pinned memory transfer off from an older "
368 "configuration; enabling it, which is the default\n", cl->
dev[devid].
cname);
420 gchar
key[256] = { 0 };
433 gchar
key[256] = { 0 };
441 gboolean opencl_enabled =
enabled;
446 for(
int dev = 0; dev < cl->num_detected_devs; dev++)
450 opencl_enabled =
TRUE;
465 gchar
key[256] = { 0 };
478 gchar
key[256] = { 0 };
499 gchar
key[256] = { 0 };
511 gchar
key[256] = { 0 };
514 const int clamped_headroom = (int)
MIN(headroom, (
size_t)G_MAXINT);
536 gboolean lock_initialized =
FALSE;
577 cl_device_id devid = cl->
dev[dev].
devid = devices[
k];
579 char *infostr = NULL;
588 char *driverversion = NULL;
589 size_t driverversion_size;
591 char *deviceversion = NULL;
592 size_t deviceversion_size;
595 size_t *infointtab = NULL;
597 cl_bool image_support = 0;
598 cl_bool device_available = 0;
599 cl_uint vendor_id = 0;
600 cl_bool little_endian = 0;
601 cl_platform_id platform_id = 0;
604 char *cachedir = calloc(
DT_PATH_MAX,
sizeof(
char));
611 char *filename = calloc(
DT_PATH_MAX,
sizeof(
char));
612 char *confentry = calloc(
DT_PATH_MAX,
sizeof(
char));
621 cl_bool host_unified_memory = CL_FALSE;
623 &host_unified_memory, NULL);
627 if(err != CL_SUCCESS)
637 if(err != CL_SUCCESS)
645 cname_size = infostr_size;
646 cname = malloc(cname_size);
648 cl->
dev[dev].
name = strdup(infostr);
652 cl->
crc = crc32(cl->
crc, (
const unsigned char *)infostr, strlen(infostr));
655 if(err != CL_SUCCESS)
664 if(err != CL_SUCCESS)
671 if(err != CL_SUCCESS)
684 if(err != CL_SUCCESS)
693 if(err != CL_SUCCESS)
702 cl->
crc = crc32(cl->
crc, (
const unsigned char *)deviceversion, deviceversion_size);
717 if(!strncasecmp(vendor,
"NVIDIA", 6))
724 const gboolean is_cpu_device = (
type & CL_DEVICE_TYPE_CPU) == CL_DEVICE_TYPE_CPU;
734 ((
type & CL_DEVICE_TYPE_CPU) == CL_DEVICE_TYPE_CPU) ?
"CPU" :
"",
735 ((
type & CL_DEVICE_TYPE_GPU) == CL_DEVICE_TYPE_GPU) ?
"GPU" :
"",
736 (
type & CL_DEVICE_TYPE_ACCELERATOR) ?
", Accelerator" :
"" );
738 if(is_cpu_device && newdevice)
746 if(!device_available)
802 if(runtime_crash_streak >= 2)
805 "[opencl_init] disabling device %d `%s' (%s runtime, driver %s): the last %d"
806 " crashes happened inside this OpenCL runtime. Re-enable it in preferences once"
807 " the driver is updated; devices on other runtimes are unaffected.\n",
809 driverversion ? driverversion :
"?", runtime_crash_streak);
818 if(newdevice && is_blacklisted)
821 const gboolean old_blacklist =
dt_conf_get_bool(
"opencl_disable_drivers_blacklist");
837 size_t infointtab_size;
839 if(err == CL_SUCCESS)
864 if(
type & CL_DEVICE_TYPE_GPU)
893 lock_initialized =
TRUE;
896 if(err != CL_SUCCESS)
905 if(err != CL_SUCCESS)
915 double tstart, tend, tdiff;
918 int len =
MIN(strlen(infostr),1024 *
sizeof(
char));;
921 for(
int i = 0;
i < len;
i++)
922 if(isalnum(infostr[
i])) devname[j++] = infostr[
i];
924 len =
MIN(strlen(driverversion), 1024 *
sizeof(
char));
927 for(
int i = 0;
i < len;
i++)
928 if(isalnum(driverversion[
i])) drvversion[j++] = driverversion[
i];
930 snprintf(cachedir,
DT_PATH_MAX *
sizeof(
char),
"%s" G_DIR_SEPARATOR_S
"cached_kernels_for_%s_%s", dtcache, devname, drvversion);
934 if(g_mkdir_with_parents(cachedir, 0700) == -1)
943 char *escapedkerneldir = NULL;
945 escapedkerneldir = g_strdup_printf(
"\"%s\"", kerneldir);
951 const char* compile_opt = NULL;
972 gchar *my_option = g_strdup(compile_opt);
975 cl->
dev[dev].
options = g_strdup_printf(
"-w %s %s -D%s=1 -I%s",
980 const char *kerneldir_token =
"<ansel-kernels>";
981 char *escapedkerneldir_md5 = NULL;
983 escapedkerneldir_md5 = g_strdup_printf(
"\"%s\"", kerneldir_token);
985 escapedkerneldir_md5 = g_strdup(kerneldir_token);
987 cl->
dev[dev].
options_md5 = g_strdup_printf(
"-w %s %s -D%s=1 -I%s",
994 dt_free(compile_option_name_cname);
998 escapedkerneldir = NULL;
1004 const char *clincludes[
DT_OPENCL_MAX_INCLUDES] = {
"rgb_norms.h",
"noise_generator.h",
"color_conversion.h",
"colorspaces.cl",
"colorspace.h",
"common.h",
"lensserious_eval.h", NULL };
1017 FILE *
f = g_fopen(filename,
"rb");
1023 gchar *confline_pattern = g_strdup_printf(
"%%%" G_GSIZE_FORMAT
"[^\n]\n",
DT_PATH_MAX *
sizeof(
char) - 1);
1024 int rd = fscanf(
f, confline_pattern, confentry);
1026 if(rd != 1)
continue;
1028 size_t end = strlen(confentry);
1029 for(
size_t pos = 0; pos < end; pos++)
1030 if(confentry[pos] ==
'#')
1032 confentry[pos] =
'\0';
1033 for(
int l = pos - 1; l >= 0; l--)
1035 if(confentry[l] ==
' ')
1036 confentry[l] =
'\0';
1042 if(confentry[0] ==
'\0')
continue;
1044 const char *programname = NULL, *programnumber = NULL;
1045 gchar **tokens = g_strsplit_set(confentry,
" \t", 2);
1048 programname = tokens[0];
1050 programnumber = tokens[1];
1053 prog = programnumber ? strtol(programnumber, NULL, 10) : -1;
1055 if(
IS_NULL_PTR(programname) || programname[0] ==
'\0' || prog < 0)
1057 dt_print(
DT_DEBUG_OPENCL,
"[dt_opencl_device_init] malformed entry in programs.conf `%s'; ignoring it!\n", confentry);
1061 gchar *program_bin = g_strdup_printf(
"%s.bin", programname);
1088 tdiff = tend - tstart;
1106 if(lock_initialized)
1184 {
"RusticlOpenCL",
"rusticl",
"rusticl" },
1185 {
"libMesaOpenCL",
"Clover",
"clover" },
1186 {
"amdocl",
"AMD",
"amd" },
1187 {
"libigdfcl",
"Intel(R) OpenCL",
"intel" },
1188 {
"libigdrcl",
"Intel(R) OpenCL",
"intel" },
1189 {
"intelocl",
"Intel(R) OpenCL",
"intel" },
1190 {
"libnvidia-opencl",
"NVIDIA",
"nvidia" },
1191 {
"nvopencl",
"NVIDIA",
"nvidia" },
1192 { NULL, NULL, NULL }
1201 gchar *haystack = g_ascii_strdown(platform_name, -1);
1202 const char *runtime = NULL;
1217 snprintf(
key,
sizeof(
key),
"opencl_driver_crash_streak_%s", runtime);
1225 snprintf(
key,
sizeof(
key),
"opencl_driver_crash_streak_%s", runtime);
1238 char *marker = g_build_filename(cachedir,
"gpu-driver-crash", NULL);
1239 g_strlcpy(buf, marker, buf_len);
1251 const char *culprit = NULL;
1261 const ssize_t
w1 = write(fd, culprit, strlen(culprit));
1262 const ssize_t
w2 = write(fd,
"\n", 1);
1277 gchar *contents = NULL;
1284 gchar **lines = g_strsplit(contents,
"\n", -1);
1285 for(
int l = 0; lines[l]; l++)
1287 if(lines[l][0] ==
'\0')
continue;
1309 cl->
mem_sizes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
1347 if(exclude_opencl)
return;
1353 char *locale = strdup(setlocale(LC_ALL, NULL));
1354 setlocale(LC_ALL,
"C");
1356 cl_platform_id *all_platforms = NULL;
1357 cl_uint *all_num_devices = NULL;
1374 "[opencl_init] no working opencl library found. Continue with opencl disabled\n");
1388 if(err != CL_SUCCESS)
1394 if(num_platforms == 0)
1400 num_platforms > 1 ?
"s" :
"");
1402 for(
int n = 0;
n < num_platforms;
n++)
1404 cl_platform_id platform = all_platforms[
n];
1408 if(err != CL_SUCCESS)
1412 if((errn == CL_SUCCESS) && (errv == CL_SUCCESS))
1417 all_num_devices[
n] = 0;
1421 char profile[64] = { 0 };
1422 size_t profile_size;
1424 if(err != CL_SUCCESS)
1426 all_num_devices[
n] = 0;
1432 if(strcmp(
"FULL_PROFILE", profile) != 0)
1434 all_num_devices[
n] = 0;
1441 cl_uint num_devices = 0;
1442 for(
int n = 0;
n < num_platforms;
n++) num_devices += all_num_devices[
n];
1445 cl_device_id *devices = 0;
1449 devices = (cl_device_id *)malloc(
sizeof(cl_device_id) * num_devices);
1459 cl_device_id *devs = devices;
1460 for(
int n = 0;
n < num_platforms;
n++)
1462 if(all_num_devices[
n])
1464 cl_platform_id platform = all_platforms[
n];
1467 if(err != CL_SUCCESS)
1469 num_devices -= all_num_devices[
n];
1472 devs += all_num_devices[
n];
1478 if(num_devices == 0)
1488 for(
int k = 0;
k < num_devices;
k++)
1525 cl->
inited ?
"" :
"NOT ");
1530 snprintf(checksum,
sizeof(checksum),
"%u", cl->
crc);
1560 setlocale(LC_ALL, locale);
1581 dt_print_nts(
DT_DEBUG_OPENCL,
" [opencl_summary_statistics] device '%s' (%d): peak memory usage %" G_GSIZE_FORMAT
" bytes (%.1f MB)\n",
1590 "successful and %d events lost. max event=%d%s\n",
1723 return (err == CL_SUCCESS && success == CL_COMPLETE);
1729 if(!cl->
inited || devid < 0)
return -1;
1737 while(*list != -1 && *list !=
value) list++;
1742 *list = *(list + 1);
1754 char tmp[2048] = { 0 };
1759 for(
int i = 0;
i < devs;
i++)
1776 maxlen = strlen(in) + 1;
1777 out = malloc(maxlen);
1783 while(*in !=
'\0' && len < maxlen - 1)
1785 int n = strcspn(in,
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
1787 if(
n != 0)
continue;
1788 out[len] = tolower(*in);
1802 int *full = malloc(
sizeof(
int) * (devs + 1));
1808 priority_list[0] = -1;
1815 if(configstr[0] ==
'+')
1822 for(
int i = 0;
i < devs;
i++) full[
i] =
i;
1825 gchar **tokens = g_strsplit(configstr,
",", 0);
1826 gchar **tokens_ptr = tokens;
1830 gchar *str = *tokens_ptr;
1841 while(*str ==
'!') str++;
1848 for(
int i = 0;
i < devs && full[
i] != -1;
i++)
1850 priority_list[count] = full[
i];
1855 else if(*str !=
'\0')
1857 char *endptr = NULL;
1863 if(number < 0) number = strtol(str, &endptr, 10);
1866 if(number < 0 || (number == 0 && endptr == str)) number = -1;
1871 if(!not&&dev_number != -1)
1873 priority_list[count] = dev_number;
1884 while(count < devs + 1) priority_list[count++] = -1;
1887 *mandatory = (priority_list[0] != -1) ? mnd : 0;
1931 if(!cl->
inited)
return -1;
1936 size_t prio_size =
sizeof(int) * (cl->
num_devs + 1);
1937 int *priority = (
int *)malloc(prio_size);
1967 const int usec = 5000;
1971 for(
int n = 0;
n < nloop;
n++)
1973 const int *prio = priority;
1994 dt_print(
DT_DEBUG_OPENCL,
"[opencl_lock_device] reached opencl_mandatory_timeout trying to lock mandatory device, fallback to CPU\n");
1999 for(
int try_dev = 0; try_dev < cl->
num_devs; try_dev++)
2017 if(devid < 0 || devid >= cl->
num_devs)
return;
2028 if(devid < 0 || devid >= cl->
num_devs)
return;
2038 if(!cl->
inited)
return 1;
2039 if(devid < 0 || devid >= cl->
num_devs)
return 1;
2046 if(!cl || !cl->
inited)
return 0;
2054 if(devid < 0 || devid >= cl->
num_devs)
return NULL;
2072 if(devid < 0 || devid >= cl->
num_devs)
return 0;
2080 if(devid < 0 || devid >= cl->
num_devs)
return 0;
2088 if(devid < 0 || devid >= cl->
num_devs)
return 0;
2109 FILE *
f = g_fopen(filename,
"rb");
2116 if(fstat(fd, st) < 0)
2142 struct stat filestat;
2152 size_t filesize = filestat.st_size;
2153 char *file = (
char *)malloc(filesize);
2163 size_t rd = fread(file,
sizeof(
char), filesize,
f);
2174 *md5sums = g_compute_checksum_for_data(G_CHECKSUM_MD5, (guchar *)file, filesize);
2181 const char *cachedir,
char *md5sum,
char **includemd5,
int *loaded_cached)
2186 struct stat filestat, cachedstat;
2199 "[opencl_load_source] program number `%d' already in use when loading file `%s'!\n", prog,
2207 size_t filesize = filestat.st_size;
2208 char *file = (
char *)malloc(filesize + 2048);
2209 size_t rd = fread(file,
sizeof(
char), filesize,
f);
2218 char *start = file + filesize;
2219 char *end = start + 2048;
2222 cl_device_id devid = cl->
dev[dev].
devid;
2226 cl_platform_id platform;
2233 len = g_strlcpy(start, options_md5, end - start);
2239 if(!includemd5[
n])
continue;
2240 len = g_strlcpy(start, includemd5[
n], end - start);
2244 char *source_md5 = g_compute_checksum_for_data(G_CHECKSUM_MD5, (guchar *)file, start - file);
2245 g_strlcpy(md5sum, source_md5, 33);
2248 file[filesize] =
'\0';
2251 ssize_t linkedfile_len = 0;
2257 snprintf(dup,
sizeof(dup),
"%s.%s", binname, md5sum);
2259 g_strlcpy(linkedfile, md5sum,
sizeof(linkedfile));
2260 linkedfile_len = strlen(md5sum);
2262 FILE *cached =
fopen_stat(binname, &cachedstat);
2268 linkedfile_len = readlink(binname, linkedfile,
sizeof(linkedfile) - 1);
2270 if(linkedfile_len > 0)
2272 linkedfile[linkedfile_len] =
'\0';
2274 if(strncmp(linkedfile, md5sum, 33) == 0)
2277 size_t cached_filesize = cachedstat.st_size;
2279 unsigned char *cached_content = (
unsigned char *)malloc(cached_filesize + 1);
2283 "[opencl_load_program] could not allocate %zu bytes for cached binary '%s'!\n",
2284 cached_filesize + 1, binname);
2288 rd = fread(cached_content,
sizeof(
char), cached_filesize, cached);
2289 if(rd != cached_filesize)
2291 dt_print(
DT_DEBUG_OPENCL,
"[opencl_load_program] could not read all of file '%s' MD5: %s!\n", binname, md5sum);
2297 (
const unsigned char **)&cached_content, NULL, &err);
2298 if(err != CL_SUCCESS)
2301 "[opencl_load_program] could not load cached binary program from file '%s' MD5: '%s'! (%i)\n",
2302 binname, md5sum, err);
2317 if(*loaded_cached == 0)
2322 if(linkedfile_len > 0)
2326 g_unlink(link_dest);
2335 "[opencl_load_program] could not load cached binary program, trying to compile source\n");
2338 cl->
dev[dev].
context, 1, (
const char **)&file, &filesize, &err);
2340 if((err != CL_SUCCESS) || (cl->
dev[dev].
program[prog] == NULL))
2354 dt_vprint(
DT_DEBUG_OPENCL,
"[opencl_load_program] loaded cached binary program from file '%s' MD5: '%s' \n", binname, md5sum);
2357 dt_vprint(
DT_DEBUG_OPENCL,
"[opencl_load_program] successfully loaded program from '%s' MD5: '%s'\n", filename, md5sum);
2363 char *md5sum,
int loaded_cached)
2367 cl_program program = cl->
dev[dev].
program[prog];
2370 if(err != CL_SUCCESS)
2375 cl_build_status build_status;
2377 sizeof(cl_build_status), &build_status, NULL);
2381 size_t ret_val_size;
2384 if(ret_val_size != SIZE_MAX)
2386 build_log = (
char *)malloc(
sizeof(
char) * (ret_val_size + 1));
2390 ret_val_size, build_log, NULL);
2392 build_log[ret_val_size] =
'\0';
2401 if(err != CL_SUCCESS)
2412 if(err != CL_SUCCESS)
2418 cl_device_id *devices = malloc(
sizeof(cl_device_id) * numdev);
2420 sizeof(cl_device_id) * numdev, devices, NULL);
2421 if(err != CL_SUCCESS)
2428 size_t *binary_sizes = malloc(
sizeof(
size_t) * numdev);
2430 sizeof(
size_t) * numdev, binary_sizes, NULL);
2431 if(err != CL_SUCCESS)
2439 unsigned char **binaries = malloc(
sizeof(
unsigned char *) * numdev);
2440 for(
int i = 0;
i < numdev;
i++) binaries[
i] = (
unsigned char *)malloc(binary_sizes[
i]);
2442 sizeof(
unsigned char *) * numdev, binaries, NULL);
2443 if(err != CL_SUCCESS)
2449 for(
int i = 0;
i < numdev;
i++)
2454 snprintf(link_dest,
sizeof(link_dest),
"%s" G_DIR_SEPARATOR_S
"%s", cachedir, md5sum);
2455 FILE *
f = g_fopen(link_dest,
"wb");
2457 const size_t bytes_written = fwrite(binaries[
i],
sizeof(
char), binary_sizes[
i],
f);
2459 if(bytes_written != binary_sizes[
i])
goto ret;
2472 gchar *bname = g_path_get_basename(binname);
2474 snprintf(link_name,
sizeof(link_name),
"%s" G_DIR_SEPARATOR_S
"%s", cachedir, bname);
2479 snprintf(final_name,
sizeof(final_name),
"%s.%s", link_name, md5sum);
2480 const int link_failed = (g_rename(link_dest, final_name) != 0);
2484 g_unlink(link_name);
2485 const int link_failed = (symlink(md5sum, link_name) != 0);
2491 link_name, strerror(errno));
2497 for(
int i = 0;
i < numdev;
i++)
dt_free(binaries[
i]);
2509 if(!cl->
inited)
return -1;
2513 for(
int dev = 0; dev < cl->
num_devs; dev++)
2522 if(err != CL_SUCCESS)
2555 for(
int dev = 0; dev < cl->
num_devs; dev++)
2566 if(!cl->
inited || dev < 0)
return -1;
2568 sizeof(size_t) * 3, sizes, NULL);
2572 unsigned long *localmemsize)
2575 if(!cl->
inited || dev < 0)
return -1;
2578 sizeof(cl_ulong), &lmemsize, NULL);
2579 if(err != CL_SUCCESS)
return err;
2581 *localmemsize = lmemsize;
2584 sizeof(
size_t), workgroupsize, NULL);
2585 if(err != CL_SUCCESS)
return err;
2594 if(!cl->
inited || dev < 0)
return -1;
2598 CL_KERNEL_WORK_GROUP_SIZE,
sizeof(size_t),
2599 kernelworkgroupsize, NULL);
2607 if(!cl->
inited || dev < 0)
return -1;
2619 const size_t *local)
2622 if(!cl->
inited || dev < 0)
return -1;
2631 2, NULL, sizes, local, 0, NULL, eventp);
2633 if(err != CL_SUCCESS)
2652 const int height,
const int rowpitch)
2655 const size_t origin[] = { 0, 0, 0 };
2673 const size_t origin[] = { 0, 0, 0 };
2681 const size_t *region,
const int rowpitch,
const int blocking)
2688 device, blocking ? CL_TRUE : CL_FALSE, origin, region, rowpitch,
2689 0, host, 0, NULL, eventp);
2699 const int height,
const int rowpitch)
2702 const size_t origin[] = { 0, 0, 0 };
2719 const size_t origin[] = { 0, 0, 0 };
2726 const size_t *region,
const int rowpitch,
const int blocking)
2733 device, blocking ? CL_TRUE : CL_FALSE, origin, region,
2734 rowpitch, 0, host, 0, NULL, eventp);
2744 if(err != CL_SUCCESS)
dt_print(
DT_DEBUG_OPENCL,
"[opencl copy_image] could not copy image on device %d: %i\n", devid, err);
2749 size_t *origin,
size_t *region,
size_t offset)
2754 _opencl->
dev[devid].
cmd_queue, src_image, dst_buffer, origin, region, offset, 0, NULL, eventp);
2755 if(err != CL_SUCCESS)
2756 dt_print(
DT_DEBUG_OPENCL,
"[opencl copy_image_to_buffer] could not copy image on device %d: %i\n", devid, err);
2761 size_t offset,
size_t *origin,
size_t *region)
2766 _opencl->
dev[devid].
cmd_queue, src_buffer, dst_image, offset, origin, region, 0, NULL, eventp);
2767 if(err != CL_SUCCESS)
2768 dt_print(
DT_DEBUG_OPENCL,
"[opencl copy_buffer_to_image] could not copy buffer on device %d: %i\n", devid, err);
2773 size_t srcoffset,
size_t dstoffset,
size_t size)
2778 src_buffer, dst_buffer, srcoffset,
2779 dstoffset,
size, 0, NULL, eventp);
2780 if(err != CL_SUCCESS)
2781 dt_print(
DT_DEBUG_OPENCL,
"[opencl copy_buffer_to_buffer] could not copy buffer on device %d: %i\n", devid, err);
2786 const size_t size,
const int blocking)
2797 const size_t size,
const int blocking)
2814 if(err != CL_SUCCESS)
2816 "[opencl copy_host_to_device_constant] could not alloc buffer on device %d: %i\n", devid, err);
2830 const int bpp,
const int rowpitch)
2834 cl_image_format fmt;
2836 if(
bpp == 4 *
sizeof(
float))
2837 fmt = (cl_image_format){ CL_RGBA, CL_FLOAT };
2838 else if(
bpp ==
sizeof(
float))
2839 fmt = (cl_image_format){ CL_R, CL_FLOAT };
2840 else if(
bpp ==
sizeof(uint16_t))
2841 fmt = (cl_image_format){ CL_R, CL_UNSIGNED_INT16 };
2848 rowpitch, host, &err);
2849 if(err != CL_SUCCESS)
2851 "[opencl copy_host_to_device] could not alloc/copy img buffer on device %d: %i\n", devid, err);
2853 if(err == CL_SUCCESS)
2855 const size_t bytes = (size_t)(rowpitch ? rowpitch :
width *
bpp) *
height;
2885 if(err != CL_SUCCESS)
dt_print(
DT_DEBUG_OPENCL,
"[opencl map buffer] could not map buffer on device %d: %i\n", devid, err);
2896 size_t origin[3] = {0, 0, 0};
2898 size_t mapped_row_pitch;
2902 &mapped_row_pitch, NULL, 0, NULL, eventp, &err);
2904 if(err != CL_SUCCESS)
2916 if(err != CL_SUCCESS)
2917 dt_print(
DT_DEBUG_OPENCL,
"[opencl unmap mem object] could not unmap mem object on device %d: %i\n", devid, err);
2922 const size_t bytes,
const cl_mem_flags
flags,
2923 const cl_image_format fmt,
void *host,
2924 const char *
const context)
2929 for(
int attempt = 0; attempt < 2; attempt++)
2933 if(err == CL_SUCCESS)
break;
2934 if(attempt == 0 && (err == CL_MEM_OBJECT_ALLOCATION_FAILURE || err == CL_OUT_OF_RESOURCES))
2937 "[opencl %s] out of memory on device %d, flushing cached pinned buffers and retrying\n",
2945 if(err != CL_SUCCESS)
2956 cl_image_format fmt;
2958 if(rgba8 && effective_bpp == 4 *
sizeof(uint8_t))
2959 fmt = (cl_image_format){ CL_RGBA, CL_UNSIGNED_INT8 };
2960 else if(effective_bpp == 4 *
sizeof(
float))
2961 fmt = (cl_image_format){ CL_RGBA, CL_FLOAT };
2962 else if(effective_bpp ==
sizeof(
float))
2963 fmt = (cl_image_format){ CL_R, CL_FLOAT };
2964 else if(effective_bpp ==
sizeof(uint16_t))
2965 fmt = (cl_image_format){ CL_R, CL_UNSIGNED_INT16 };
2966 else if(effective_bpp ==
sizeof(uint8_t))
2967 fmt = (cl_image_format){ CL_R, CL_UNSIGNED_INT8 };
2971 const size_t bytes = (size_t)
width *
height * effective_bpp;
2976 const int bpp,
void *host,
const int flags)
2980 cl_image_format fmt;
2982 if(rgba8 && effective_bpp == 4 *
sizeof(uint8_t))
2983 fmt = (cl_image_format){ CL_RGBA, CL_UNSIGNED_INT8 };
2984 else if(effective_bpp == 4 *
sizeof(
float))
2985 fmt = (cl_image_format){ CL_RGBA, CL_FLOAT };
2986 else if(effective_bpp ==
sizeof(
float))
2987 fmt = (cl_image_format){ CL_R, CL_FLOAT };
2988 else if(effective_bpp ==
sizeof(uint16_t))
2989 fmt = (cl_image_format){ CL_R, CL_UNSIGNED_INT16 };
2993 const size_t bytes = (size_t)
width *
height * effective_bpp;
2995 "alloc_device_use_host_pointer");
3003 for(
int attempt = 0; attempt < 2; attempt++)
3007 if(err == CL_SUCCESS)
break;
3008 if(attempt == 0 && (err == CL_MEM_OBJECT_ALLOCATION_FAILURE || err == CL_OUT_OF_RESOURCES))
3011 "[opencl alloc_device_buffer] out of memory on device %d, flushing cached pinned buffers and retrying\n",
3018 if(err != CL_SUCCESS)
3041 return (err == CL_SUCCESS) ?
size : 0;
3050 if(err != CL_SUCCESS)
3065 cl_mem_flags
flags = 0;
3067 if(err != CL_SUCCESS)
return 0;
3079 return (err == CL_SUCCESS) ? (int)
size : 0;
3090 return (err == CL_SUCCESS) ? (int)
size : 0;
3102 return (err == CL_SUCCESS) ? (int)
size : 0;
3119 if(devid < 0)
return;
3167 "[opencl memory] device %d: %" G_GSIZE_FORMAT
" bytes (%.1f MB) in use\n", devid,
_opencl->
dev[devid].
memory_in_use,
3179 *devid = rec->
devid;
3189 if(!cl->
inited || devid < 0)
return;
3198 "[dt_opencl_check_tuning] use %" G_GSIZE_FORMAT
" MiB on device `%s' id=%i\n",
3208 cl_ulong available = (limit > in_use) ? (limit - in_use) : 0;
3240 if(system_available > 0)
3241 available =
MIN(available, (cl_ulong)((system_available > reserved) ? system_available - reserved : 0));
3261 const size_t overhead,
size_t *needed,
size_t *limit)
3263 size_t n = 0, l = 0;
3267 if(!cl->
inited || devid < 0)
3274 const size_t total = (size_t)ceilf((
float)required *
factor) + overhead;
3286 "[opencl] trying to allocate %" PRIu64
" MiB of memory while the vRAM has %" PRIu64
3296 "[opencl] trying to allocate %" PRIu64
" MiB of memory while the vRAM has %" PRIu64
3303 if(needed) *needed =
n;
3304 if(limit) *limit = l;
3309 const float factor,
const size_t overhead)
3319 return (
size % roundup == 0 ?
size : (
size / roundup + 1) * roundup);
3324 return (
size % roundup == 0 ?
size : (
size / roundup + 1) * roundup);
3394 if(!cl->
inited || devid < 0)
return NULL;
3397 static const cl_event zeroevent[1];
3411 *eventlist = calloc(newevents,
sizeof(cl_event));
3413 if(!*eventlist || !*eventtags)
3422 *maxevents = newevents;
3426 if(*numevents > 0 && !memcmp((*eventlist) + *numevents - 1, zeroevent,
sizeof(cl_event)))
3436 (*eventtags)[*numevents - 1].tag[0] =
'\0';
3440 return (*eventlist) + *numevents - 1;
3444 if((*numevents - *eventsconsolidated + 1 > cl->
dev[devid].
event_handles) || (*numevents == *maxevents))
3448 if(*numevents == *maxevents)
3451 cl_event *neweventlist = calloc(newevents,
sizeof(cl_event));
3461 memcpy(neweventlist, *eventlist,
sizeof(cl_event) * *maxevents);
3465 *eventlist = neweventlist;
3466 *eventtags = neweventtags;
3467 *maxevents = newevents;
3472 memcpy((*eventlist) + *numevents - 1, zeroevent,
sizeof(cl_event));
3479 (*eventtags)[*numevents - 1].tag[0] =
'\0';
3483 *maxeventslot =
MAX(*maxeventslot, *numevents - 1);
3484 return (*eventlist) + *numevents - 1;
3492 if(!cl->
inited || devid < 0)
return;
3503 if(
IS_NULL_PTR(*eventlist) || *numevents == 0)
return;
3505 static const cl_event zeroevent[1];
3510 for(
int k = *eventsconsolidated;
k < *numevents;
k++)
3512 if(memcmp((*eventlist) +
k, zeroevent,
sizeof(cl_event)))
3518 *eventsconsolidated = 0;
3520 *summary = CL_COMPLETE;
3530 if(!cl->
inited || devid < 0)
return;
3533 static const cl_event zeroevent[1];
3540 if(
IS_NULL_PTR(*eventlist) || *numevents == 0)
return;
3543 if(!memcmp((*eventlist) + *numevents - 1, zeroevent,
sizeof(cl_event)))
3550 if(*numevents == *eventsconsolidated)
return;
3552 assert(*numevents > *eventsconsolidated);
3565 for(
int k = *eventsconsolidated;
k < *numevents;
k++)
3567 if(!memcmp((*eventlist) +
k, zeroevent,
sizeof(cl_event)))
3571 if((err != CL_SUCCESS) && (err != CL_INVALID_VALUE))
3599 static const cl_event zeroevent[1];
3601 if(
IS_NULL_PTR(*eventlist) || *numevents == 0)
return CL_COMPLETE;
3607 for(
int k = *eventsconsolidated;
k < *numevents;
k++)
3614 if(!memcmp((*eventlist) +
k, zeroevent,
sizeof(cl_event)))
3617 (*eventsconsolidated)++;
3622 char *tag = (*eventtags)[
k].tag;
3623 cl_int *retval = &((*eventtags)[
k].retval);
3627 sizeof(cl_int), retval, NULL);
3628 if(err != CL_SUCCESS)
3631 tag[0] ==
'\0' ?
"<?>" : tag, err);
3633 else if(*retval != CL_COMPLETE)
3636 tag[0] ==
'\0' ?
"<?>" : tag, *retval == CL_COMPLETE ?
"was successful" :
"failed", *retval);
3648 (*eventlist)[
k], CL_PROFILING_COMMAND_START,
sizeof(cl_ulong), &start, NULL);
3650 sizeof(cl_ulong), &end, NULL);
3651 if(errs == CL_SUCCESS && erre == CL_SUCCESS)
3653 (*eventtags)[
k].timelapsed = end - start;
3657 (*eventtags)[
k].timelapsed = 0;
3662 (*eventtags)[
k].timelapsed = 0;
3666 (*eventsconsolidated)++;
3669 cl_int result = *summary;
3681 return result == CL_COMPLETE ? 0 : result;
3690 if(!cl->
inited || devid < 0)
return;
3702 char **tags = malloc(
sizeof(
char *) * (*eventsconsolidated + 1));
3703 float *timings = malloc(
sizeof(
float) * (*eventsconsolidated + 1));
3709 for(
int k = 0;
k < *eventsconsolidated;
k++)
3729 timings[tagfound] += (*eventtags)[
k].timelapsed * 1e-9;
3735 tags[
items - 1] = (*eventtags)[
k].tag;
3736 timings[
items - 1] = (*eventtags)[
k].timelapsed * 1e-9;
3743 tags[
items - 1] = (*eventtags)[
k].tag;
3744 timings[
items - 1] = (*eventtags)[
k].timelapsed * 1e-9;
3750 "[opencl_profiling] profiling device %d ('%s'):\n", devid, cl->
dev[devid].
name);
3756 tags[
i][0] ==
'\0' ?
"<?>" : tags[
i]);
3757 total += timings[
i];
3760 if(timings[0] != 0.0f)
3763 total += timings[0];
3767 "[opencl_profiling] spent %7.4f seconds totally in command queue (with %d event%s missing)\n",
3768 (
double)total, *lostevents, *lostevents == 1 ?
"" :
"s");
3791 size_t maxsizes[3] = { 0 };
3792 size_t workgroupsize = 0;
3793 unsigned long localmemsize = 0;
3794 size_t kernelworkgroupsize = 0;
3796 int *blocksizex = &factors->
sizex;
3797 int *blocksizey = &factors->
sizey;
3801 *blocksizex = CLAMP(
nextpow2(*blocksizex), 1, 1 << 16);
3802 *blocksizey = CLAMP(
nextpow2(*blocksizey), 1, 1 << 16);
3807 while(maxsizes[0] < *blocksizex || maxsizes[1] < *blocksizey
3808 || localmemsize < ((factors->
xfactor * (*blocksizex) + factors->
xoffset) *
3810 || workgroupsize < (
size_t)(*blocksizex) * (*blocksizey) || kernelworkgroupsize < (
size_t)(*blocksizex) * (*blocksizey))
3812 if(*blocksizex == 1 && *blocksizey == 1)
return FALSE;
3814 if(*blocksizex > *blocksizey)
3822 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)
void dt_bilateral_init_cl_global(void)
void dt_bilateral_free_cl_global(void)
void dt_develop_blend_free_cl_global(void)
void dt_develop_blend_init_cl_global(void)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_colorspaces_init_cl_global(void)
Compile the colorspace kernels. Called once by common/opencl.c at device init.
void dt_colorspaces_free_cl_global(void)
Release the kernels and the struct from dt_colorspaces_init_cl_global(). NULL-safe.
const dt_colormatrix_t dt_aligned_pixel_t out
void dt_conf_set_bool(const char *name, int val)
int dt_conf_flush(void)
Write the settings to their file now. Overridden keys keep their stored value.
int dt_conf_get_bool(const char *name)
int dt_conf_key_exists(const char *key)
Does key have a value?
gchar * dt_conf_get_string(const char *name)
Read the stored string for name as a private copy.
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
Integer for name, clamped to the bounds declared in the XML.
int64_t dt_conf_get_int64(const char *name)
64-bit integer for name, clamped to its declared bounds.
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
Borrow the stored string for name without copying it.
gboolean dt_conf_key_not_empty(const char *name)
void reset(dt_view_t *self)
size_t dt_get_system_available_mem(void)
void dt_capabilities_remove(char *capability)
void dt_capabilities_add(char *capability)
dt_dlopencl_t * dt_dlopencl_init(const char *name)
GtkWidget * preview
what the selected row actually captures
gboolean enabled
–doc was passed on the command line
static int dt_pthread_mutex_BAD_lock(dt_pthread_mutex_t *mutex)
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)
Initialise a mutex. With mutexattr NULL – which is how 54 of the 56 call sites in this tree spell it ...
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
void dt_dwt_init_cl_global(void)
void dt_dwt_free_cl_global(void)
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(void)
void dt_gaussian_init_cl_global(void)
void dt_guided_filter_init_cl_global(void)
void dt_guided_filter_free_cl_global(void)
void dt_heal_free_cl_global(void)
void dt_heal_init_cl_global(void)
void dt_iop_nap(int32_t usec)
void dt_interpolation_free_cl_global(void)
void dt_interpolation_init_cl_global(void)
static float kernel(const float *x, const float *y)
void dt_local_laplacian_init_cl_global(void)
void dt_local_laplacian_free_cl_global(void)
_lib_location_type_t type
int32_t dt_get_debug_flags(void)
void void dt_print_nts(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
dt_print() without the timestamp prefix (nts = no time stamp).
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
void void void dt_vprint(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
dt_print() that additionally requires DT_DEBUG_VERBOSE to be enabled, i.e. both -d <channel> and -d v...
float *const restrict const size_t k
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
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)
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)
const char * dt_opencl_get_device_name(const int devid)
Human-readable device name, owned by the OpenCL module.
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)
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_events_reset(const int devid)
cl_int dt_opencl_events_flush(const int devid, const int reset)
void dt_opencl_note_crash_backtrace(const char *backtrace, size_t backtrace_len)
Tell the OpenCL module that the process crashed, and let it judge whether the crash was its driver's ...
int dt_opencl_copy_device_to_host(const int devid, void *host, void *device, const int width, const int height, const int bpp)
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)
static const _gpu_runtime_t _gpu_runtimes[]
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)
void dt_opencl_cleanup(void)
static void _opencl_driver_crash_marker_path(char *buf, size_t buf_len)
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)
static char _driver_crash_marker[DT_PATH_MAX]
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 _gpu_runtime_set_crash_streak(const char *runtime, int value)
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_report_pipe_error(void)
Record that a pipe run failed on OpenCL, and decide whether to give up on it.
int dt_opencl_get_image_height(cl_mem mem)
void dt_opencl_reserve_device_by_id(const int devid)
Reserve a device the caller has already identified, blocking until it is free.
size_t dt_opencl_get_device_headroom(const int devid)
Bytes of the device left to other applications (its forced_headroom, from its own config key or memor...
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)
size_t dt_opencl_get_device_memory_in_use(const int devid)
Bytes Ansel holds on the device by its own accounting (dt_opencl_memory_statistics()),...
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)
gboolean dt_opencl_get_device_max_image_size(const int devid, int *width, int *height)
Largest 2D image the device will accept, which is what bounds tile size.
int dt_opencl_set_detected_device_enabled(const int detected, const gboolean enabled)
static const char * _gpu_runtime_of_platform(const char *platform_name)
int dt_opencl_try_reserve_device_by_id(const int devid)
Reserve a device only if it is free right now.
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)
static void _opencl_fold_driver_crashes(void)
void dt_opencl_clear_driver_crash_streak(void)
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)
static void dt_opencl_cleanup_device(dt_opencl_t *cl, int i)
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_reserve_device_for_pipe(const int pipetype)
Reserve a device for a pipe run: choose a free one by the pipe's priority list and take its lock....
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)
gboolean dt_opencl_use_pinned_memory(const int devid)
int dt_opencl_get_image_width(cl_mem mem)
cl_ulong dt_opencl_get_device_memalloc(const int devid)
static dt_opencl_t * _opencl
static int _gpu_runtime_crash_streak(const char *runtime)
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)
size_t dt_opencl_get_device_max_global_mem(const int devid)
Total device memory in bytes, or 0 for an out-of-range id.
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)
void dt_opencl_release_device(const int devid)
Release a device reserved by either reserve function.
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)
static 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)
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)
void dt_opencl_init(const gboolean exclude_opencl, const gboolean print_statistics)
static int _device_by_cname(const char *name)
int dt_opencl_get_image_element_size(cl_mem mem)
int dt_opencl_get_num_devices(void)
Number of usable OpenCL devices; 0 when OpenCL is unavailable.
gboolean dt_opencl_detected_device_enabled(const int detected)
static const char * dt_opencl_get_vendor_by_id(unsigned int id)
gboolean dt_opencl_get_mem_record(cl_mem mem, int *devid, size_t *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_MAX_ERRORS
#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)
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
void dt_concat_path_file(char destination[4096], const char path[4096], const char *const file)
Append a constant filename to a variable, stack-based, fixed-sized, directory, and add a / in-between...
@ DT_DEV_PIXELPIPE_THUMBNAIL
@ DT_DEV_PIXELPIPE_EXPORT
@ DT_DEV_PIXELPIPE_PREVIEW
void dt_dev_pixelpipe_cache_flush_clmem(const int devid)
Release cached OpenCL buffers for a single device.
Pixelpipe cache for storing intermediate results in the pixelpipe.
static const dt_aligned_pixel_simd_t value
void dt_startup_progress_report(const char *format,...)
unsigned __int64 uint64_t
const char *const char * platform
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
int opencl_synchronization_timeout
int * dev_priority_preview
int * dev_priority_export
dt_pthread_mutex_t mem_sizes_lock
dt_opencl_detected_device_t * detected_devs
int * dev_priority_thumbnail
static double dt_get_wtime(void)
gchar * dt_util_str_replace(const gchar *string, const gchar *pattern, const gchar *substitute)