aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/dictionary.dic1
-rwxr-xr-xtools/genspec.py68
-rwxr-xr-xtools/get_descriptions.py9
-rw-r--r--tools/tosa.py97
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)