2 Copyright (c) 2012, Brice Videau <brice.videau@imag.fr>
3 Copyright (c) 2012, 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.
31 $api_entries_array = []
32 $cl_objects = ["platform_id", "device_id", "context", "command_queue", "mem", "program", "kernel", "event", "sampler"]
33 $know_entries = { 1 => "clGetPlatformInfo", 0 => "clGetPlatformIDs" }
34 $use_name_in_test = { 1 => "clGetPlatformInfo", 0 => "clGetPlatformIDs" }
35 # do not call these functions when trying to discover the mapping
36 $forbidden_funcs = ["clGetExtensionFunctionAddress", "clGetPlatformIDs",
37 "clGetPlatformInfo", "clGetGLContextInfoKHR", "clUnloadCompiler",
38 "clSetCommandQueueProperty"]
39 $windows_funcs = ["clGetDeviceIDsFromD3D10KHR", "clCreateFromD3D10BufferKHR",
40 "clCreateFromD3D10Texture2DKHR", "clCreateFromD3D10Texture3DKHR",
41 "clEnqueueAcquireD3D10ObjectsKHR", "clEnqueueReleaseD3D10ObjectsKHR",
42 "clGetDeviceIDsFromD3D11KHR", "clCreateFromD3D11BufferKHR",
43 "clCreateFromD3D11Texture2DKHR", "clCreateFromD3D11Texture3DKHR",
44 "clEnqueueAcquireD3D11ObjectsKHR", "clEnqueueReleaseD3D11ObjectsKHR",
45 "clGetDeviceIDsFromDX9MediaAdapterKHR", "clCreateFromDX9MediaSurfaceKHR",
46 "clEnqueueAcquireDX9MediaSurfacesKHR", "clEnqueueReleaseDX9MediaSurfacesKHR"]
47 # do not create weak functions for these ones in the discovering program
48 $noweak_funcs = ["clGetExtensionFunctionAddress", "clGetPlatformIDs",
49 "clGetPlatformInfo", "clGetGLContextInfoKHR", "clUnloadCompiler",
50 "clCreateContext", "clCreateContextFromType", "clWaitForEvents"]
51 # functions written specifically in the loader
52 $specific_loader_funcs = ["clGetExtensionFunctionAddress","clGetPlatformIDs",
53 "clGetGLContextInfoKHR", "clUnloadCompiler",
54 "clCreateContext", "clCreateContextFromType", "clWaitForEvents"]
55 $header_files = ["/usr/include/CL/cl.h", "/usr/include/CL/cl_gl.h",
56 "/usr/include/CL/cl_ext.h", "/usr/include/CL/cl_gl_ext.h"]
57 $windows_header_files = ["/usr/include/CL/cl_dx9_media_sharing.h", "/usr/include/CL/cl_d3d11.h", "/usr/include/CL/cl_d3d10.h"]
58 $versions_entries = []
61 Copyright (c) 2012, Brice Videau <brice.videau@imag.fr>
62 Copyright (c) 2012, Vincent Danjean <Vincent.Danjean@ens-lyon.org>
65 Redistribution and use in source and binary forms, with or without
66 modification, are permitted provided that the following conditions are met:
68 1. Redistributions of source code must retain the above copyright notice, this
69 list of conditions and the following disclaimer.
70 2. Redistributions in binary form must reproduce the above copyright notice,
71 this list of conditions and the following disclaimer in the documentation
72 and/or other materials provided with the distribution.
74 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
75 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
78 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
79 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
81 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
82 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
83 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
85 Do not edit this file. It is automatically generated.
88 ##########################################################
89 ##########################################################
91 def self.parse_headers
93 $header_files.each{ |fname|
96 api_entries += doc.scan(/CL_API_ENTRY.*?;/m)
99 api_entries.each{ |entry|
102 entry_name = entry.match(/CL_API_CALL(.*?)\(/m)[1].strip
104 entry_name = entry.match(/(\S*?)\(/m)[1].strip
106 next if entry_name.match('\*')
107 next if entry_name.match("INTEL")
108 next if entry_name.match("APPLE")
109 $api_entries[entry_name] = entry.gsub("\r","")
111 # $api_entries.each{ |key, value|
112 # puts "#{key}: #{value}"
116 def self.load_database(yamlfile, with_windows=false)
117 doc = YAML::load_file(yamlfile)
120 $versions_entries = Hash::new { |hash,key| hash[key]=[] }
123 doc.each { |key, value|
124 #puts (key.to_s+":: "+value)
126 entry_name = value.match(/CL_API_CALL(.*?)\(/m)[1].strip
128 entry_name = value.match(/(\S*?)\(/m)[1].strip
130 next if (!with_windows) && $windows_funcs.include?(entry_name)
131 version = value.match(/SUFFIX__VERSION_(\d_\d)/m)[1]
132 $versions_entries[version].push(entry_name)
133 $known_entries[key] = entry_name
134 $api_entries[entry_name] = value
136 $api_entries_array = []
137 ($known_entries.length+$buff).times { |i|
138 #puts (i.to_s+": "+$known_entries[i])
139 if $known_entries[i] then
140 $api_entries_array.push( $api_entries[$known_entries[i]] )
142 $api_entries_array.push( "CL_API_ENTRY cl_int CL_API_CALL clUnknown#{i}(void);" )
147 def self.include_headers
149 $header_files.each { |h|
150 if h.match('^/usr/include/') then
151 headers += "#include <#{h[13..-1]}>\n"
153 headers += "#include \"#{h}\"\n"
159 ##########################################################
160 ##########################################################
162 def self.generate_libdummy_icd_header
163 libdummy_icd_structures = "/**\n#{$license}\n*/\n"
164 libdummy_icd_structures += "#include <CL/opencl.h>\n"
165 libdummy_icd_structures += self.include_headers
166 libdummy_icd_structures += "\n\nstruct _cl_icd_dispatch;\n"
167 libdummy_icd_structures += "struct _cl_platform_id { struct _cl_icd_dispatch *dispatch; };\n\n"
168 libdummy_icd_structures += "struct _cl_icd_dispatch {\n"
169 ($api_entries.length+$buff).times { |i|
170 if( $known_entries[i] ) then
171 libdummy_icd_structures += " void(*known#{i})(void);\n"
173 libdummy_icd_structures += " void(*unknown#{i})(void);\n"
176 libdummy_icd_structures += "};\n\n"
177 libdummy_icd_structures += "#pragma GCC visibility push(hidden)\n\n"
178 libdummy_icd_structures += "struct _cl_icd_dispatch master_dispatch; \n\n"
179 $use_name_in_test.each { |k, f|
180 libdummy_icd_structures += "typeof(#{f}) INT#{f};\n"
182 libdummy_icd_structures += "#pragma GCC visibility pop\n\n"
183 return libdummy_icd_structures
186 def self.generate_libdummy_icd_source
187 libdummy_icd_source = "/**\n#{$license}\n*/\n\n"
188 libdummy_icd_source += "#include <stdio.h>\n\n"
189 libdummy_icd_source += "#include \"libdummy_icd_gen.h\"\n\n"
190 libdummy_icd_source += "#include \"libdummy_icd.h\"\n\n"
191 (0...$api_entries.length+$buff).each { |i|
192 libdummy_icd_source += "void dummyFunc#{i}(void){ printf(\"#{i} : \"); fflush(NULL); }\n"
194 libdummy_icd_source += "\nstruct _cl_icd_dispatch master_dispatch = {\n"
196 ($api_entries.length+$buff).times { |i|
197 comma="" if (i == $api_entries.length+$buff-1)
198 if( $use_name_in_test[i] ) then
199 libdummy_icd_source += " (void(*)(void))& INT#{$known_entries[i]}#{comma}\n"
201 libdummy_icd_source += " (void(*)(void))& dummyFunc#{i}#{comma}\n"
204 libdummy_icd_source += "};\n"
205 return libdummy_icd_source
208 def self.generate_run_dummy_icd_source
209 run_dummy_icd = "/**\n#{$license}\n*/\n"
210 run_dummy_icd += "#include <stdlib.h>\n"
211 run_dummy_icd += "#include <stdio.h>\n"
212 run_dummy_icd += "#pragma GCC diagnostic push\n"
213 run_dummy_icd += "# pragma GCC diagnostic ignored \"-Wcpp\"\n"
214 run_dummy_icd += "# define CL_USE_DEPRECATED_OPENCL_1_0_APIS\n"
215 run_dummy_icd += "# define CL_USE_DEPRECATED_OPENCL_1_1_APIS\n"
216 run_dummy_icd += "# include <CL/opencl.h>\n"
217 run_dummy_icd += self.include_headers
218 run_dummy_icd += "#pragma GCC diagnostic pop\n"
219 run_dummy_icd += "\n\n"
220 run_dummy_icd += "typedef CL_API_ENTRY cl_int (CL_API_CALL* oclFuncPtr_fn)(cl_platform_id platform);\n\n"
221 run_dummy_icd += "void call_all_OpenCL_functions(cl_platform_id chosen_platform) {\n"
222 run_dummy_icd += " oclFuncPtr_fn oclFuncPtr;\n"
223 run_dummy_icd += " cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)chosen_platform, 0 };\n"
224 $api_entries.each_key { |func_name|
225 next if $forbidden_funcs.include?(func_name)
226 if func_name == "clCreateContext" then
227 run_dummy_icd += " #{func_name}(properties,1,(cl_device_id*)&chosen_platform,NULL,NULL,NULL);\n"
228 elsif func_name == "clGetGLContextInfoKHR" then
229 run_dummy_icd += " #{func_name}(properties,CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, 0, NULL, NULL);\n"
230 elsif func_name == "clCreateContextFromType" then
231 run_dummy_icd += " #{func_name}(properties,CL_DEVICE_TYPE_CPU,NULL,NULL,NULL);\n"
232 elsif func_name == "clWaitForEvents" then
233 run_dummy_icd += " #{func_name}(1,(cl_event*)&chosen_platform);\n"
234 elsif func_name == "clGetExtensionFunctionAddressForPlatform" then
235 run_dummy_icd += " #{func_name}((cl_platform_id)chosen_platform, \"clIcdGetPlatformIDsKHR\");\n"
237 run_dummy_icd += " oclFuncPtr = (oclFuncPtr_fn)" + func_name + ";\n"
238 run_dummy_icd += " oclFuncPtr(chosen_platform);\n"
240 run_dummy_icd += " printf(\"%s\\n\", \"#{func_name}\");"
241 run_dummy_icd += " fflush(NULL);\n"
243 run_dummy_icd += " return;\n}\n"
247 def self.generate_run_dummy_icd_weak_source
248 run_dummy_icd_weak = "/**\n#{$license}\n*/\n"
249 run_dummy_icd_weak += <<EOF
250 #define _GNU_SOURCE 1
255 __attribute__((weak)) int f (void* arg, void* arg2) { \\
256 void (* p)(void*, void*)=NULL; \\
257 p=dlsym(RTLD_NEXT, #f); \\
267 $api_entries.each_key { |func_name|
268 next if $noweak_funcs.include?(func_name)
269 run_dummy_icd_weak += "F(#{func_name})\n"
271 return run_dummy_icd_weak
274 def self.generate_sources(from_headers=true, from_database=false, database=nil)
278 if from_database then
279 load_database(database)
281 File.open('libdummy_icd_gen.h','w') { |f|
282 f.puts generate_libdummy_icd_header
284 File.open('libdummy_icd_gen.c','w') { |f|
285 f.puts generate_libdummy_icd_source
287 File.open('run_dummy_icd_gen.c','w') { |f|
288 f.puts generate_run_dummy_icd_source
290 File.open('run_dummy_icd_weak.c','w') { |f|
291 f.puts generate_run_dummy_icd_weak_source
295 ##########################################################
296 ##########################################################
298 def self.generate_ocl_icd_header
299 ocl_icd_header = "/**\n#{$license}\n*/\n\n"
300 ocl_icd_header += "#ifndef OCL_ICD_H\n"
301 ocl_icd_header += "#define OCL_ICD_H\n"
302 ocl_icd_header += "#pragma GCC diagnostic push\n"
303 ocl_icd_header += "# pragma GCC diagnostic ignored \"-Wcpp\"\n"
304 ocl_icd_header += "# define CL_USE_DEPRECATED_OPENCL_1_0_APIS\n"
305 ocl_icd_header += "# define CL_USE_DEPRECATED_OPENCL_1_1_APIS\n"
306 ocl_icd_header += "# include <CL/opencl.h>\n"
307 ocl_icd_header += self.include_headers
308 ocl_icd_header += "#pragma GCC diagnostic pop\n"
309 ocl_icd_header += <<EOF
311 #define OCL_ICD_API_VERSION 1
312 #define OCL_ICD_IDENTIFIED_FUNCTIONS #{$known_entries.count}
314 struct _cl_icd_dispatch {
316 $api_entries_array.each { |entry|
317 ocl_icd_header += entry.gsub("\r","").
318 sub(/CL_API_CALL\n?(.*?)\(/m,'(CL_API_CALL*\1)('+"\n ").
319 gsub(/\) (CL_API_SUFFIX__VERSION)/m,"\n) \\1").gsub(/\s*$/,'').
320 gsub(/^[\t ]+/," ").gsub(/^([^\t ])/, ' \1') + "\n\n"
322 ocl_icd_header += "};\n"
323 ocl_icd_header += "#endif\n\n"
324 return ocl_icd_header
327 def self.generate_ocl_icd_loader_header
328 ocl_icd_header = "/**\n#{$license}\n*/\n\n"
329 ocl_icd_header += "#include \"ocl_icd.h\"\n\n"
330 ocl_icd_header += <<EOF
334 void(*const addr)(void);
337 extern const struct func_desc function_description[];
340 ocl_icd_header += "extern struct _cl_icd_dispatch master_dispatch;\n"
341 $cl_objects.each { |o|
342 ocl_icd_header += "struct _cl_#{o} { struct _cl_icd_dispatch *dispatch; };\n"
344 return ocl_icd_header
347 def self.generate_ocl_icd_loader_map
348 ocl_icd_loader_map = "/**\n#{$license}\n*/\n\n"
350 $versions_entries.keys.sort.each { |version|
351 ocl_icd_loader_map += "OPENCL_#{version.sub('_','.')} {\n";
352 ocl_icd_loader_map += " global:\n";
353 $versions_entries[version].each { |symb|
354 ocl_icd_loader_map += " #{symb};\n"
356 if (prev_version == "") then
357 ocl_icd_loader_map += " local:\n";
358 ocl_icd_loader_map += " *;\n";
360 ocl_icd_loader_map += "} #{prev_version};\n\n";
361 prev_version="OPENCL_#{version.sub('_','.')}";
363 return ocl_icd_loader_map
366 def self.generate_ocl_icd_bindings_source
367 ocl_icd_bindings_source = "/**\n#{$license}\n*/\n"
368 ocl_icd_bindings_source += "#include \"ocl_icd.h\"\n"
369 ocl_icd_bindings_source += "struct _cl_icd_dispatch master_dispatch = {\n"
370 ($api_entries.length+$buff-1).times { |i|
371 if( $known_entries[i] ) then
372 ocl_icd_bindings_source += " #{$known_entries[i]},\n"
374 ocl_icd_bindings_source += " (void *) NULL,\n"
377 if( $known_entries[$api_entries.length+$buff-1] ) then
378 ocl_icd_bindings_source += " #{$known_entries[i]}\n"
380 ocl_icd_bindings_source += " (void *) NULL\n"
382 ocl_icd_bindings_source += "};\n"
383 ocl_icd_bindings_source += <<EOF
385 CL_API_ENTRY cl_int CL_API_CALL clIcdGetPlatformIDsKHR(
387 cl_platform_id *platforms,
388 cl_uint *num_platforms) {
389 if( platforms == NULL && num_platforms == NULL )
390 return CL_INVALID_VALUE;
391 if( num_entries == 0 && platforms != NULL )
392 return CL_INVALID_VALUE;
393 #error You have to fill the commented lines with corresponding variables from your library
394 // if( your_number_of_platforms == 0)
395 // return CL_PLATFORM_NOT_FOUND_KHR;
396 // if( num_platforms != NULL )
397 // *num_platforms = your_number_of_platforms;
398 if( platforms != NULL ) {
400 // for( i=0; i<(your_number_of_platforms<num_entries?your_number_of_platforms:num_entries); i++)
401 // platforms[i] = &your_platforms[i];
406 CL_API_ENTRY void * CL_API_CALL clGetExtensionFunctionAddress(
407 const char * func_name) CL_API_SUFFIX__VERSION_1_0 {
408 #error You have to fill this function with your extensions of incorporate these lines in your version
409 if( func_name != NULL && strcmp("clIcdGetPlatformIDsKHR", func_name) == 0 )
410 return (void *)clIcdGetPlatformIDsKHR;
413 CL_API_ENTRY cl_int CL_API_CALL clGetPlatformInfo(
414 cl_platform_id platform,
415 cl_platform_info param_name,
416 size_t param_value_size,
418 size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0 {
419 #error You ahve to fill this function with your information or assert that your version responds to CL_PLATFORM_ICD_SUFFIX_KHR
420 // char cl_platform_profile[] = "FULL_PROFILE";
421 // char cl_platform_version[] = "OpenCL 1.1";
422 // char cl_platform_name[] = "DummyCL";
423 // char cl_platform_vendor[] = "LIG";
424 // char cl_platform_extensions[] = "cl_khr_icd";
425 // char cl_platform_icd_suffix_khr[] = "DUMMY";
428 if( platform != NULL ) {
431 for(i=0; i<num_master_platforms; i++) {
432 if( platform == &master_platforms[i] )
436 return CL_INVALID_PLATFORM;
438 switch ( param_name ) {
439 case CL_PLATFORM_PROFILE:
440 string_p = cl_platform_profile;
441 size_string = sizeof(cl_platform_profile);
443 case CL_PLATFORM_VERSION:
444 string_p = cl_platform_version;
445 size_string = sizeof(cl_platform_version);
447 case CL_PLATFORM_NAME:
448 string_p = cl_platform_name;
449 size_string = sizeof(cl_platform_name);
451 case CL_PLATFORM_VENDOR:
452 string_p = cl_platform_vendor;
453 size_string = sizeof(cl_platform_vendor);
455 case CL_PLATFORM_EXTENSIONS:
456 string_p = cl_platform_extensions;
457 size_string = sizeof(cl_platform_extensions);
459 case CL_PLATFORM_ICD_SUFFIX_KHR:
460 string_p = cl_platform_icd_suffix_khr;
461 size_string = sizeof(cl_platform_icd_suffix_khr);
464 return CL_INVALID_VALUE;
467 if( param_value != NULL ) {
468 if( size_string > param_value_size )
469 return CL_INVALID_VALUE;
470 memcpy(param_value, string_p, size_string);
472 if( param_value_size_ret != NULL )
473 *param_value_size_ret = size_string;
477 return ocl_icd_bindings_source
480 def self.generate_ocl_icd_loader_gen_source
481 skip_funcs = $specific_loader_funcs
482 ocl_icd_loader_gen_source = "/**\n#{$license}\n*/\n"
483 ocl_icd_loader_gen_source += "#include \"ocl_icd_loader.h\"\n"
484 ocl_icd_loader_gen_source += "#define DEBUG_OCL_ICD_PROVIDE_DUMP_FIELD\n"
485 ocl_icd_loader_gen_source += "#include \"ocl_icd_debug.h\"\n"
486 ocl_icd_loader_gen_source += ""
487 $api_entries.each { |func_name, entry|
488 next if skip_funcs.include?(func_name)
489 clean_entry = entry.sub(/(.*\)).*/m,'\1').gsub("/*","").gsub("*/","").gsub("\r","") + "{\n"
490 parameters = clean_entry.match(/\(.*\)/m)[0][1..-2]
491 parameters.gsub!(/\[.*?\]/,"")
492 parameters.sub!(/\(.*?\*\s*(.*?)\)\s*\(.*?\)/,'\1')
493 ocl_icd_loader_gen_source += clean_entry.gsub(/\[.*?\]/,"")
494 first_parameter = parameters.match(/.*?\,/m)
495 if not first_parameter then
496 first_parameter = parameters.match(/.*/m)[0]
498 first_parameter = first_parameter[0][0..-2]
500 fps = first_parameter.split
501 ocl_icd_loader_gen_source += " debug_trace();\n"
502 ocl_icd_loader_gen_source += " RETURN(((struct _#{fps[0]} *)#{fps[1]})->dispatch->#{func_name}("
503 ps = parameters.split(",")
504 ps = ps.collect { |p|
506 p = p[-1].gsub("*","")
508 ocl_icd_loader_gen_source += ps.join(", ")
509 ocl_icd_loader_gen_source += "));\n"
510 ocl_icd_loader_gen_source += "}\n\n"
512 ocl_icd_loader_gen_source += "#pragma GCC visibility push(hidden)\n\n"
513 skip_funcs = $specific_loader_funcs
514 $api_entries.each { |func_name, entry|
515 #next if func_name.match(/EXT$/)
516 #next if func_name.match(/KHR$/)
517 if (skip_funcs.include?(func_name)) then
518 ocl_icd_loader_gen_source += "extern typeof(#{func_name}) #{func_name}_hid;\n"
520 ocl_icd_loader_gen_source += "typeof(#{func_name}) #{func_name}_hid __attribute__ ((alias (\"#{func_name}\"), visibility(\"hidden\")));\n"
523 ocl_icd_loader_gen_source += "\n\nstruct func_desc const function_description[]= {\n"
524 $api_entries.each { |func_name, entry|
525 #next if func_name.match(/EXT$/)
526 #next if func_name.match(/KHR$/)
527 ocl_icd_loader_gen_source += " {\"#{func_name}\", (void(* const)(void))&#{func_name}_hid },\n"
529 ocl_icd_loader_gen_source += <<EOF
534 void dump_platform(clGEFA_t f, cl_platform_id pid) {
535 debug(D_ALWAYS, "platform @%p: name=field_in_struct [clGetExtensionFunctionAddress(name)/clGetExtensionFunctionAddressForPlatform(name)]", pid);
537 $api_entries_array.each { |entry|
538 e = entry.gsub("\r"," ").gsub("\n"," ").gsub("\t"," ").
539 sub(/.*CL_API_CALL *([^ ()]*)[ ()].*$/m, '\1')
540 ocl_icd_loader_gen_source += " dump_field(pid, f, #{e});\n"
543 ocl_icd_loader_gen_source += <<EOF
547 #pragma GCC visibility pop
550 return ocl_icd_loader_gen_source;
553 def self.generate_from_database(yamlfile)
554 load_database(yamlfile)
555 File.open('ocl_icd.h','w') { |f|
556 f.puts generate_ocl_icd_header
558 File.open('ocl_icd_loader.h','w') { |f|
559 f.puts generate_ocl_icd_loader_header
561 File.open('ocl_icd_loader.map','w') { |f|
562 f.puts generate_ocl_icd_loader_map
564 File.open('ocl_icd_bindings.c','w') { |f|
565 f.puts generate_ocl_icd_bindings_source
567 File.open('ocl_icd_loader_gen.c','w') { |f|
568 f.puts generate_ocl_icd_loader_gen_source
572 ##########################################################
573 ##########################################################
574 # update-database mode
575 def self.savedb(yamlfile)
576 File::open(yamlfile,"w") { |f|
577 f.write($license.gsub(/^/,"# "))
580 # In Intel (OpenCL 1.1):
581 # * clSetCommandQueueProperty(13): nil (deprecated in 1.1)
582 # * clGetGLContextInfoKHR(74): function present with its symbol
584 # * 92: correspond to symbol clGetKernelArgInfo (first abandonned version?)
586 # In nvidia (OpenCL 1.1):
587 # * clGetGLContextInfoKHR(74): function present but no symbol
590 # * only two OpenCL symbols: clGetPlatformInfo(1) and clGetExtensionFunctionAddress(65)
591 # In AMD (OpenCL 1.2):
592 # * clGetPlatformIDs(0): nil (symbol present)
593 # * clGetGLContextInfoKHR(74): function present but no symbol
601 # Not using YAML::dump as:
602 # * keys are not ordered
603 # * strings are badly formatted in new YAML ruby implementation (psych)
604 # * it is very easy to do it ourself
605 #f.write(YAML::dump(api_db))
607 $known_entries.keys.sort.each { |k|
608 f.write("\n#{k}: |-\n ")
609 f.write($api_entries[$known_entries[k]].gsub("\n","\n "))
615 def self.updatedb_from_input(dbfile, inputfile)
617 load_database(dbfile, with_windows=true)
618 doc = YAML::load_file(inputfile)
621 next if $known_entries[i]
622 $known_entries[i]=doc[i]
629 ############################################################
630 ############################################################
631 ############################################################
638 OptionParser.new do |opts|
639 opts.banner = "Usage: cd_generator.rb [options] mode"
641 opts.on("-d", "--database FILE", String, "YAML file (default ocl_interface.yaml)") do |v|
642 options[:database] = v
644 opts.on("-i", "--input FILE", String,
645 "binding between OpenCL functions and entry number (required for update-database)") \
649 opts.on("-s", "--[no-]system-headers",
650 "Look for OpenCL functions in system header files") \
652 options[:"system-headers"] = v
654 opts.on("-m", "--mode [MODE]", [:database, :generate, :"update-database"],
655 "Select mode (database, generate, update-database)") do |m|
660 if !options[:database] then
661 options[:database] = "ocl_interface.yaml"
664 if !options[:mode] then
665 raise "--mode option required"
667 if options[:mode] == :generate then
668 if !options[:"system-headers"] then
669 IcdGenerator.generate_sources(from_headers=false, from_database=true, database=options[:database])
671 IcdGenerator.generate_sources(from_headers=true, from_database=false)
673 elsif options[:mode] == :"update-database" then
674 if !options[:input] then
675 raise "--input option required"
677 IcdGenerator.updatedb_from_input(options[:database], options[:input])
678 elsif options[:mode] == :database then
679 IcdGenerator.generate_from_database(options[:database])
681 raise "Mode must be one of generate, database or update-database not #{options[:mode]}"