Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
dlopencl.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2011-2012 johannes hanika.
4 Copyright (C) 2011 Moritz Lipp.
5 Copyright (C) 2011-2014, 2016-2017 Ulrich Pegelow.
6 Copyright (C) 2012 Michal Babej.
7 Copyright (C) 2012 parafin.
8 Copyright (C) 2012 Richard Wonka.
9 Copyright (C) 2012-2014, 2016 Tobias Ellinghaus.
10 Copyright (C) 2014, 2016 Roman Lebedev.
11 Copyright (C) 2016-2017 Peter Budai.
12 Copyright (C) 2019 Heiko Bauke.
13 Copyright (C) 2020 Pascal Obry.
14 Copyright (C) 2022 Hanno Schwalm.
15 Copyright (C) 2022 Martin Bařinka.
16 Copyright (C) 2025 Aurélien PIERRE.
17
18 darktable is free software: you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation, either version 3 of the License, or
21 (at your option) any later version.
22
23 darktable is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
27
28 You should have received a copy of the GNU General Public License
29 along with darktable. If not, see <http://www.gnu.org/licenses/>.
30*/
31
32#ifdef HAVE_OPENCL
33
34#include "common/dlopencl.h"
35#include "system/dynload.h"
36#include "common/logging.h"
37#include "system/macros.h"
38#include "system/mem_alloc.h"
39
40#include <assert.h>
41#include <signal.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45
46#if defined(WIN32)
47static const char *ocllib[] = { "OpenCL.dll", NULL };
48#elif defined(__APPLE__)
49static const char *ocllib[] = { "/System/Library/Frameworks/OpenCL.framework/Versions/Current/OpenCL", NULL };
50#else
51static const char *ocllib[] = { "libOpenCL", "libOpenCL.so", "libOpenCL.so.1", NULL };
52#endif
53
54
55/* only for debugging: default noop function for all unassigned function pointers */
57{
58 /* we should normally never get here */
59 fprintf(stderr, "dt_dlopencl internal error: unsupported function call\n");
60 raise(SIGABRT);
61}
62
63
64/* dynamically load OpenCL library and bind needed symbols */
66{
67 dt_gmodule_t *module = NULL;
68 dt_dlopencl_t *ocl;
69 const char *library = NULL;
70 int success;
71
72 /* check if our platform supports gmodules */
73 success = dt_gmodule_supported();
74 if(!success) return NULL;
75
76 /* try to load library. if a name is given check only that library - else iterate over default names. */
77 if(!IS_NULL_PTR(name) && name[0] != '\0')
78 {
79 library = name;
80 module = dt_gmodule_open(library);
81 if(IS_NULL_PTR(module))
82 dt_vprint(DT_DEBUG_OPENCL, "[dt_dlopencl_init] could not find opencl runtime library '%s'\n", library);
83 else
84 dt_vprint(DT_DEBUG_OPENCL, "[dt_dlopencl_init] found opencl runtime library '%s'\n", library);
85 }
86 else
87 {
88 const char **iter = ocllib;
89 while(*iter && (IS_NULL_PTR(module)))
90 {
91 library = *iter;
92 module = dt_gmodule_open(library);
93 if(IS_NULL_PTR(module))
94 dt_vprint(DT_DEBUG_OPENCL, "[dt_dlopencl_init] could not find opencl runtime library '%s'\n", library);
95 else
96 dt_vprint(DT_DEBUG_OPENCL, "[dt_dlopencl_init] found opencl runtime library '%s'\n", library);
97 iter++;
98 }
99 }
100
101 if(IS_NULL_PTR(module))
102 return NULL;
103 else
104 {
105 /* now bind symbols */
106 success = TRUE;
107 ocl = (dt_dlopencl_t *)malloc(sizeof(dt_dlopencl_t));
108
109 if(IS_NULL_PTR(ocl))
110 {
111 dt_free(module);
112 return NULL;
113 }
114
115 ocl->symbols = (dt_dlopencl_symbols_t *)calloc(1, sizeof(dt_dlopencl_symbols_t));
116
117 if(IS_NULL_PTR(ocl->symbols))
118 {
119 dt_free(ocl);
120 dt_free(module);
121 return NULL;
122 }
123
124 ocl->library = module->library;
125
126 /* assign noop function as a default to each function pointer */
127 void (**slist)(void) = (void (**)(void))ocl->symbols;
128 /* sanity check against padding */
129 if(sizeof(dt_dlopencl_symbols_t) % sizeof(void (*)(void)) == 0)
130 for(int k = 0; k < sizeof(dt_dlopencl_symbols_t) / sizeof(void (*)(void)); k++) slist[k] = dt_dlopencl_noop;
131
132 /* only bind needed symbols */
133 success = success && dt_gmodule_symbol(module, "clGetPlatformIDs",
134 (void (**)(void)) & ocl->symbols->dt_clGetPlatformIDs);
135 success = success && dt_gmodule_symbol(module, "clGetPlatformInfo",
136 (void (**)(void)) & ocl->symbols->dt_clGetPlatformInfo);
137 success = success && dt_gmodule_symbol(module, "clGetDeviceIDs",
138 (void (**)(void)) & ocl->symbols->dt_clGetDeviceIDs);
139 success = success && dt_gmodule_symbol(module, "clGetDeviceInfo",
140 (void (**)(void)) & ocl->symbols->dt_clGetDeviceInfo);
141 success = success && dt_gmodule_symbol(module, "clCreateContext",
142 (void (**)(void)) & ocl->symbols->dt_clCreateContext);
143 success = success && dt_gmodule_symbol(module, "clCreateCommandQueue",
144 (void (**)(void)) & ocl->symbols->dt_clCreateCommandQueue);
145 success = success && dt_gmodule_symbol(module, "clCreateProgramWithSource",
146 (void (**)(void)) & ocl->symbols->dt_clCreateProgramWithSource);
147 success = success && dt_gmodule_symbol(module, "clBuildProgram",
148 (void (**)(void)) & ocl->symbols->dt_clBuildProgram);
149 success = success && dt_gmodule_symbol(module, "clGetProgramBuildInfo",
150 (void (**)(void)) & ocl->symbols->dt_clGetProgramBuildInfo);
151 success = success && dt_gmodule_symbol(module, "clCreateKernel",
152 (void (**)(void)) & ocl->symbols->dt_clCreateKernel);
153 success = success && dt_gmodule_symbol(module, "clCreateBuffer",
154 (void (**)(void)) & ocl->symbols->dt_clCreateBuffer);
155 success = success && dt_gmodule_symbol(module, "clCreateImage2D",
156 (void (**)(void)) & ocl->symbols->dt_clCreateImage2D);
157 success = success && dt_gmodule_symbol(module, "clEnqueueWriteBuffer",
158 (void (**)(void)) & ocl->symbols->dt_clEnqueueWriteBuffer);
159 success = success && dt_gmodule_symbol(module, "clSetKernelArg",
160 (void (**)(void)) & ocl->symbols->dt_clSetKernelArg);
161 success = success && dt_gmodule_symbol(module, "clGetKernelWorkGroupInfo",
162 (void (**)(void)) & ocl->symbols->dt_clGetKernelWorkGroupInfo);
163 success = success && dt_gmodule_symbol(module, "clEnqueueNDRangeKernel",
164 (void (**)(void)) & ocl->symbols->dt_clEnqueueNDRangeKernel);
165 success = success && dt_gmodule_symbol(module, "clEnqueueReadImage",
166 (void (**)(void)) & ocl->symbols->dt_clEnqueueReadImage);
167 success = success && dt_gmodule_symbol(module, "clEnqueueWriteImage",
168 (void (**)(void)) & ocl->symbols->dt_clEnqueueWriteImage);
169 success = success && dt_gmodule_symbol(module, "clEnqueueCopyImage",
170 (void (**)(void)) & ocl->symbols->dt_clEnqueueCopyImage);
171 success = success && dt_gmodule_symbol(module, "clEnqueueCopyImageToBuffer",
172 (void (**)(void)) & ocl->symbols->dt_clEnqueueCopyImageToBuffer);
173 success = success && dt_gmodule_symbol(module, "clEnqueueCopyBufferToImage",
174 (void (**)(void)) & ocl->symbols->dt_clEnqueueCopyBufferToImage);
175 success = success && dt_gmodule_symbol(module, "clFinish", (void (**)(void)) & ocl->symbols->dt_clFinish);
176 success = success && dt_gmodule_symbol(module, "clEnqueueReadBuffer",
177 (void (**)(void)) & ocl->symbols->dt_clEnqueueReadBuffer);
178 success = success && dt_gmodule_symbol(module, "clReleaseMemObject",
179 (void (**)(void)) & ocl->symbols->dt_clReleaseMemObject);
180 success = success && dt_gmodule_symbol(module, "clReleaseProgram",
181 (void (**)(void)) & ocl->symbols->dt_clReleaseProgram);
182 success = success && dt_gmodule_symbol(module, "clReleaseKernel",
183 (void (**)(void)) & ocl->symbols->dt_clReleaseKernel);
184 success = success && dt_gmodule_symbol(module, "clReleaseCommandQueue",
185 (void (**)(void)) & ocl->symbols->dt_clReleaseCommandQueue);
186 success = success && dt_gmodule_symbol(module, "clReleaseContext",
187 (void (**)(void)) & ocl->symbols->dt_clReleaseContext);
188 success = success && dt_gmodule_symbol(module, "clReleaseEvent",
189 (void (**)(void)) & ocl->symbols->dt_clReleaseEvent);
190 success = success && dt_gmodule_symbol(module, "clWaitForEvents",
191 (void (**)(void)) & ocl->symbols->dt_clWaitForEvents);
192 success = success && dt_gmodule_symbol(module, "clGetEventInfo",
193 (void (**)(void)) & ocl->symbols->dt_clGetEventInfo);
194 success = success && dt_gmodule_symbol(module, "clGetEventProfilingInfo",
195 (void (**)(void)) & ocl->symbols->dt_clGetEventProfilingInfo);
196 success = success && dt_gmodule_symbol(module, "clGetKernelInfo",
197 (void (**)(void)) & ocl->symbols->dt_clGetKernelInfo);
198 success = success && dt_gmodule_symbol(module, "clEnqueueBarrier",
199 (void (**)(void)) & ocl->symbols->dt_clEnqueueBarrier);
200 success = success && dt_gmodule_symbol(module, "clFlush",
201 (void (**)(void)) & ocl->symbols->dt_clFlush);
202 success = success && dt_gmodule_symbol(module, "clGetKernelWorkGroupInfo",
203 (void (**)(void)) & ocl->symbols->dt_clGetKernelWorkGroupInfo);
204 success = success && dt_gmodule_symbol(module, "clEnqueueReadBuffer",
205 (void (**)(void)) & ocl->symbols->dt_clEnqueueReadBuffer);
206 success = success && dt_gmodule_symbol(module, "clEnqueueWriteBuffer",
207 (void (**)(void)) & ocl->symbols->dt_clEnqueueWriteBuffer);
208 success = success && dt_gmodule_symbol(module, "clGetProgramInfo",
209 (void (**)(void)) & ocl->symbols->dt_clGetProgramInfo);
210 success = success && dt_gmodule_symbol(module, "clCreateProgramWithBinary",
211 (void (**)(void)) & ocl->symbols->dt_clCreateProgramWithBinary);
212 success = success && dt_gmodule_symbol(module, "clEnqueueCopyBuffer",
213 (void (**)(void)) & ocl->symbols->dt_clEnqueueCopyBuffer);
214 success = success && dt_gmodule_symbol(module, "clEnqueueMapBuffer",
215 (void (**)(void)) & ocl->symbols->dt_clEnqueueMapBuffer);
216 success = success && dt_gmodule_symbol(module, "clEnqueueMapImage",
217 (void (**)(void)) & ocl->symbols->dt_clEnqueueMapImage);
218 success = success && dt_gmodule_symbol(module, "clEnqueueUnmapMemObject",
219 (void (**)(void)) & ocl->symbols->dt_clEnqueueUnmapMemObject);
220 success = success && dt_gmodule_symbol(module, "clGetMemObjectInfo",
221 (void (**)(void)) & ocl->symbols->dt_clGetMemObjectInfo);
222 success = success && dt_gmodule_symbol(module, "clGetImageInfo",
223 ((void (**)(void)) & ocl->symbols->dt_clGetImageInfo));
224
225 ocl->have_opencl = success;
226
227 if(!success)
228 dt_print(DT_DEBUG_OPENCL, "[opencl_init] could not load all required symbols from library\n");
229 }
230
231 dt_free(module);
232
233 if(!success)
234 {
235 dt_free(ocl->symbols);
236 dt_free(ocl);
237 return NULL;
238 }
239
240 return ocl;
241}
242
243#endif
244
245// clang-format off
246// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
247// vim: shiftwidth=2 expandtab tabstop=2 cindent
248// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
249// clang-format on
#define TRUE
Definition ashift_lsd.c:162
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
static const char * ocllib[]
Definition dlopencl.c:49
void dt_dlopencl_noop(void)
Definition dlopencl.c:56
dt_dlopencl_t * dt_dlopencl_init(const char *name)
Definition dlopencl.c:65
int dt_gmodule_symbol(dt_gmodule_t *module, const char *name, void(**pointer)(void))
Definition dynload.c:115
int dt_gmodule_supported(void)
APPLE
Definition dynload.c:92
@ DT_DEBUG_OPENCL
Definition logging.h:57
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...
Definition macros.h:96
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
Definition mem_alloc.h:171
const char * name
Definition pdf.h:90
APPLE
Definition dynload.h:40