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 $known_entries= { 1 => "clGetPlatformInfo", 0 => "clGetPlatformIDs" }
34 # do not call these functions when trying to discover the mapping
35 $forbidden_funcs = ["clGetExtensionFunctionAddress", "clGetPlatformIDs",
36 "clGetPlatformInfo", "clGetGLContextInfoKHR", "clUnloadCompiler"]
37 $windows_funcs = ["clGetDeviceIDsFromD3D10KHR", "clCreateFromD3D10BufferKHR",
38 "clCreateFromD3D10Texture2DKHR", "clCreateFromD3D10Texture3DKHR",
39 "clEnqueueAcquireD3D10ObjectsKHR", "clEnqueueReleaseD3D10ObjectsKHR",
40 "clGetDeviceIDsFromD3D11KHR", "clCreateFromD3D11BufferKHR",
41 "clCreateFromD3D11Texture2DKHR", "clCreateFromD3D11Texture3DKHR",
42 "clEnqueueAcquireD3D11ObjectsKHR", "clEnqueueReleaseD3D11ObjectsKHR",
43 "clGetDeviceIDsFromDX9MediaAdapterKHR", "clCreateFromDX9MediaSurfaceKHR",
44 "clEnqueueAcquireDX9MediaSurfacesKHR", "clEnqueueReleaseDX9MediaSurfacesKHR"]
45 # do not create weak functions for these ones in the discovering program
46 $noweak_funcs = ["clGetExtensionFunctionAddress", "clGetPlatformIDs",
47 "clGetPlatformInfo", "clGetGLContextInfoKHR", "clUnloadCompiler",
48 "clCreateContext", "clCreateContextFromType", "clWaitForEvents"]
49 # functions written specifically in the loader
50 $specific_loader_funcs = ["clGetExtensionFunctionAddress","clGetPlatformIDs",
51 "clGetGLContextInfoKHR", "clUnloadCompiler",
52 "clCreateContext", "clCreateContextFromType", "clWaitForEvents"]
53 $header_files = ["/usr/include/CL/cl.h", "/usr/include/CL/cl_gl.h",
54 "/usr/include/CL/cl_ext.h", "/usr/include/CL/cl_gl_ext.h"]
55 $windows_header_files = ["/usr/include/CL/cl_dx9_media_sharing.h", "/usr/include/CL/cl_d3d11.h", "/usr/include/CL/cl_d3d10.h"]
56 $versions_entries = []
59 Copyright (c) 2012, Brice Videau <brice.videau@imag.fr>
60 Copyright (c) 2012, Vincent Danjean <Vincent.Danjean@ens-lyon.org>
63 Redistribution and use in source and binary forms, with or without
64 modification, are permitted provided that the following conditions are met:
66 1. Redistributions of source code must retain the above copyright notice, this
67 list of conditions and the following disclaimer.
68 2. Redistributions in binary form must reproduce the above copyright notice,
69 this list of conditions and the following disclaimer in the documentation
70 and/or other materials provided with the distribution.
72 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
73 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
76 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
79 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
81 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
83 Do not edit this file. It is automatically generated.
86 def self.parse_headers
88 $header_files.each{ |fname|
91 api_entries += doc.scan(/CL_API_ENTRY.*?;/m)
94 api_entries.each{ |entry|
97 entry_name = entry.match(/CL_API_CALL(.*?)\(/m)[1].strip
98 next if entry_name.match('\*')
99 next if entry_name.match("INTEL")
100 next if entry_name.match("APPLE")
101 $api_entries[entry_name] = entry
104 entry_name = entry.match(/(\S*?)\(/m)[1].strip
105 next if entry_name.match('\*')
106 next if entry_name.match("INTEL")
107 next if entry_name.match("APPLE")
108 $api_entries[entry_name] = entry
111 # $api_entries.each{ |key, value|
112 # puts "#{key}: #{value}"
116 def self.include_headers
118 $header_files.each { |h|
119 if h.match('^/usr/include/') then
120 headers += "#include <#{h[13..-1]}>\n"
122 headers += "#include \"#{h}\"\n"
128 def self.generate_ocl_icd_header
129 ocl_icd_header = "/**\n#{$license}\n*/\n\n"
130 ocl_icd_header += "#pragma GCC diagnostic push\n"
131 ocl_icd_header += "# pragma GCC diagnostic ignored \"-Wcpp\"\n"
132 ocl_icd_header += "# define CL_USE_DEPRECATED_OPENCL_1_0_APIS\n"
133 ocl_icd_header += "# define CL_USE_DEPRECATED_OPENCL_1_1_APIS\n"
134 ocl_icd_header += "# include <CL/opencl.h>\n"
135 ocl_icd_header += self.include_headers
136 ocl_icd_header += "#pragma GCC diagnostic pop\n"
137 ocl_icd_header += <<EOF
139 #define OCL_ICD_API_VERSION 1
140 #define OCL_ICD_IDENTIFIED_FUNCTIONS #{$known_entries.count}
142 struct _cl_icd_dispatch {
144 $api_entries_array.each { |entry|
145 ocl_icd_header += entry.gsub("\r","").
146 sub(/CL_API_CALL\n?(.*?)\(/m,'(CL_API_CALL*\1)('+"\n ").
147 gsub(/\) (CL_API_SUFFIX__VERSION)/m,"\n) \\1").gsub(/\s*$/,'').
148 gsub(/^[\t ]+/," ").gsub(/^([^\t ])/, ' \1') + "\n\n"
150 ocl_icd_header += "};\n\n"
151 return ocl_icd_header
154 def self.generate_ocl_icd_loader_header
155 ocl_icd_header = "/**\n#{$license}\n*/\n\n"
156 ocl_icd_header += "#include \"ocl_icd.h\"\n\n"
157 ocl_icd_header += <<EOF
161 void(*const addr)(void);
164 extern const struct func_desc function_description[];
167 ocl_icd_header += "extern struct _cl_icd_dispatch master_dispatch;\n"
168 $cl_objects.each { |o|
169 ocl_icd_header += "struct _cl_#{o} { struct _cl_icd_dispatch *dispatch; };\n"
171 return ocl_icd_header
174 def self.generate_ocl_icd_bindings_source
175 ocl_icd_bindings_source = "/**\n#{$license}\n*/\n"
176 ocl_icd_bindings_source += "#include \"ocl_icd.h\"\n"
177 ocl_icd_bindings_source += "struct _cl_icd_dispatch master_dispatch = {\n"
178 ($api_entries.length+$buff-1).times { |i|
179 if( $known_entries[i] ) then
180 ocl_icd_bindings_source += " #{$known_entries[i]},\n"
182 ocl_icd_bindings_source += " (void *) NULL,\n"
185 if( $known_entries[$api_entries.length+$buff-1] ) then
186 ocl_icd_bindings_source += " #{$known_entries[i]}\n"
188 ocl_icd_bindings_source += " (void *) NULL\n"
190 ocl_icd_bindings_source += "};\n"
191 ocl_icd_bindings_source += <<EOF
193 CL_API_ENTRY cl_int CL_API_CALL clIcdGetPlatformIDsKHR(
195 cl_platform_id *platforms,
196 cl_uint *num_platforms) {
197 if( platforms == NULL && num_platforms == NULL )
198 return CL_INVALID_VALUE;
199 if( num_entries == 0 && platforms != NULL )
200 return CL_INVALID_VALUE;
201 #error You have to fill the commented lines with corresponding variables from your library
202 // if( your_number_of_platforms == 0)
203 // return CL_PLATFORM_NOT_FOUND_KHR;
204 // if( num_platforms != NULL )
205 // *num_platforms = your_number_of_platforms;
206 if( platforms != NULL ) {
208 // for( i=0; i<(your_number_of_platforms<num_entries?your_number_of_platforms:num_entries); i++)
209 // platforms[i] = &your_platforms[i];
214 CL_API_ENTRY void * CL_API_CALL clGetExtensionFunctionAddress(
215 const char * func_name) CL_API_SUFFIX__VERSION_1_0 {
216 #error You have to fill this function with your extensions of incorporate these lines in your version
217 if( func_name != NULL && strcmp("clIcdGetPlatformIDsKHR", func_name) == 0 )
218 return (void *)clIcdGetPlatformIDsKHR;
221 CL_API_ENTRY cl_int CL_API_CALL clGetPlatformInfo(
222 cl_platform_id platform,
223 cl_platform_info param_name,
224 size_t param_value_size,
226 size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0 {
227 #error You ahve to fill this function with your information or assert that your version responds to CL_PLATFORM_ICD_SUFFIX_KHR
228 // char cl_platform_profile[] = "FULL_PROFILE";
229 // char cl_platform_version[] = "OpenCL 1.1";
230 // char cl_platform_name[] = "DummyCL";
231 // char cl_platform_vendor[] = "LIG";
232 // char cl_platform_extensions[] = "cl_khr_icd";
233 // char cl_platform_icd_suffix_khr[] = "DUMMY";
236 if( platform != NULL ) {
239 for(i=0; i<num_master_platforms; i++) {
240 if( platform == &master_platforms[i] )
244 return CL_INVALID_PLATFORM;
246 switch ( param_name ) {
247 case CL_PLATFORM_PROFILE:
248 string_p = cl_platform_profile;
249 size_string = sizeof(cl_platform_profile);
251 case CL_PLATFORM_VERSION:
252 string_p = cl_platform_version;
253 size_string = sizeof(cl_platform_version);
255 case CL_PLATFORM_NAME:
256 string_p = cl_platform_name;
257 size_string = sizeof(cl_platform_name);
259 case CL_PLATFORM_VENDOR:
260 string_p = cl_platform_vendor;
261 size_string = sizeof(cl_platform_vendor);
263 case CL_PLATFORM_EXTENSIONS:
264 string_p = cl_platform_extensions;
265 size_string = sizeof(cl_platform_extensions);
267 case CL_PLATFORM_ICD_SUFFIX_KHR:
268 string_p = cl_platform_icd_suffix_khr;
269 size_string = sizeof(cl_platform_icd_suffix_khr);
272 return CL_INVALID_VALUE;
275 if( param_value != NULL ) {
276 if( size_string > param_value_size )
277 return CL_INVALID_VALUE;
278 memcpy(param_value, string_p, size_string);
280 if( param_value_size_ret != NULL )
281 *param_value_size_ret = size_string;
285 return ocl_icd_bindings_source
288 def self.generate_ocl_icd_loader_gen_source
289 skip_funcs = $specific_loader_funcs
290 ocl_icd_loader_gen_source = "/**\n#{$license}\n*/\n"
291 ocl_icd_loader_gen_source += "#include \"ocl_icd_loader.h\"\n"
292 ocl_icd_loader_gen_source += "#define DEBUG_OCL_ICD_PROVIDE_DUMP_FIELD\n"
293 ocl_icd_loader_gen_source += "#include \"ocl_icd_debug.h\"\n"
294 ocl_icd_loader_gen_source += ""
295 $api_entries.each { |func_name, entry|
296 next if skip_funcs.include?(func_name)
297 clean_entry = entry.sub(/(.*\)).*/m,'\1').gsub("/*","").gsub("*/","").gsub("\r","") + "{\n"
298 parameters = clean_entry.match(/\(.*\)/m)[0][1..-2]
299 parameters.gsub!(/\[.*?\]/,"")
300 parameters.sub!(/\(.*?\*\s*(.*?)\)\s*\(.*?\)/,'\1')
301 ocl_icd_loader_gen_source += clean_entry.gsub(/\[.*?\]/,"")
302 first_parameter = parameters.match(/.*?\,/m)
303 if not first_parameter then
304 first_parameter = parameters.match(/.*/m)[0]
306 first_parameter = first_parameter[0][0..-2]
308 fps = first_parameter.split
309 ocl_icd_loader_gen_source += " debug_trace();\n"
310 ocl_icd_loader_gen_source += " RETURN(((struct _#{fps[0]} *)#{fps[1]})->dispatch->#{func_name}("
311 ps = parameters.split(",")
312 ps = ps.collect { |p|
314 p = p[-1].gsub("*","")
316 ocl_icd_loader_gen_source += ps.join(", ")
317 ocl_icd_loader_gen_source += "));\n"
318 ocl_icd_loader_gen_source += "}\n\n"
320 ocl_icd_loader_gen_source += "#pragma GCC visibility push(hidden)\n\n"
321 skip_funcs = $specific_loader_funcs
322 $api_entries.each { |func_name, entry|
323 #next if func_name.match(/EXT$/)
324 #next if func_name.match(/KHR$/)
325 if (skip_funcs.include?(func_name)) then
326 ocl_icd_loader_gen_source += "extern typeof(#{func_name}) #{func_name}_hid;\n"
328 ocl_icd_loader_gen_source += "typeof(#{func_name}) #{func_name}_hid __attribute__ ((alias (\"#{func_name}\"), visibility(\"hidden\")));\n"
331 ocl_icd_loader_gen_source += "\n\nstruct func_desc const function_description[]= {\n"
332 $api_entries.each { |func_name, entry|
333 #next if func_name.match(/EXT$/)
334 #next if func_name.match(/KHR$/)
335 ocl_icd_loader_gen_source += " {\"#{func_name}\", (void(* const)(void))&#{func_name}_hid },\n"
337 ocl_icd_loader_gen_source += <<EOF
342 void dump_platform(clGEFA_t f, cl_platform_id pid) {
343 debug(D_ALWAYS, "platform @%p: name=field_in_struct [clGetExtensionFunctionAddress(name)/clGetExtensionFunctionAddressForPlatform(name)]", pid);
345 $api_entries_array.each { |entry|
346 e = entry.gsub("\r"," ").gsub("\n"," ").gsub("\t"," ").
347 sub(/.*CL_API_CALL *([^ ()]*)[ ()].*$/m, '\1')
348 ocl_icd_loader_gen_source += " dump_field(pid, f, #{e});\n"
351 ocl_icd_loader_gen_source += <<EOF
355 #pragma GCC visibility pop
358 return ocl_icd_loader_gen_source;
361 def self.generate_libdummy_icd_header
362 libdummy_icd_structures = "/**\n#{$license}\n*/\n"
363 libdummy_icd_structures += "#include <CL/opencl.h>\n"
364 libdummy_icd_structures += self.include_headers
365 libdummy_icd_structures += "\n\nstruct _cl_icd_dispatch;\n"
366 libdummy_icd_structures += "struct _cl_platform_id { struct _cl_icd_dispatch *dispatch; };\n\n"
367 libdummy_icd_structures += "struct _cl_icd_dispatch {\n"
368 ($api_entries.length+$buff).times { |i|
369 if( $known_entries[i] ) then
370 libdummy_icd_structures += " void(*known#{i})(void);\n"
372 libdummy_icd_structures += " void(*unknown#{i})(void);\n"
375 libdummy_icd_structures += "};\n\n"
376 libdummy_icd_structures += "#pragma GCC visibility push(hidden)\n\n"
377 libdummy_icd_structures += "struct _cl_icd_dispatch master_dispatch; \n\n"
378 $known_entries.each { |k, f|
379 libdummy_icd_structures += "typeof(#{f}) INT#{f};\n"
381 libdummy_icd_structures += "#pragma GCC visibility pop\n\n"
382 return libdummy_icd_structures
385 def self.generate_libdummy_icd_source
386 libdummy_icd_source = "/**\n#{$license}\n*/\n\n"
387 libdummy_icd_source += "#include <stdio.h>\n\n"
388 libdummy_icd_source += "#include \"libdummy_icd_gen.h\"\n\n"
389 libdummy_icd_source += "#include \"libdummy_icd.h\"\n\n"
390 (0...$api_entries.length+$buff).each { |i|
391 libdummy_icd_source += "void dummyFunc#{i}(void){ printf(\"#{i} : \"); fflush(NULL); }\n"
393 libdummy_icd_source += "\nstruct _cl_icd_dispatch master_dispatch = {\n"
395 ($api_entries.length+$buff).times { |i|
396 comma="" if (i == $api_entries.length+$buff-1)
397 if( $known_entries[i] ) then
398 libdummy_icd_source += " (void(*)(void))& INT#{$known_entries[i]}#{comma}\n"
400 libdummy_icd_source += " (void(*)(void))& dummyFunc#{i}#{comma}\n"
403 libdummy_icd_source += "};\n"
404 return libdummy_icd_source
407 def self.generate_run_dummy_icd_weak_source
408 run_dummy_icd_weak = "/**\n#{$license}\n*/\n"
409 run_dummy_icd_weak += <<EOF
410 #define _GNU_SOURCE 1
415 __attribute__((weak)) int f (void* arg, void* arg2) { \\
416 void (* p)(void*, void*)=NULL; \\
417 p=dlsym(RTLD_NEXT, #f); \\
427 $api_entries.each_key { |func_name|
428 next if $noweak_funcs.include?(func_name)
429 run_dummy_icd_weak += "F(#{func_name})\n"
431 return run_dummy_icd_weak
433 def self.generate_run_dummy_icd_source
434 run_dummy_icd = "/**\n#{$license}\n*/\n"
435 run_dummy_icd += "#include <stdlib.h>\n"
436 run_dummy_icd += "#include <stdio.h>\n"
437 run_dummy_icd += "#pragma GCC diagnostic push\n"
438 run_dummy_icd += "# pragma GCC diagnostic ignored \"-Wcpp\"\n"
439 run_dummy_icd += "# define CL_USE_DEPRECATED_OPENCL_1_0_APIS\n"
440 run_dummy_icd += "# define CL_USE_DEPRECATED_OPENCL_1_1_APIS\n"
441 run_dummy_icd += "# include <CL/opencl.h>\n"
442 run_dummy_icd += self.include_headers
443 run_dummy_icd += "#pragma GCC diagnostic pop\n"
444 run_dummy_icd += "\n\n"
445 run_dummy_icd += "typedef CL_API_ENTRY cl_int (CL_API_CALL* oclFuncPtr_fn)(cl_platform_id platform);\n\n"
446 run_dummy_icd += "void call_all_OpenCL_functions(cl_platform_id chosen_platform) {\n"
447 run_dummy_icd += " oclFuncPtr_fn oclFuncPtr;\n"
448 run_dummy_icd += " cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)chosen_platform, 0 };\n"
449 $api_entries.each_key { |func_name|
450 next if $forbidden_funcs.include?(func_name)
451 if func_name == "clCreateContext" then
452 run_dummy_icd += " #{func_name}(properties,1,(cl_device_id*)&chosen_platform,NULL,NULL,NULL);\n"
453 elsif func_name == "clGetGLContextInfoKHR" then
454 run_dummy_icd += " #{func_name}(properties,CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, 0, NULL, NULL);\n"
455 elsif func_name == "clCreateContextFromType" then
456 run_dummy_icd += " #{func_name}(properties,CL_DEVICE_TYPE_CPU,NULL,NULL,NULL);\n"
457 elsif func_name == "clWaitForEvents" then
458 run_dummy_icd += " #{func_name}(1,(cl_event*)&chosen_platform);\n"
459 elsif func_name == "clGetExtensionFunctionAddressForPlatform" then
460 run_dummy_icd += " #{func_name}((cl_platform_id)chosen_platform, \"clIcdGetPlatformIDsKHR\");\n"
462 run_dummy_icd += " oclFuncPtr = (oclFuncPtr_fn)" + func_name + ";\n"
463 run_dummy_icd += " oclFuncPtr(chosen_platform);\n"
465 run_dummy_icd += " printf(\"%s\\n\", \"#{func_name}\");"
466 run_dummy_icd += " fflush(NULL);\n"
468 run_dummy_icd += " return;\n}\n"
472 def self.generate_ocl_icd_loader_map
473 ocl_icd_loader_map = "/**\n#{$license}\n*/\n\n"
475 $versions_entries.keys.sort.each { |version|
476 ocl_icd_loader_map += "OPENCL_#{version.sub('_','.')} {\n";
477 ocl_icd_loader_map += " global:\n";
478 $versions_entries[version].each { |symb|
479 ocl_icd_loader_map += " #{symb};\n"
481 if (prev_version == "") then
482 ocl_icd_loader_map += " local:\n";
483 ocl_icd_loader_map += " *;\n";
485 ocl_icd_loader_map += "} #{prev_version};\n\n";
486 prev_version="OPENCL_#{version.sub('_','.')}";
488 return ocl_icd_loader_map
491 def self.generate_sources
493 File.open('libdummy_icd_gen.h','w') { |f|
494 f.puts generate_libdummy_icd_header
496 File.open('libdummy_icd_gen.c','w') { |f|
497 f.puts generate_libdummy_icd_source
499 File.open('run_dummy_icd_gen.c','w') { |f|
500 f.puts generate_run_dummy_icd_source
502 File.open('run_dummy_icd_weak.c','w') { |f|
503 f.puts generate_run_dummy_icd_weak_source
507 def self.savedb(yamlfile)
510 File::open(yamlfile,"r") { |f|
511 api_db = YAML::load(f.read)
512 # puts api_db.inspect
517 $known_entries.each_key {|i|
519 api_db[i] = $api_entries[$known_entries[i]].gsub("\r","")
521 File::open(yamlfile,"w") { |f|
522 f.write($license.gsub(/^/,"# "))
525 # In Intel (OpenCL 1.1):
526 # * clSetCommandQueueProperty(13): nil (deprecated in 1.1)
527 # * clGetGLContextInfoKHR(74): function present with its symbol
529 # * 92: correspond to symbol clGetKernelArgInfo (first abandonned version?)
531 # In nvidia (OpenCL 1.1):
532 # * clGetGLContextInfoKHR(74): function present but no symbol
535 # * only two OpenCL symbols: clGetPlatformInfo(1) and clGetExtensionFunctionAddress(65)
536 # In AMD (OpenCL 1.2):
537 # * clGetPlatformIDs(0): nil (symbol present)
538 # * clGetGLContextInfoKHR(74): function present but no symbol
546 # Not using YAML::dump as:
547 # * keys are not ordered
548 # * strings are badly formatted in new YAML ruby implementation (psych)
549 # * it is very easy to do it ourself
550 #f.write(YAML::dump(api_db))
552 api_db.keys.sort.each { |k|
553 f.write("\n#{k}: |-\n ")
554 f.write(api_db[k].gsub("\n","\n "))
560 def self.finalize(yamlfile)
562 doc = YAML::load(`./run_dummy_icd`)
564 $known_entries.merge!(doc)
565 self.savedb(yamlfile)
567 $api_entries_array = []
568 ($known_entries.length+$buff).times { |i|
569 #puts $known_entries[i]
570 if $known_entries[i] then
571 $api_entries_array.push( $api_entries[$known_entries[i]] )
573 $api_entries_array.push( "CL_API_ENTRY cl_int CL_API_CALL clUnknown#{i}(void);" )
579 def self.generate_from_database(yamlfile)
581 File::open(yamlfile) { |f|
582 doc = YAML:: load(f.read)
586 $versions_entries = Hash::new { |hash,key| hash[key]=[] }
589 doc.each { |key, value|
591 entry_name = value.match(/CL_API_CALL(.*?)\(/m)[1].strip
593 entry_name = value.match(/(\S*?)\(/m)[1].strip
595 next if $windows_funcs.include?(entry_name)
596 version = value.match(/SUFFIX__VERSION_(\d_\d)/m)[1]
597 $versions_entries[version].push(entry_name)
598 $known_entries[key] = entry_name
599 $api_entries[entry_name] = value
601 $api_entries_array = []
603 ($known_entries.length+$buff).times { |i|
604 #puts $known_entries[i]
605 if $known_entries[i] then
606 $api_entries_array.push( $api_entries[$known_entries[i]] )
608 $api_entries_array.push( "CL_API_ENTRY cl_int CL_API_CALL clUnknown#{i}(void);" )
612 File.open('ocl_icd.h','w') { |f|
613 f.puts generate_ocl_icd_header
615 File.open('ocl_icd_loader.h','w') { |f|
616 f.puts generate_ocl_icd_loader_header
618 File.open('ocl_icd_loader.map','w') { |f|
619 f.puts generate_ocl_icd_loader_map
621 File.open('ocl_icd_bindings.c','w') { |f|
622 f.puts generate_ocl_icd_bindings_source
624 File.open('ocl_icd_loader_gen.c','w') { |f|
625 f.puts generate_ocl_icd_loader_gen_source
633 OptionParser.new do |opts|
634 opts.banner = "Usage: cd_generator.rb [options] mode"
636 opts.on("-f", "--file FILE", String, "YAML file (default ocl_interface.yaml)") do |v|
639 opts.on("-m", "--mode [MODE]", [:database, :generate, :finalize],
640 "Select mode (database, generate, finalize)") do |m|
645 if !options[:file] then
646 options[:file] = "ocl_interface.yaml"
649 if !options[:mode] then
650 raise "--mode option required"
652 if options[:mode] == :generate then
653 IcdGenerator.generate_sources
654 elsif options[:mode] == :finalize then
655 IcdGenerator.finalize(options[:file])
656 elsif options[:mode] == :database then
657 IcdGenerator.generate_from_database(options[:file])
659 raise "Mode must be one of generate, database or finalize not #{options[:mode]}"