2 Copyright (c) 2012-2015, Brice Videau <brice.videau@imag.fr>
3 Copyright (c) 2012-2015, Vincent Danjean <Vincent.Danjean@ens-lyon.org>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice, this
10 list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright notice,
12 this list of conditions and the following disclaimer in the documentation
13 and/or other materials provided with the distribution.
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 $api_entries_array = []
33 $cl_objects = ["platform_id", "device_id", "context", "command_queue", "mem", "program", "kernel", "event", "sampler"]
34 $know_entries = { 1 => "clGetPlatformInfo", 0 => "clGetPlatformIDs", 2 => "clGetDeviceIDs" }
35 $use_name_in_test = { 1 => "clGetPlatformInfo", 0 => "clGetPlatformIDs", 2 => "clGetDeviceIDs" }
36 # do not call these functions when trying to discover the mapping
38 "clUnloadCompiler", # No parameters so no way to forward to an ICD, OpenCL 1.0
39 "clGetPlatformIDs", # Implemented directly within the ICD Loader, not forwarded to ICD
41 # windows function to ignore when loading the database
42 $windows_funcs = ["clGetDeviceIDsFromD3D10KHR", "clCreateFromD3D10BufferKHR",
43 "clCreateFromD3D10Texture2DKHR", "clCreateFromD3D10Texture3DKHR",
44 "clEnqueueAcquireD3D10ObjectsKHR", "clEnqueueReleaseD3D10ObjectsKHR",
45 "clGetDeviceIDsFromD3D11KHR", "clCreateFromD3D11BufferKHR",
46 "clCreateFromD3D11Texture2DKHR", "clCreateFromD3D11Texture3DKHR",
47 "clEnqueueAcquireD3D11ObjectsKHR", "clEnqueueReleaseD3D11ObjectsKHR",
48 "clGetDeviceIDsFromDX9MediaAdapterKHR", "clCreateFromDX9MediaSurfaceKHR",
49 "clEnqueueAcquireDX9MediaSurfacesKHR", "clEnqueueReleaseDX9MediaSurfacesKHR"]
50 # do not create weak functions for these ones in the discovering program
51 $noweak_funcs = ["clGetExtensionFunctionAddress", "clGetPlatformIDs",
52 "clGetPlatformInfo", "clGetGLContextInfoKHR", "clUnloadCompiler",
53 "clCreateContext", "clCreateContextFromType", "clWaitForEvents"]
54 # functions written specifically in the loader
55 $specific_loader_funcs = ["clGetExtensionFunctionAddress","clGetPlatformIDs",
56 "clGetGLContextInfoKHR", "clUnloadCompiler",
57 "clCreateContext", "clCreateContextFromType", "clWaitForEvents"]
58 $header_files = ["/usr/include/CL/cl.h", "/usr/include/CL/cl_gl.h", "/usr/include/CL/cl_egl.h",
59 "/usr/include/CL/cl_ext.h", "/usr/include/CL/cl_gl_ext.h"]
60 $windows_header_files = ["/usr/include/CL/cl_dx9_media_sharing.h", "/usr/include/CL/cl_d3d11.h", "/usr/include/CL/cl_d3d10.h"]
61 $cl_data_type_error = { "cl_platform_id" => "CL_INVALID_PLATFORM",
62 "cl_device_id" => "CL_INVALID_DEVICE",
63 "cl_context" => "CL_INVALID_CONTEXT",
64 "cl_command_queue" => "CL_INVALID_COMMAND_QUEUE",
65 "cl_mem" => "CL_INVALID_MEM_OBJECT",
66 "cl_program" => "CL_INVALID_PROGRAM",
67 "cl_kernel" => "CL_INVALID_KERNEL",
68 "cl_event" => "CL_INVALID_EVENT",
69 "cl_sampler" => "CL_INVALID_SAMPLER"}
70 $non_standard_error = [ "clGetExtensionFunctionAddressForPlatform", "clSVMAlloc" ]
71 $versions_entries = []
74 Copyright (c) 2012-2015, Brice Videau <brice.videau@imag.fr>
75 Copyright (c) 2012-2015, Vincent Danjean <Vincent.Danjean@ens-lyon.org>
78 Redistribution and use in source and binary forms, with or without
79 modification, are permitted provided that the following conditions are met:
81 1. Redistributions of source code must retain the above copyright notice, this
82 list of conditions and the following disclaimer.
83 2. Redistributions in binary form must reproduce the above copyright notice,
84 this list of conditions and the following disclaimer in the documentation
85 and/or other materials provided with the distribution.
87 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
88 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
91 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98 Do not edit this file. It is automatically generated.
101 ##########################################################
102 ##########################################################
104 def self.parse_headers
106 $header_files.each{ |fname|
107 f = File::open(fname)
109 api_entries += doc.scan(/CL_API_ENTRY.*?;/m)
112 api_entries.each{ |entry|
115 entry_name = entry.match(/CL_API_CALL(.*?)\(/m)[1].strip
117 entry_name = entry.match(/(\S*?)\(/m)[1].strip
119 next if entry_name.match('\*')
120 next if entry_name.match("INTEL")
121 next if entry_name.match("APPLE")
122 $api_entries[entry_name] = entry.gsub("\r","")
124 # $api_entries.each{ |key, value|
125 # puts "#{key}: #{value}"
129 def self.load_database(yamlfile, with_windows=false)
130 doc = YAML::load_file(yamlfile)
133 $versions_entries = Hash::new { |hash,key| hash[key]=[] }
136 doc.each { |key, value|
137 #puts (key.to_s+":: "+value)
139 entry_name = value.match(/CL_API_CALL(.*?)\(/m)[1].strip
141 entry_name = value.match(/(\S*?)\(/m)[1].strip
143 next if (!with_windows) && $windows_funcs.include?(entry_name)
144 version = value.match(/SUFFIX__VERSION_(\d_\d)/m)[1]
145 $versions_entries[version].push(entry_name)
146 $known_entries[key] = entry_name
147 $key_entries[entry_name] = key
148 $api_entries[entry_name] = value
150 $api_entries_array = []
151 ($known_entries.length+$buff).times { |i|
152 #puts (i.to_s+": "+$known_entries[i])
153 if $known_entries[i] then
154 $api_entries_array.push( $api_entries[$known_entries[i]] )
156 $api_entries_array.push( "CL_API_ENTRY cl_int CL_API_CALL clUnknown#{i}(void);" )
161 def self.include_headers
163 $header_files.each { |h|
164 if h.match('^/usr/include/') then
165 headers += "#include <#{h[13..-1]}>\n"
167 headers += "#include \"#{h}\"\n"
173 ##########################################################
174 ##########################################################
176 def self.generate_libdummy_icd_header
177 libdummy_icd_structures = "/**\n#{$license}\n*/\n"
178 libdummy_icd_structures += "#include <CL/opencl.h>\n"
179 libdummy_icd_structures += self.include_headers
180 libdummy_icd_structures += "\n\nstruct _cl_icd_dispatch;\n"
181 libdummy_icd_structures += "struct _cl_platform_id { struct _cl_icd_dispatch *dispatch; };\n\n"
182 libdummy_icd_structures += "struct _cl_icd_dispatch {\n"
183 ($api_entries.length+$buff).times { |i|
184 if( $known_entries[i] ) then
185 libdummy_icd_structures += " void(*known#{i})(void);\n"
187 libdummy_icd_structures += " void(*unknown#{i})(void);\n"
190 libdummy_icd_structures += "};\n\n"
191 libdummy_icd_structures += "#pragma GCC visibility push(hidden)\n\n"
192 libdummy_icd_structures += "struct _cl_icd_dispatch master_dispatch; \n\n"
193 $use_name_in_test.each { |k, f|
194 libdummy_icd_structures += "typeof(#{f}) INT#{f};\n"
196 libdummy_icd_structures += "#pragma GCC visibility pop\n\n"
197 return libdummy_icd_structures
200 def self.generate_libdummy_icd_source
201 libdummy_icd_source = "/**\n#{$license}\n*/\n\n"
202 libdummy_icd_source += "#include <stdio.h>\n\n"
203 libdummy_icd_source += "#include \"libdummy_icd_gen.h\"\n\n"
204 libdummy_icd_source += "#include \"libdummy_icd.h\"\n\n"
205 (0...$api_entries.length+$buff).each { |i|
206 libdummy_icd_source += "void dummyFunc#{i}(void){ printf(\"#{i} : \"); fflush(NULL); }\n"
208 libdummy_icd_source += "\nstruct _cl_icd_dispatch master_dispatch = {\n"
210 ($api_entries.length+$buff).times { |i|
211 comma="" if (i == $api_entries.length+$buff-1)
212 if( $use_name_in_test[i] ) then
213 libdummy_icd_source += " (void(*)(void))& INT#{$known_entries[i]}#{comma}\n"
215 libdummy_icd_source += " (void(*)(void))& dummyFunc#{i}#{comma}\n"
218 libdummy_icd_source += "};\n"
219 return libdummy_icd_source
222 def self.generate_run_dummy_icd_source
223 run_dummy_icd = "/**\n#{$license}\n*/\n"
224 run_dummy_icd += "#include <stdlib.h>\n"
225 run_dummy_icd += "#include <stdio.h>\n"
226 run_dummy_icd += "#pragma GCC diagnostic push\n"
227 run_dummy_icd += "# pragma GCC diagnostic ignored \"-Wcpp\"\n"
228 run_dummy_icd += "# define CL_USE_DEPRECATED_OPENCL_1_0_APIS\n"
229 run_dummy_icd += "# define CL_USE_DEPRECATED_OPENCL_1_1_APIS\n"
230 run_dummy_icd += "# define CL_USE_DEPRECATED_OPENCL_1_2_APIS\n"
231 run_dummy_icd += "# include <CL/opencl.h>\n"
232 run_dummy_icd += self.include_headers
233 run_dummy_icd += "#pragma GCC diagnostic pop\n"
234 run_dummy_icd += "\n\n"
235 $api_entries.each_key { |func_name|
236 next if $forbidden_funcs.include?(func_name)
237 run_dummy_icd += $api_entries[func_name]+";\n"
239 run_dummy_icd += "\n\n"
240 run_dummy_icd += "void call_all_OpenCL_functions(cl_platform_id chosen_platform) {\n"
241 run_dummy_icd += " cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)chosen_platform, 0 };\n"
242 $api_entries.each_key { |func_name|
243 next if $forbidden_funcs.include?(func_name)
244 if func_name == "clCreateContext" then
245 run_dummy_icd += " #{func_name}(properties,1,(cl_device_id*)&chosen_platform,NULL,NULL,NULL);\n"
246 elsif func_name == "clGetGLContextInfoKHR" then
247 run_dummy_icd += " #{func_name}(properties,CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, 0, NULL, NULL);\n"
248 elsif func_name == "clCreateContextFromType" then
249 run_dummy_icd += " #{func_name}(properties,CL_DEVICE_TYPE_CPU,NULL,NULL,NULL);\n"
250 elsif func_name == "clWaitForEvents" then
251 run_dummy_icd += " #{func_name}(1,(cl_event*)&chosen_platform);\n"
252 elsif func_name == "clGetExtensionFunctionAddress" then
253 run_dummy_icd += " #{func_name}(\"extLIG\");\n"
254 elsif func_name == "clGetExtensionFunctionAddressForPlatform" then
255 run_dummy_icd += " #{func_name}((cl_platform_id )chosen_platform,\"extLIG\");\n"
256 elsif func_name == "clUnloadCompiler" then
257 run_dummy_icd += " #{func_name}();\n"
259 params = $api_entries[func_name].gsub(/[[:space:]]+/, ' ')
260 params.gsub!(/[\/][*](([^*]*)[*][^\/])*[^*]*[*][\/]/,'')
261 params.gsub!(/^[^(]*[(] *(.*[^ ]) *[)][^)]*$/, '\1')
262 params = params.gsub(/[^,(]+([(][^)]*[)])*[^,]*/) { |p|
264 p.gsub!("user_func", "")
265 if false && p.match(/[*]/) then
271 if func_name != "clGetPlatformIDs" then
272 params.gsub!(/^([^0]*)0/, '\1chosen_platform')
274 run_dummy_icd += " #{func_name}(#{params});\n"
276 run_dummy_icd += " printf(\"%s\\n\", \"#{func_name}\");\n"
277 run_dummy_icd += "#ifdef OCL_ICD_PRINT_EXPECTED\n"
278 run_dummy_icd += " printf(\"#{$key_entries[func_name]} : %s (expected)\\n\", \"#{func_name}\");\n"
279 run_dummy_icd += "#endif\n"
280 run_dummy_icd += " fflush(NULL);\n"
282 run_dummy_icd += " return;\n}\n"
286 def self.generate_run_dummy_icd_weak_source
287 run_dummy_icd_weak = "/**\n#{$license}\n*/\n"
288 run_dummy_icd_weak += <<EOF
289 #define _GNU_SOURCE 1
294 run_dummy_icd_weak += "#pragma GCC diagnostic push\n"
295 run_dummy_icd_weak += "# pragma GCC diagnostic ignored \"-Wcpp\"\n"
296 run_dummy_icd_weak += "# define CL_USE_DEPRECATED_OPENCL_1_0_APIS\n"
297 run_dummy_icd_weak += "# define CL_USE_DEPRECATED_OPENCL_1_1_APIS\n"
298 run_dummy_icd_weak += "# define CL_USE_DEPRECATED_OPENCL_1_2_APIS\n"
299 run_dummy_icd_weak += "# include <CL/opencl.h>\n"
300 run_dummy_icd_weak += self.include_headers
301 run_dummy_icd_weak += "#pragma GCC diagnostic pop\n"
303 $api_entries.each { |func_name, entry|
304 next if $noweak_funcs.include?(func_name)
305 clean_entry = entry.sub(/(.*\)).*/m,'\1').gsub("/*","").gsub("*/","").gsub("\r","") + "{\n"
306 return_type = entry.match(/CL_API_ENTRY (.*) CL_API_CALL/)[1]
307 parameters = clean_entry.match(/\(.*\)/m)[0][1..-2]
308 parameters.gsub!(/\[.*?\]/,"")
309 parameters.sub!(/\(.*?\*\s*(.*?)\)\s*\(.*?\)/m,'\1')
310 run_dummy_icd_weak += clean_entry.gsub(/\*\[.*?\]/,"* ").gsub(/\[.+?\]/,"")
311 first_parameter = parameters.match(/.*?\,/m)
312 if not first_parameter then
313 first_parameter = parameters.match(/.*/m)[0]
315 first_parameter = first_parameter[0][0..-2]
317 fps = first_parameter.split
318 run_dummy_icd_weak += " void (*p)()=dlsym(RTLD_NEXT, \"#{func_name}\");\n"
319 ps = parameters.split(",")
320 ps = ps.collect { |p|
322 p = p[-1].gsub("*","")
325 run_dummy_icd_weak += " if(p) {\n"
326 run_dummy_icd_weak += " return((*(typeof(#{func_name})*)p)("
327 run_dummy_icd_weak += ps.join(", ")
328 run_dummy_icd_weak += "));\n"
329 run_dummy_icd_weak += " } else {\n"
330 run_dummy_icd_weak += " printf(\"-1 : \");\n"
331 run_dummy_icd_weak += " return (#{return_type})0;\n"
332 run_dummy_icd_weak += " }\n"
333 run_dummy_icd_weak += "}\n\n"
335 return run_dummy_icd_weak
338 def self.generate_sources(from_headers=true, from_database=false, database=nil)
342 if from_database then
343 load_database(database)
345 File.open('libdummy_icd_gen.h','w') { |f|
346 f.puts generate_libdummy_icd_header
348 File.open('libdummy_icd_gen.c','w') { |f|
349 f.puts generate_libdummy_icd_source
351 File.open('run_dummy_icd_gen.c','w') { |f|
352 f.puts generate_run_dummy_icd_source
354 File.open('run_dummy_icd_weak_gen.c','w') { |f|
355 f.puts generate_run_dummy_icd_weak_source
359 ##########################################################
360 ##########################################################
362 def self.generate_ocl_icd_header
363 ocl_icd_header = "/**\n#{$license}\n*/\n\n"
364 ocl_icd_header += "#ifndef OCL_ICD_H\n"
365 ocl_icd_header += "#define OCL_ICD_H\n"
366 ocl_icd_header += "#pragma GCC diagnostic push\n"
367 ocl_icd_header += "# pragma GCC diagnostic ignored \"-Wcpp\"\n"
368 ocl_icd_header += "# define CL_USE_DEPRECATED_OPENCL_1_0_APIS\n"
369 ocl_icd_header += "# define CL_USE_DEPRECATED_OPENCL_1_1_APIS\n"
370 ocl_icd_header += "# define CL_USE_DEPRECATED_OPENCL_1_2_APIS\n"
371 ocl_icd_header += "# include <CL/opencl.h>\n"
372 ocl_icd_header += self.include_headers
373 ocl_icd_header += "#pragma GCC diagnostic pop\n"
374 ocl_icd_header += <<EOF
376 #define OCL_ICD_API_VERSION 1
377 #define OCL_ICD_IDENTIFIED_FUNCTIONS #{$known_entries.count}
379 struct _cl_icd_dispatch {
382 $api_entries_array.each { |entry|
383 version = entry.split("\n").
384 grep(/ CL_API_SUFFIX__(VERSION_[0-9_]+)[^0-9_]/).join('').
385 gsub(/.* CL_API_SUFFIX__(VERSION_[0-9_]+)[^0-9_].*$/, '\1')
386 if (version != '') then
387 ocl_icd_header += '#ifdef CL_'+version+"\n"
389 ocl_icd_header += entry.gsub("\r","").
390 sub(/CL_API_CALL\n?(.*?)\(/m,'(CL_API_CALL*\1)('+"\n ").
391 gsub(/\) (CL_API_SUFFIX__VERSION)/m,"\n) \\1").gsub(/\s*$/,'').
392 gsub(/^[\t ]+/," ").gsub(/^([^\t ])/, ' \1') + "\n"
393 if (version != '') then
394 ocl_icd_header += '#else'+"\n"
395 ocl_icd_header += ' CL_API_ENTRY cl_int (CL_API_CALL* clUnknown'+nb.to_s+")(void);\n"
396 ocl_icd_header += '#endif'+"\n"
398 ocl_icd_header += "\n"
401 ocl_icd_header += "};\n"
402 ocl_icd_header += "#endif\n\n"
403 return ocl_icd_header
406 def self.generate_ocl_icd_loader_header
407 ocl_icd_header = "/**\n#{$license}\n*/\n\n"
408 ocl_icd_header += "#include \"ocl_icd.h\"\n\n"
409 ocl_icd_header += <<EOF
413 void(*const addr)(void);
415 typedef __typeof__(clGetExtensionFunctionAddress) *clGetExtensionFunctionAddress_fn;
416 extern const struct func_desc function_description[];
418 cl_uint num_platforms;
420 clGetExtensionFunctionAddress_fn ext_fn_ptr;
423 struct platform_icd {
424 char * extension_suffix;
426 struct vendor_icd *vicd;
428 cl_uint ngpus; /* number of GPU devices */
429 cl_uint ncpus; /* number of CPU devices */
430 cl_uint ndevs; /* total number of devices, of all types */
434 ocl_icd_header += "extern struct _cl_icd_dispatch master_dispatch;\n"
435 $cl_objects.each { |o|
436 ocl_icd_header += "struct _cl_#{o} { struct _cl_icd_dispatch *dispatch; };\n"
438 return ocl_icd_header
441 def self.generate_ocl_icd_loader_map
442 ocl_icd_loader_map = "/**\n#{$license}\n*/\n\n"
444 $versions_entries.keys.sort.each { |version|
445 ocl_icd_loader_map += "OPENCL_#{version.sub('_','.')} {\n";
446 ocl_icd_loader_map += " global:\n";
447 $versions_entries[version].each { |symb|
448 ocl_icd_loader_map += " #{symb};\n"
450 if (prev_version == "") then
451 ocl_icd_loader_map += " local:\n";
452 ocl_icd_loader_map += " *;\n";
454 ocl_icd_loader_map += "} #{prev_version};\n\n";
455 prev_version="OPENCL_#{version.sub('_','.')}";
457 return ocl_icd_loader_map
460 def self.generate_ocl_icd_bindings_source
461 ocl_icd_bindings_source = "/**\n#{$license}\n*/\n"
462 ocl_icd_bindings_source += "#include \"ocl_icd.h\"\n"
463 ocl_icd_bindings_source += "struct _cl_icd_dispatch master_dispatch = {\n"
464 ($api_entries.length+$buff-1).times { |i|
465 if( $known_entries[i] ) then
466 ocl_icd_bindings_source += " #{$known_entries[i]},\n"
468 ocl_icd_bindings_source += " (void *) NULL,\n"
471 if( $known_entries[$api_entries.length+$buff-1] ) then
472 ocl_icd_bindings_source += " #{$known_entries[$api_entries.length+$buff-1]}\n"
474 ocl_icd_bindings_source += " (void *) NULL\n"
476 ocl_icd_bindings_source += "};\n"
477 ocl_icd_bindings_source += <<EOF
479 CL_API_ENTRY cl_int CL_API_CALL clIcdGetPlatformIDsKHR(
481 cl_platform_id *platforms,
482 cl_uint *num_platforms) {
483 if( platforms == NULL && num_platforms == NULL )
484 return CL_INVALID_VALUE;
485 if( num_entries == 0 && platforms != NULL )
486 return CL_INVALID_VALUE;
487 #error You have to fill the commented lines with corresponding variables from your library
488 // if( your_number_of_platforms == 0)
489 // return CL_PLATFORM_NOT_FOUND_KHR;
490 // if( num_platforms != NULL )
491 // *num_platforms = your_number_of_platforms;
492 if( platforms != NULL ) {
494 // for( i=0; i<(your_number_of_platforms<num_entries?your_number_of_platforms:num_entries); i++)
495 // platforms[i] = &your_platforms[i];
500 CL_API_ENTRY void * CL_API_CALL clGetExtensionFunctionAddress(
501 const char * func_name) CL_API_SUFFIX__VERSION_1_0 {
502 #error You have to fill this function with your extensions of incorporate these lines in your version
503 if( func_name != NULL && strcmp("clIcdGetPlatformIDsKHR", func_name) == 0 )
504 return (void *)clIcdGetPlatformIDsKHR;
507 CL_API_ENTRY cl_int CL_API_CALL clGetPlatformInfo(
508 cl_platform_id platform,
509 cl_platform_info param_name,
510 size_t param_value_size,
512 size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0 {
513 #error You ahve to fill this function with your information or assert that your version responds to CL_PLATFORM_ICD_SUFFIX_KHR
514 // char cl_platform_profile[] = "FULL_PROFILE";
515 // char cl_platform_version[] = "OpenCL 1.1";
516 // char cl_platform_name[] = "DummyCL";
517 // char cl_platform_vendor[] = "LIG";
518 // char cl_platform_extensions[] = "cl_khr_icd";
519 // char cl_platform_icd_suffix_khr[] = "DUMMY";
522 if( platform != NULL ) {
525 for(i=0; i<num_master_platforms; i++) {
526 if( platform == &master_platforms[i] )
530 return CL_INVALID_PLATFORM;
532 switch ( param_name ) {
533 case CL_PLATFORM_PROFILE:
534 string_p = cl_platform_profile;
535 size_string = sizeof(cl_platform_profile);
537 case CL_PLATFORM_VERSION:
538 string_p = cl_platform_version;
539 size_string = sizeof(cl_platform_version);
541 case CL_PLATFORM_NAME:
542 string_p = cl_platform_name;
543 size_string = sizeof(cl_platform_name);
545 case CL_PLATFORM_VENDOR:
546 string_p = cl_platform_vendor;
547 size_string = sizeof(cl_platform_vendor);
549 case CL_PLATFORM_EXTENSIONS:
550 string_p = cl_platform_extensions;
551 size_string = sizeof(cl_platform_extensions);
553 case CL_PLATFORM_ICD_SUFFIX_KHR:
554 string_p = cl_platform_icd_suffix_khr;
555 size_string = sizeof(cl_platform_icd_suffix_khr);
558 return CL_INVALID_VALUE;
561 if( param_value != NULL ) {
562 if( size_string > param_value_size )
563 return CL_INVALID_VALUE;
564 memcpy(param_value, string_p, size_string);
566 if( param_value_size_ret != NULL )
567 *param_value_size_ret = size_string;
571 return ocl_icd_bindings_source
574 def self.generate_get_extension_address_for_platform
576 if( func_name == NULL )
578 struct func_desc const * fn=&function_description[0];
579 int lenfn=strlen(func_name);
581 (strcmp(func_name+lenfn-3, "KHR")==0 || strcmp(func_name+lenfn-3, "EXT")==0)) {
582 while (fn->name != NULL) {
583 if (strcmp(func_name, fn->name)==0)
592 def self.generate_ocl_icd_loader_gen_source
593 skip_funcs = $specific_loader_funcs
594 ocl_icd_loader_gen_source = "/**\n#{$license}\n*/\n"
595 ocl_icd_loader_gen_source += "#include <string.h>\n"
596 ocl_icd_loader_gen_source += "#include \"ocl_icd_loader.h\"\n"
597 ocl_icd_loader_gen_source += "#define DEBUG_OCL_ICD_PROVIDE_DUMP_FIELD\n"
598 ocl_icd_loader_gen_source += "#include \"ocl_icd_debug.h\"\n"
599 $api_entries.each { |func_name, entry|
600 next if skip_funcs.include?(func_name)
601 clean_entry = entry.sub(/(.*\)).*/m,'\1').gsub("/*","").gsub("*/","").gsub("\r","") + "{\n"
602 return_type = entry.match(/CL_API_ENTRY (.*) CL_API_CALL/)[1]
603 parameters = clean_entry.match(/\(.*\)/m)[0][1..-2]
604 parameters.gsub!(/\[.*?\]/,"")
605 parameters.sub!(/\(.*?\*\s*(.*?)\)\s*\(.*?\)/m,'\1')
606 ocl_icd_loader_gen_source += clean_entry.gsub(/\*\[.*?\]/,"* ").gsub(/\[.+?\]/,"")
607 first_parameter = parameters.match(/.*?\,/m)
608 if not first_parameter then
609 first_parameter = parameters.match(/.*/m)[0]
611 first_parameter = first_parameter[0][0..-2]
613 fps = first_parameter.split
614 ocl_icd_loader_gen_source += " debug_trace();\n"
615 ocl_icd_loader_gen_source += generate_get_extension_address_for_platform if func_name == "clGetExtensionFunctionAddressForPlatform"
616 raise "Unsupported data_type #{fps[0]}" if not $cl_data_type_error[fps[0]]
617 ps = parameters.split(",")
618 ps = ps.collect { |p|
620 p = p[-1].gsub("*","")
622 error_handler = lambda {
623 if(ps.include?("errcode_ret")) then
624 ocl_icd_loader_gen_source += " if( errcode_ret != NULL ) {\n";
625 ocl_icd_loader_gen_source += " *errcode_ret = #{$cl_data_type_error[fps[0]]};\n"
626 ocl_icd_loader_gen_source += " }\n"
627 if return_type != "void" then
628 ocl_icd_loader_gen_source += " RETURN(NULL);\n"
630 ocl_icd_loader_gen_source += " return;\n"
632 elsif ($non_standard_error.include?(func_name)) then
633 if return_type != "void" then
634 ocl_icd_loader_gen_source += " RETURN(NULL);\n"
636 ocl_icd_loader_gen_source += " return;\n"
639 if return_type != "void" then
640 ocl_icd_loader_gen_source += " RETURN(#{$cl_data_type_error[fps[0]]});\n" if return_type != "void"
642 ocl_icd_loader_gen_source += " return;\n"
647 if(fps[0] == "cl_platform_id") then
648 ocl_icd_loader_gen_source += " #{fps[1]}=selectPlatformID(#{fps[1]});\n"
650 ocl_icd_loader_gen_source += " if( (struct _#{fps[0]} *)#{fps[1]} == NULL) {\n"
652 ocl_icd_loader_gen_source += " }\n"
653 if return_type != "void" then
654 return_debug="RETURN"
656 return_debug="return"
658 ocl_icd_loader_gen_source += " #{return_debug}(((struct _#{fps[0]} *)#{fps[1]})->dispatch->#{func_name}("
659 ocl_icd_loader_gen_source += ps.join(", ")
660 ocl_icd_loader_gen_source += "));\n"
661 ocl_icd_loader_gen_source += "}\n\n"
663 ocl_icd_loader_gen_source += "#pragma GCC visibility push(hidden)\n\n"
664 skip_funcs = $specific_loader_funcs
665 $api_entries.each { |func_name, entry|
666 #next if func_name.match(/EXT$/)
667 #next if func_name.match(/KHR$/)
668 if (skip_funcs.include?(func_name)) then
669 ocl_icd_loader_gen_source += "extern typeof(#{func_name}) #{func_name}_hid;\n"
671 ocl_icd_loader_gen_source += "typeof(#{func_name}) #{func_name}_hid __attribute__ ((alias (\"#{func_name}\"), visibility(\"hidden\")));\n"
674 ocl_icd_loader_gen_source += "\n\nstruct func_desc const function_description[]= {\n"
675 $api_entries.each { |func_name, entry|
676 #next if func_name.match(/EXT$/)
677 #next if func_name.match(/KHR$/)
678 ocl_icd_loader_gen_source += " {\"#{func_name}\", (void(* const)(void))&#{func_name}_hid },\n"
680 ocl_icd_loader_gen_source += <<EOF
685 void dump_platform(clGEFA_t f, cl_platform_id pid) {
686 debug(D_ALWAYS, "platform @%p: name=field_in_struct [clGetExtensionFunctionAddress(name)/clGetExtensionFunctionAddressForPlatform(name)]", pid);
688 $api_entries_array.each { |entry|
689 e = entry.gsub("\r"," ").gsub("\n"," ").gsub("\t"," ").
690 sub(/.*CL_API_CALL *([^ ()]*)[ ()].*$/m, '\1')
691 ocl_icd_loader_gen_source += " dump_field(pid, f, #{e});\n"
694 ocl_icd_loader_gen_source += <<EOF
698 #pragma GCC visibility pop
701 return ocl_icd_loader_gen_source;
704 def self.generate_from_database(yamlfile)
705 load_database(yamlfile)
706 File.open('ocl_icd.h','w') { |f|
707 f.puts generate_ocl_icd_header
709 File.open('ocl_icd_loader_gen.h','w') { |f|
710 f.puts generate_ocl_icd_loader_header
712 File.open('ocl_icd_loader_gen.map','w') { |f|
713 f.puts generate_ocl_icd_loader_map
715 File.open('ocl_icd_bindings.c','w') { |f|
716 f.puts generate_ocl_icd_bindings_source
718 File.open('ocl_icd_loader_gen.c','w') { |f|
719 f.puts generate_ocl_icd_loader_gen_source
723 ##########################################################
724 ##########################################################
725 # update-database mode
726 def self.savedb(yamlfile)
727 File::open(yamlfile,"w") { |f|
728 f.write($license.gsub(/^/,"# "))
731 # In Intel (OpenCL 1.1):
732 # * clSetCommandQueueProperty(13): nil (deprecated in 1.1)
733 # * clGetGLContextInfoKHR(74): function present with its symbol
735 # * 92: correspond to symbol clGetKernelArgInfo (first abandonned version?)
737 # In nvidia (OpenCL 1.1):
738 # * clGetGLContextInfoKHR(74): function present but no symbol
741 # * only two OpenCL symbols: clGetPlatformInfo(1) and clGetExtensionFunctionAddress(65)
742 # In AMD (OpenCL 1.2):
743 # * clGetPlatformIDs(0): nil (symbol present)
744 # * clGetGLContextInfoKHR(74): function present but no symbol
752 # Not using YAML::dump as:
753 # * keys are not ordered
754 # * strings are badly formatted in new YAML ruby implementation (psych)
755 # * it is very easy to do it ourself
756 #f.write(YAML::dump(api_db))
758 $known_entries.keys.sort.each { |k|
759 f.write("\n#{k}: |-\n ")
760 f.write($api_entries[$known_entries[k]].gsub("\n","\n "))
766 def self.updatedb_from_input(dbfile, inputfile)
768 load_database(dbfile, with_windows=true)
769 doc = YAML::load_file(inputfile)
772 next if $known_entries[i]
773 $known_entries[i]=doc[i]
780 ############################################################
781 ############################################################
782 ############################################################
789 OptionParser.new do |opts|
790 opts.banner = "Usage: cd_generator.rb [options] mode"
792 opts.on("-d", "--database FILE", String, "YAML file (default ocl_interface.yaml)") do |v|
793 options[:database] = v
795 opts.on("-i", "--input FILE", String,
796 "binding between OpenCL functions and entry number (required for update-database)") \
800 opts.on("-s", "--[no-]system-headers",
801 "Look for OpenCL functions in system header files") \
803 options[:"system-headers"] = v
805 opts.on("-m", "--mode [MODE]", [:database, :generate, :"update-database"],
806 "Select mode (database, generate, update-database)") do |m|
811 if !options[:database] then
812 options[:database] = "ocl_interface.yaml"
815 if !options[:mode] then
816 raise "--mode option required"
818 if options[:mode] == :generate then
819 if !options[:"system-headers"] then
820 IcdGenerator.generate_sources(from_headers=false, from_database=true, database=options[:database])
822 IcdGenerator.generate_sources(from_headers=true, from_database=false)
824 elsif options[:mode] == :"update-database" then
825 if !options[:input] then
826 raise "--input option required"
828 IcdGenerator.updatedb_from_input(options[:database], options[:input])
829 elsif options[:mode] == :database then
830 IcdGenerator.generate_from_database(options[:database])
832 raise "Mode must be one of generate, database or update-database not #{options[:mode]}"