Skip to content

Commit 2f73f77

Browse files
author
Petr Vesely
committed
[UR] Generate structure type along with function type
1 parent bd76766 commit 2f73f77

File tree

2 files changed

+87
-74
lines changed

2 files changed

+87
-74
lines changed

scripts/generate_ids.py

Lines changed: 85 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from fileinput import FileInput
1010
import util
1111
import yaml
12+
import re
13+
import copy
1214

1315
ENUM_NAME = '$x_function_t'
1416

@@ -18,36 +20,99 @@ class quoted(str):
1820
def quoted_presenter(dumper, data):
1921
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"')
2022

23+
def get_registry_header():
24+
return {'type': 'header', 'desc': quoted('Intel $OneApi Unified Runtime function registry'), 'ordinal': quoted(-1)}
25+
2126
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)
2427
with open(path, 'w') as fout:
2528
yaml.add_representer(quoted, quoted_presenter)
2629
yaml.dump_all(data, fout,
2730
default_flow_style=False,
2831
sort_keys=False,
2932
explicit_start=True)
3033

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_')
31108

32-
def generate_registry(path, specs):
109+
def generate_registry(path, specs, meta, update_fn):
33110
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)
51116

52117
except BaseException as e:
53118
print("Failed to generate registry.yml... %s", e)

scripts/parse_specs.py

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -853,54 +853,6 @@ def sort_etors(x):
853853
return value
854854
matching_enum['etors'] = sorted(matching_enum['etors'], key=sort_etors)
855855

856-
def _generate_structure_type_t(specs, meta, registry):
857-
extended_structs = [obj for s in specs for obj in s['objects'] if re.match(r"struct|union", obj['type']) and 'base' in obj]
858-
ur_structure_type_t = [obj for s in specs for obj in s['objects'] if obj['name'] == "$x_structure_type_t"][0]
859-
existing_etors = ur_structure_type_t['etors']
860-
max_enum = int(max(ur_structure_type_t['etors'], key= lambda x : int(x['value']))['value'])
861-
862-
out_etors = []
863-
for struct in extended_structs:
864-
# skip experimental enumerations
865-
if struct['name'].startswith("$x_exp_"):
866-
continue
867-
868-
# name of the etor
869-
etor = [mem for mem in struct['members'] if mem['name'] == 'stype'][0]['init']
870-
871-
# try and match the etor
872-
matched_etor = [e for e in existing_etors if e['name'] == etor]
873-
874-
# if no match exists then we have to add it
875-
if len(matched_etor) == 0:
876-
max_enum += 1
877-
out_etors.append({
878-
"name": etor,
879-
"desc": struct['name'],
880-
"value": str(max_enum)
881-
})
882-
else:
883-
out_etors.append({
884-
"name": etor,
885-
"desc": struct['name'],
886-
"value": matched_etor[0]['value']
887-
})
888-
889-
out_etors = sorted(out_etors, key = lambda x : int(x['value']))
890-
ur_structure_type_t['etors'] = out_etors
891-
_refresh_enum_meta(ur_structure_type_t, meta)
892-
893-
## write the result out to the yml file
894-
try:
895-
contents = list(util.yamlRead(registry))
896-
cpy = copy.deepcopy(ur_structure_type_t)
897-
for e in cpy['etors']:
898-
e['name'] = e['name'][len("$X_STRUCTURE_TYPE_"):]
899-
contents[2] = cpy
900-
generate_ids.write_registry(contents[1:], registry)
901-
except:
902-
raise
903-
904856
"""
905857
Entry-point:
906858
Reads each YML file and extracts data
@@ -911,13 +863,10 @@ def parse(section, version, tags, meta, ref):
911863
specs = []
912864

913865
files = util.findFiles(path, "*.yml")
914-
# make sure registry is last, because it's autogenerated based on the rest of the spec
915-
files = sorted(files, key=lambda f: 1 if f.endswith('registry.yml') else 0)
866+
registry = [f for f in files if f.endswith('registry.yml')][0]
916867

917868
enum_extensions = []
918869
for f in files:
919-
if f.endswith('registry.yml'):
920-
generate_ids.generate_registry(f, specs)
921870

922871
print("Parsing %s..."%f)
923872
docs = util.yamlRead(f)
@@ -970,8 +919,7 @@ def parse(section, version, tags, meta, ref):
970919

971920
specs = sorted(specs, key=lambda s: s['header']['ordinal'])
972921
_inline_extended_structs(specs, meta)
973-
registry = [f for f in files if f.endswith('registry.yml')][0]
974-
_generate_structure_type_t(specs, meta, registry)
922+
generate_ids.generate_registry(registry, specs, meta, _refresh_enum_meta)
975923
_extend_enums(enum_extensions, specs, meta)
976924
_generate_extra(specs, meta)
977925

0 commit comments

Comments
 (0)