9
9
from fileinput import FileInput
10
10
import util
11
11
import yaml
12
+ import re
13
+ import copy
12
14
13
15
ENUM_NAME = '$x_function_t'
14
16
@@ -18,36 +20,99 @@ class quoted(str):
18
20
def quoted_presenter (dumper , data ):
19
21
return dumper .represent_scalar ('tag:yaml.org,2002:str' , data , style = '"' )
20
22
23
+ def get_registry_header ():
24
+ return {'type' : 'header' , 'desc' : quoted ('Intel $OneApi Unified Runtime function registry' ), 'ordinal' : quoted (- 1 )}
25
+
21
26
def write_registry (data , path ):
22
- header = {'type' : 'header' , 'desc' : quoted ('Intel $OneApi Unified Runtime function registry' ), 'ordinal' : quoted (- 1 )}
23
- data .insert (0 , header )
24
27
with open (path , 'w' ) as fout :
25
28
yaml .add_representer (quoted , quoted_presenter )
26
29
yaml .dump_all (data , fout ,
27
30
default_flow_style = False ,
28
31
sort_keys = False ,
29
32
explicit_start = True )
30
33
34
+ def find_type_in_specs (specs , type ):
35
+ return [obj for s in specs for obj in s ['objects' ] if obj ['name' ] == type ][0 ]
36
+
37
+ def get_max_enum (enum ):
38
+ return int (max (enum ['etors' ], key = lambda x : int (x ['value' ]))['value' ])
39
+
40
+ def copy_and_strip_prefix_from_enums (enum , prefix ):
41
+ cpy = copy .deepcopy (enum )
42
+ for etor in cpy ['etors' ]:
43
+ etor ['name' ] = etor ['name' ][len (prefix ):]
44
+ return cpy
45
+
46
+
47
+ def generate_function_type (specs , meta , update_fn ) -> dict :
48
+ existing_function_type = find_type_in_specs (specs , '$x_function_t' )
49
+ existing_etors = {etor ['name' ] : etor ['value' ] for etor in existing_function_type ['etors' ]}
50
+ max_etor = get_max_enum (existing_function_type )
51
+ functions = [obj ['class' ][len ('$x' ):] + obj ['name' ] for s in specs for obj in s ['objects' ] if obj ['type' ] == 'function' ]
52
+ registry = list ()
53
+ for fname in functions :
54
+ etor_name = "$X_FUNCTION_" + util .to_snake_case (fname ).upper ()
55
+ id = existing_etors .get (etor_name )
56
+ if id is None :
57
+ max_etor += 1
58
+ id = max_etor
59
+ registry .append ({
60
+ 'name' : etor_name ,
61
+ 'desc' : f'Enumerator for $x{ fname } ' ,
62
+ 'value' : str (id )}
63
+ )
64
+ registry = sorted (registry , key = lambda x : int (x ['value' ]))
65
+ existing_function_type ['etors' ] = registry
66
+ update_fn (existing_function_type , meta )
67
+
68
+ ## create a copy to write back to registry.yml
69
+ return copy_and_strip_prefix_from_enums (existing_function_type , '$X_FUNCTION_' )
70
+
71
+
72
+ def generate_structure_type (specs , meta , refresh_fn ) -> dict :
73
+ structure_type = find_type_in_specs (specs , '$x_structure_type_t' )
74
+ extended_structs = [obj for s in specs for obj in s ['objects' ] if re .match (r"struct|union" , obj ['type' ]) and 'base' in obj ]
75
+ max_enum = get_max_enum (structure_type )
76
+
77
+ structure_type_etors = list ()
78
+ for struct in extended_structs :
79
+ # skip experimental enumerations
80
+ if struct ['name' ].startswith ('$x_exp_' ):
81
+ continue
82
+
83
+ etor = [mem for mem in struct ['members' ] if mem ['name' ] == 'stype' ][0 ]['init' ]
84
+
85
+ # try and match the etor
86
+ matched_etor = [e for e in structure_type ['etors' ] if e ['name' ] == etor ]
87
+
88
+ out_etor = {
89
+ 'name' : etor ,
90
+ 'desc' : struct ['name' ]
91
+ }
92
+
93
+ # if no match exists we assign it a new value
94
+ if len (matched_etor ) == 0 :
95
+ max_enum += 1
96
+ out_etor ['value' ] = str (max_enum )
97
+ else :
98
+ out_etor ['value' ] = matched_etor [0 ]['value' ]
99
+
100
+ structure_type_etors .append (out_etor )
101
+
102
+ structure_type_etors = sorted (structure_type_etors , key = lambda x : int (x ['value' ]))
103
+ structure_type ['etors' ] = structure_type_etors
104
+ refresh_fn (structure_type , meta )
105
+
106
+ ## create a copy to write back to registry.yml
107
+ return copy_and_strip_prefix_from_enums (structure_type , '$X_STRUCTURE_TYPE_' )
31
108
32
- def generate_registry (path , specs ):
109
+ def generate_registry (path , specs , meta , update_fn ):
33
110
try :
34
- contents = list (util .yamlRead (path ))
35
- existing_registry = contents [1 ]['etors' ]
36
- existing_etors = {etor ["name" ]: etor ["value" ] for etor in existing_registry }
37
- max_etor = int (max (existing_registry , key = lambda x : int (x ["value" ]))["value" ])
38
- functions = [obj ['class' ][len ('$x' ):] + obj ['name' ] for s in specs for obj in s ['objects' ] if obj ['type' ] == 'function' ]
39
- registry = list ()
40
- for fname in functions :
41
- etor_name = util .to_snake_case (fname ).upper ()
42
- id = existing_etors .get (etor_name )
43
- if id is None :
44
- max_etor += 1
45
- id = max_etor
46
- registry .append ({'name' : util .to_snake_case (fname ).upper (), 'desc' : 'Enumerator for $x' + fname , 'value' : str (id )})
47
- registry = sorted (registry , key = lambda x : int (x ['value' ]))
48
- wrapper = { 'name' : ENUM_NAME , 'type' : 'enum' , 'desc' : 'Defines unique stable identifiers for all functions' , 'etors' : registry }
49
- contents [1 ] = wrapper
50
- write_registry (contents [1 :], path )
111
+ write_registry ([
112
+ get_registry_header (),
113
+ generate_function_type (specs , meta , update_fn ),
114
+ generate_structure_type (specs , meta , update_fn )
115
+ ], path )
51
116
52
117
except BaseException as e :
53
118
print ("Failed to generate registry.yml... %s" , e )
0 commit comments