diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/dictionary.dic | 1 | ||||
-rwxr-xr-x | tools/genspec.py | 68 | ||||
-rwxr-xr-x | tools/get_descriptions.py | 9 | ||||
-rw-r--r-- | tools/tosa.py | 97 |
4 files changed, 169 insertions, 6 deletions
diff --git a/tools/dictionary.dic b/tools/dictionary.dic index b062ac2..5f53b0c 100644 --- a/tools/dictionary.dic +++ b/tools/dictionary.dic @@ -1,5 +1,6 @@ personal_ws-1.1 en 500 activations +adoc ARGMAX AsciiDoc BILINEAR diff --git a/tools/genspec.py b/tools/genspec.py new file mode 100755 index 0000000..c871b75 --- /dev/null +++ b/tools/genspec.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +import os + +import tosa + + +class TOSASpecAsciidocGenerator: + def __init__(self, spec): + self.spec = spec + + def generate_operator(self, op, file): + file.write("\n*Arguments:*\n") + file.write("\n|===\n") + file.write("|Argument|Type|Name|Shape|Description\n\n") + for arg in op.arguments: + cats = arg.categories + if len(cats) > 1: + cattext = "" + sep = "" + for cat in cats: + proflist = "/".join(cat.profiles) + profcaption = "profiles" if len(cat.profiles) > 1 else "profile" + cattext += sep + cat.name.title() + f" ({proflist} {profcaption})" + sep = " " + else: + cattext = cats[0].name.title() + file.write( + f"|{cattext}|{arg.type}|{arg.name}|{arg.shape}|{arg.description}\n" + ) + file.write("|===\n") + if op.typesupports: + file.write("\n*Supported Data Types:*\n\n") + file.write("|===\n") + header = "|Profile|Mode" + for ty in op.types: + header += f"|{ty}" + file.write(header) + file.write("\n\n") + for tysup in op.typesupports: + profile = ", ".join(tysup.profiles) if tysup.profiles else "Any" + entry = f"|{profile}|{tysup.mode}" + for ty in op.types: + entry += f"|{tysup.tymap[ty]}" + entry += "\n" + file.write(entry) + file.write("|===\n") + + def generate(self, outdir): + opdir = os.path.join(outdir, "operators") + os.makedirs(opdir, exist_ok=True) + for group in self.spec.operatorgroups: + for op in group.operators: + with open(os.path.join(opdir, op.name + ".adoc"), "w") as f: + self.generate_operator(op, f) + + +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser() + parser.add_argument("--xml", required=True, help="Path to specification XML") + parser.add_argument("--outdir", required=True, help="Output directory") + args = parser.parse_args() + + spec = tosa.TOSASpec(args.xml) + + generator = TOSASpecAsciidocGenerator(spec) + generator.generate(args.outdir) diff --git a/tools/get_descriptions.py b/tools/get_descriptions.py index beded87..0a39a19 100755 --- a/tools/get_descriptions.py +++ b/tools/get_descriptions.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 - # Copyright (c) 2022, ARM Limited. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,10 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - # Script to pull the descriptions out of the specification so that # they can be run through a spellcheck with less noise - import argparse import re @@ -40,17 +37,17 @@ for name in args.filenames: continue if not in_description: # Look for the start of an operator - if re.match(r'^===', text): + if re.match(r"^===", text): in_description = True print(text) else: # Stop when we get to a subsection like *Arguments* # or pseudocode in a [source] section. Spellcheck is # not useful there - if re.match(r'[\[\*]', text): + if re.match(r"[\[\*]", text): in_description = False # skip comments - elif re.match(r'\w*\/\/', text): + elif re.match(r"\w*\/\/", text): continue else: print(text) diff --git a/tools/tosa.py b/tools/tosa.py new file mode 100644 index 0000000..87b4f1a --- /dev/null +++ b/tools/tosa.py @@ -0,0 +1,97 @@ +import re +import xml.etree.ElementTree as ET + + +class TOSAOperatorArgumentCategory: + def __init__(self, name, profiles=None): + self.name = name + self.profiles = profiles + + +class TOSAOperatorArgument: + def __init__(self, name, description, categories, ty, shape): + self.name = name + self.description = description + self.categories = categories + self.type = ty + self.shape = shape + + +class TOSAOperatorDataTypeSupport: + def __init__(self, mode, tymap, profiles=None): + self.mode = mode + self.tymap = tymap + self.profiles = profiles + + +class TOSAOperator: + def __init__(self, name, arguments, types, typesupports): + self.name = name + self.arguments = arguments + self.types = types + self.typesupports = typesupports + + +class TOSAOperatorGroup: + def __init__(self, name, operators): + self.name = name + self.operators = operators + + +class TOSASpec: + def __init__(self, xmlpath): + tree = ET.parse(xmlpath) + self.xmlroot = tree.getroot() + self.operatorgroups = [] + self.__load_spec() + + def __load_spec(self): + for group in self.xmlroot.findall("./operators/operatorgroup"): + self.operatorgroups.append(self.__load_operator_group(group)) + + def __load_operator_group(self, group): + name = group.get("name") + operators = [] + for op in group.findall("operator"): + operators.append(self.__load_operator(op)) + return TOSAOperatorGroup(name, operators) + + def __load_operator(self, op): + name = op.find("name").text + args = [] + types = [] + typesupports = [] + for arg in op.findall("arguments/argument"): + args.append(self.__load_operator_argument(arg)) + + # TODO add pseudo-code to operator object? + + for ty in op.findall("types/type"): + types.append(ty.get("name")) + + for tysup in op.findall("typesupport"): + tsmode = tysup.get("mode") + tsmap = {} + profiles = tysup.findall("profile") + tsprofiles = [] + for p in profiles: + tsprofiles.append(p.get("name")) + for ty in types: + tsmap[ty] = tysup.get(ty) + typesupports.append(TOSAOperatorDataTypeSupport(tsmode, tsmap, tsprofiles)) + return TOSAOperator(name, args, types, typesupports) + + def __load_operator_argument(self, arg): + name = arg.get("name") + desc = arg.find("description").text.strip() + argcats = [] + argtype = arg.get("type") + shape = arg.get("shape") + + cats = re.findall( + r"(input|output|attribute)\(?([A-Z,]+)?\)?", arg.get("category") + ) + for cat in cats: + argcats.append(TOSAOperatorArgumentCategory(cat[0], cat[1].split(","))) + + return TOSAOperatorArgument(name, desc, argcats, argtype, shape) |