15
15
You should have received a copy of the GNU General Public License
16
16
along with darktable. If not, see <http://www.gnu.org/licenses/>.
21
24
#include "common/darktable.h"
22
25
#include "common/opencl.h"
26
#include "common/dlopencl.h"
27
#include "control/conf.h"
24
29
void dt_opencl_init(dt_opencl_t *cl, const int argc, char *argv[])
26
31
dt_pthread_mutex_init(&cl->lock, NULL);
35
int exclude_opencl = 0;
37
// preliminary disable opencl in prefs. We will re-set it to previous state later if possible
38
// Will remain disabled if initialization fails.
39
const int prefs = dt_conf_get_bool("opencl");
40
dt_conf_set_bool("opencl", FALSE);
28
42
for(int k=0; k<argc; k++) if(!strcmp(argv[k], "--disable-opencl"))
30
dt_print(DT_DEBUG_OPENCL, "[opencl_init] not using opencl by explicit request\n");
44
dt_print(DT_DEBUG_OPENCL, "[opencl_init] do not try to find and use an opencl runtime library due to explicit user request\n");
48
if(exclude_opencl) return;
51
// look for explicit definition of opencl_runtime library in preferences
52
const char *library = dt_conf_get_string("opencl_runtime");
53
dt_print(DT_DEBUG_OPENCL, "[opencl_init] trying to load opencl library: %s\n", library && strlen(library) != 0 ? library : "<system default>");
55
// dynamically load opencl runtime
56
if(!dt_dlopencl_init(library, &cl->dlocl))
58
dt_print(DT_DEBUG_OPENCL, "[opencl_init] no working opencl library found. Continue with opencl disabled\n");
63
dt_print(DT_DEBUG_OPENCL, "[opencl_init] opencl library %s found on your system and loaded\n", cl->dlocl->library);
34
67
cl_platform_id all_platforms[5];
35
68
cl_platform_id platform = NULL;
36
69
cl_uint num_platforms = 5;
37
err = clGetPlatformIDs (5, all_platforms, &num_platforms);
70
err = (cl->dlocl->symbols->dt_clGetPlatformIDs) (5, all_platforms, &num_platforms);
38
71
if(err != CL_SUCCESS)
40
73
dt_print(DT_DEBUG_OPENCL, "[opencl_init] could not get platforms: %d\n", err);
55
88
// create the device list
56
cl->num_devs = num_devices;
57
89
cl->dev = (dt_opencl_device_t *)malloc(sizeof(dt_opencl_device_t)*num_devices);
58
90
cl_device_id *devices = (cl_device_id *)malloc(sizeof(cl_device_id)*num_devices);
59
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
91
err = (cl->dlocl->symbols->dt_clGetDeviceIDs)(platform, CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
60
92
if(err != CL_SUCCESS)
62
94
dt_print(DT_DEBUG_OPENCL, "[opencl_init] could not get devices list: %d\n", err);
65
97
dt_print(DT_DEBUG_OPENCL, "[opencl_init] found %d devices\n", num_devices);
66
99
for(int k=0; k<num_devices; k++)
68
memset(cl->dev[k].program_used, 0x0, sizeof(int)*DT_OPENCL_MAX_PROGRAMS);
69
memset(cl->dev[k].kernel_used, 0x0, sizeof(int)*DT_OPENCL_MAX_KERNELS);
70
cl->dev[k].devid = devices[k];
101
memset(cl->dev[dev].program_used, 0x0, sizeof(int)*DT_OPENCL_MAX_PROGRAMS);
102
memset(cl->dev[dev].kernel_used, 0x0, sizeof(int)*DT_OPENCL_MAX_KERNELS);
103
cl_device_id devid = cl->dev[dev].devid = devices[k];
72
105
char infostr[1024];
74
107
size_t infointtab[1024];
75
108
cl_bool image_support = 0;
76
109
cl_ulong max_global_mem = 0;
77
size_t image_width = 0, image_height = 0;
110
//size_t image_width = 0, image_height = 0;
79
112
// test 1GB mem and image support:
80
clGetDeviceInfo(cl->dev[k].devid, CL_DEVICE_NAME, sizeof(infostr), &infostr, NULL);
81
clGetDeviceInfo(cl->dev[k].devid, CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), &image_support, NULL);
82
clGetDeviceInfo(cl->dev[k].devid, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof(size_t), &image_height, NULL);
83
clGetDeviceInfo(cl->dev[k].devid, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &image_width, NULL);
113
(cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_NAME, sizeof(infostr), &infostr, NULL);
114
(cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), &image_support, NULL);
115
(cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof(size_t), &(cl->dev[dev].max_image_height), NULL);
116
(cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &(cl->dev[dev].max_image_width), NULL);
84
117
if(!image_support)
86
cl->num_devs = --num_devices;
87
119
dt_print(DT_DEBUG_OPENCL, "[opencl_init] discarding device %d `%s' due to missing image support.\n", k, infostr);
90
if(image_height < 8192 || image_width < 8192)
92
fprintf(stderr, "[opencl_init] WARNING: your card only supports image sizes of %zd x %zd\n", image_width, image_height);
93
fprintf(stderr, "[opencl_init] WARNING: expect random crashes, especially with images larger than that.\n");
122
//if(image_height < 8192 || image_width < 8192)
124
// fprintf(stderr, "[opencl_init] WARNING: your card only supports image sizes of %zd x %zd\n", image_width, image_height);
125
// fprintf(stderr, "[opencl_init] WARNING: expect random crashes, especially with images larger than that.\n");
96
clGetDeviceInfo(cl->dev[k].devid, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(cl_ulong), &max_global_mem, NULL);
128
(cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(cl_ulong), &max_global_mem, NULL);
97
129
if(max_global_mem < 1000000000ul)
99
cl->num_devs = --num_devices;
100
dt_print(DT_DEBUG_OPENCL, "[opencl_init] discarding device %d `%s' due to insufficient global memory.\n", k, infostr);
131
dt_print(DT_DEBUG_OPENCL, "[opencl_init] discarding device %d `%s' due to insufficient global memory (%luMB).\n", k, infostr, max_global_mem/1024/1024);
103
134
if(darktable.unmuted & DT_DEBUG_OPENCL)
105
136
printf("[opencl_init] device %d: %s \n", k, infostr);
106
clGetDeviceInfo(cl->dev[k].devid, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(infoint), &infoint, NULL);
137
(cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(infoint), &infoint, NULL);
107
138
printf(" MAX_WORK_GROUP_SIZE: %zd\n", infoint);
108
clGetDeviceInfo(cl->dev[k].devid, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(infoint), &infoint, NULL);
139
(cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(infoint), &infoint, NULL);
109
140
printf(" MAX_WORK_ITEM_DIMENSIONS: %zd\n", infoint);
110
141
printf(" MAX_WORK_ITEM_SIZES: [ ");
111
clGetDeviceInfo(cl->dev[k].devid, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(infointtab), infointtab, NULL);
142
(cl->dlocl->symbols->dt_clGetDeviceInfo)(devid, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(infointtab), infointtab, NULL);
112
143
for (int i=0; i<infoint; i++) printf("%zd ", infointtab[i]);
115
dt_pthread_mutex_init(&cl->dev[k].lock, NULL);
146
dt_pthread_mutex_init(&cl->dev[dev].lock, NULL);
117
cl->dev[k].context = clCreateContext(0, 1, &cl->dev[k].devid, NULL, NULL, &err);
148
cl->dev[dev].context = (cl->dlocl->symbols->dt_clCreateContext)(0, 1, &devid, NULL, NULL, &err);
118
149
if(err != CL_SUCCESS)
120
151
dt_print(DT_DEBUG_OPENCL, "[opencl_init] could not create context for device %d: %d\n", k, err);
123
154
// create a command queue for first device the context reported
124
cl->dev[k].cmd_queue = clCreateCommandQueue(cl->dev[k].context, cl->dev[k].devid, 0, &err);
155
cl->dev[dev].cmd_queue = (cl->dlocl->symbols->dt_clCreateCommandQueue)(cl->dev[dev].context, devid, 0, &err);
125
156
if(err != CL_SUCCESS)
127
158
dt_print(DT_DEBUG_OPENCL, "[opencl_init] could not create command queue for device %d: %d\n", k, err);
280
332
if(prog < 0 || prog >= DT_OPENCL_MAX_PROGRAMS) return -1;
281
333
cl_program program = cl->dev[dev].program[prog];
283
err = clBuildProgram(program, 1, &cl->dev[dev].devid, "-cl-fast-relaxed-math -cl-strict-aliasing", 0, 0);
335
err = (cl->dlocl->symbols->dt_clBuildProgram)(program, 1, &cl->dev[dev].devid, "-cl-fast-relaxed-math -cl-strict-aliasing", 0, 0);
284
336
if(err != CL_SUCCESS)
286
338
dt_print(DT_DEBUG_OPENCL, "[opencl_build_program] could not build program: %d\n", err);
287
339
cl_build_status build_status;
288
clGetProgramBuildInfo(program, cl->dev[dev].devid, CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &build_status, NULL);
340
(cl->dlocl->symbols->dt_clGetProgramBuildInfo)(program, cl->dev[dev].devid, CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &build_status, NULL);
289
341
if (build_status != CL_SUCCESS)
292
344
size_t ret_val_size;
293
clGetProgramBuildInfo(program, cl->dev[dev].devid, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
345
(cl->dlocl->symbols->dt_clGetProgramBuildInfo)(program, cl->dev[dev].devid, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
294
346
build_log = (char *)malloc(sizeof(char)*(ret_val_size+1));
295
clGetProgramBuildInfo(program, cl->dev[dev].devid, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
347
(cl->dlocl->symbols->dt_clGetProgramBuildInfo)(program, cl->dev[dev].devid, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
297
349
build_log[ret_val_size] = '\0';
377
432
// const size_t local[2] = {16, 16};
378
433
// let the driver choose:
379
434
const size_t *local = NULL;
380
return clEnqueueNDRangeKernel(cl->dev[dev].cmd_queue, cl->dev[dev].kernel[kernel], 2, NULL, sizes, local, 0, NULL, NULL);
435
return (cl->dlocl->symbols->dt_clEnqueueNDRangeKernel)(cl->dev[dev].cmd_queue, cl->dev[dev].kernel[kernel], 2, NULL, sizes, local, 0, NULL, NULL);
383
void dt_opencl_copy_device_to_host(void *host, void *device, const int width, const int height, const int devid, const int bpp)
438
int dt_opencl_copy_device_to_host(void *host, void *device, const int width, const int height, const int devid, const int bpp)
385
if(!darktable.opencl->inited) return;
440
if(!darktable.opencl->inited) return -1;
386
441
size_t origin[] = {0, 0, 0};
387
442
size_t region[] = {width, height, 1};
389
clEnqueueReadImage(darktable.opencl->dev[devid].cmd_queue, device, CL_TRUE, origin, region, region[0]*bpp, 0, host, 0, NULL, NULL);
444
return (darktable.opencl->dlocl->symbols->dt_clEnqueueReadImage)(darktable.opencl->dev[devid].cmd_queue, device, CL_TRUE, origin, region, region[0]*bpp, 0, host, 0, NULL, NULL);
447
int dt_opencl_enqueue_copy_image(cl_command_queue q, cl_mem src, cl_mem dst, size_t *orig_src, size_t *orig_dst, size_t *region, int events, cl_event *wait, cl_event *event)
449
if(!darktable.opencl->inited) return -1;
451
err = (darktable.opencl->dlocl->symbols->dt_clEnqueueCopyImage)(q, src, dst, orig_src, orig_dst, region, events, wait, event);
452
if(err != CL_SUCCESS) dt_print(DT_DEBUG_OPENCL, "[opencl copy_image] could not copy image: %d\n", err);
392
456
void* dt_opencl_copy_host_to_device_constant(const int size, const int devid, void *host)
394
458
if(!darktable.opencl->inited) return NULL;
396
cl_mem dev = clCreateBuffer (darktable.opencl->dev[devid].context,
460
cl_mem dev = (darktable.opencl->dlocl->symbols->dt_clCreateBuffer) (darktable.opencl->dev[devid].context,
397
461
CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR,
400
if(err != CL_SUCCESS) fprintf(stderr, "[opencl alloc_device] could not alloc img buffer on device %d: %d\n", devid, err);
464
if(err != CL_SUCCESS) dt_print(DT_DEBUG_OPENCL, "[opencl copy_host_to_device_constant] could not alloc buffer on device %d: %d\n", devid, err);
458
530
else return NULL;
460
cl_mem dev = clCreateImage2D (darktable.opencl->dev[devid].context,
532
cl_mem dev = (darktable.opencl->dlocl->symbols->dt_clCreateImage2D) (darktable.opencl->dev[devid].context,
461
533
CL_MEM_READ_WRITE,
463
535
width, height, 0,
465
if(err != CL_SUCCESS) fprintf(stderr, "[opencl alloc_device] could not alloc img buffer on device %d: %d\n", devid, err);
537
if(err != CL_SUCCESS) dt_print(DT_DEBUG_OPENCL, "[opencl alloc_device] could not alloc img buffer on device %d: %d\n", devid, err);
542
/** check if image size fit into limits given by OpenCL runtime */
543
int dt_opencl_image_fits_device(const int devid, const size_t width, const size_t height)
545
if(!darktable.opencl->inited) return FALSE;
547
return (darktable.opencl->dev[devid].max_image_width >= width && darktable.opencl->dev[devid].max_image_height >= height);
551
/** check if opencl is inited */
552
int dt_opencl_is_inited(void)
554
return darktable.opencl->inited;
558
/** check if opencl is enabled */
559
int dt_opencl_is_enabled(void)
561
if(!darktable.opencl->inited) return FALSE;
562
return darktable.opencl->enabled;
566
/** disable opencl */
567
void dt_opencl_disable(void)
569
if(!darktable.opencl->inited) return;
570
darktable.opencl->enabled = FALSE;
571
dt_conf_set_bool("opencl", FALSE);
575
/** update enabled flag with value from preferences */
576
void dt_opencl_update_enabled(void)
578
if(!darktable.opencl->inited) return;
579
const int prefs = dt_conf_get_bool("opencl");
581
//printf("[opencl_update_enabled] preferences is set to %d\n", prefs);
583
if (darktable.opencl->enabled != prefs)
585
darktable.opencl->enabled = prefs;
586
dt_print(DT_DEBUG_OPENCL, "[opencl_update_enabled] enabled flag set to %s\n", prefs ? "ON" : "OFF");