From 42085e36b0b47209ca767a3b8300f689cb6ec0bf Mon Sep 17 00:00:00 2001 From: Eric Kunze Date: Mon, 9 Jan 2023 11:16:51 -0800 Subject: Add TOSA rank requirements to TOSA XML Adds new optional element to argument 'rank' - Must supply minimum and maximum rank - Integer values or the level based "MAX_RANK" - trailing modifiers allowed for "MAX_RANK" - Displays in a new column in the document - Document generation validates rank against specified shape Change-Id: I507dc51bfe012d3230af43103c6c423a6f1e92b5 Signed-off-by: Eric Kunze --- tools/genspec.py | 19 ++++- tools/tosa.py | 38 +++++++++- tosa.xml | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++---- tosa.xsd | 24 ++++++ 4 files changed, 287 insertions(+), 21 deletions(-) diff --git a/tools/genspec.py b/tools/genspec.py index f495296..c64f05b 100755 --- a/tools/genspec.py +++ b/tools/genspec.py @@ -3,7 +3,6 @@ import os import tosa - class TOSASpecAsciidocGenerator: def __init__(self, spec): self.spec = spec @@ -19,8 +18,9 @@ class TOSASpecAsciidocGenerator: def generate_operator(self, op, file): file.write("\n*Arguments:*\n") + file.write("[cols='2,1,1,1,2,4']") file.write("\n|===\n") - file.write("|Argument|Type|Name|Shape|Description\n\n") + file.write("|Argument|Type|Name|Shape|Rank|Description\n\n") for arg in op.arguments: cats = arg.categories if len(cats) > 1: @@ -33,8 +33,15 @@ class TOSASpecAsciidocGenerator: sep = " " else: cattext = cats[0].name.title() + if len(arg.rank) > 0: + if (arg.rank[0] == arg.rank[1]): + rank = f'{arg.rank[0]}' + else: + rank = f'{arg.rank[0]} to {arg.rank[1]}' + else: + rank = "" file.write( - f"|{cattext}|{arg.type}|{arg.name}|{arg.shape}|{arg.description}\n" + f"|{cattext}|{arg.type}|{arg.name}|{arg.shape}|{rank}|{arg.description}\n" ) file.write("|===\n") if op.typesupports: @@ -112,7 +119,11 @@ if __name__ == "__main__": parser.add_argument("--outdir", required=True, help="Output directory") args = parser.parse_args() - spec = tosa.TOSASpec(args.xml) + try: + spec = tosa.TOSASpec(args.xml) + except RuntimeError as e: + print(f"Failure reading/validating XML spec: {str(e)}") + exit(1) generator = TOSASpecAsciidocGenerator(spec) generator.generate(args.outdir) diff --git a/tools/tosa.py b/tools/tosa.py index bc6faa6..218412f 100644 --- a/tools/tosa.py +++ b/tools/tosa.py @@ -1,6 +1,22 @@ import re import xml.etree.ElementTree as ET +# possible shapes: shape1, [2], [N,H,W,C] +# returns (checkable, rank) +# checkable is false if shape doesn't contain [] +def get_rank_from_shape(shape): + if '[' not in shape or '[]' in shape: + return (False, -1) + # Check for fixed rank requirement [N] + m = re.match(r'\[(\d+)\]', shape) + if m: + return (True, 1) + # Check for comma separated rank descriptors, return count + m = re.match(r'\[(.*)\]', shape) + if m: + return (True, len(m.group(1).split(','))) + else: + raise RuntimeError(f'Unable to parse shape {shape}') class TOSAOperatorArgumentCategory: def __init__(self, name, profiles=None): @@ -20,13 +36,14 @@ class TOSALevel: self.maximums = maximums class TOSAOperatorArgument: - def __init__(self, name, description, categories, ty, shape, levellimits): + def __init__(self, name, description, categories, ty, shape, levellimits, rank): self.name = name self.description = description self.categories = categories self.type = ty self.shape = shape self.levellimits = levellimits + self.rank = rank class TOSAOperatorDataTypeSupport: @@ -103,7 +120,7 @@ class TOSASpec: types = [] typesupports = [] for arg in op.findall("arguments/argument"): - args.append(self.__load_operator_argument(arg)) + args.append(self.__load_operator_argument(arg, name)) # TODO add pseudo-code to operator object? @@ -122,13 +139,26 @@ class TOSASpec: typesupports.append(TOSAOperatorDataTypeSupport(tsmode, tsmap, tsprofiles)) return TOSAOperator(name, args, types, typesupports) - def __load_operator_argument(self, arg): + def __load_operator_argument(self, arg, op_name): name = arg.get("name") desc = arg.find("description").text.strip() argcats = [] argtype = arg.get("type") shape = arg.get("shape") levellimits = [] + rank = [] + r = arg.find("rank") + if r != None: + if shape == "-": + raise RuntimeError(f"rank is not empty, but shape is '-' for {op_name}: {name}") + rank = [r.get('min'),r.get('max')] + # validate rank against the shape argument + (shape_check, shape_rank) = get_rank_from_shape(shape) + if shape_check and (shape_rank < int(rank[0]) or shape_rank > int(rank[1])): + raise RuntimeError(f"Description of shape rank doesn't match XML rank min/max: {op_name} {name} shape: {shape} shape_rank: {shape_rank} min/max: {rank[0]} {rank[1]}") + else: + if shape != "-": + raise RuntimeError(f"Rank not present for {op_name}: {name} when shape is {shape}") for levellimit in arg.findall("levellimit"): value = levellimit.get("value") limit = levellimit.get("limit") @@ -140,7 +170,7 @@ class TOSASpec: for cat in cats: argcats.append(TOSAOperatorArgumentCategory(cat[0], cat[1].split(","))) - return TOSAOperatorArgument(name, desc, argcats, argtype, shape, levellimits) + return TOSAOperatorArgument(name, desc, argcats, argtype, shape, levellimits, rank) def __load_enum(self, arg): name = arg.get("name") diff --git a/tosa.xml b/tosa.xml index 7810127..5b863bb 100644 --- a/tosa.xml +++ b/tosa.xml @@ -19,12 +19,14 @@ Input tensor + - Axis in range from 0 to rank(shape1)-1 + Axis in range from 0 to rank(shape1) - 1 - Output tensor, with rank = rank(shape1)-1 + Output tensor, with rank = rank(shape1) - 1 + @@ -50,17 +52,20 @@ AVG_POOL2D - Input tensor 4D + Input tensor + [kernel_y, kernel_x] + [stride_y, stride_x] + [pad_top, pad_bottom, pad_left, pad_right] @@ -68,6 +73,7 @@ + Enumerated type, must be one of INT32, FP16, FP32, as defined in the Supported Data Types table for this operation @@ -80,6 +86,7 @@ Output tensor 4D + @@ -110,14 +117,17 @@ Input tensor + Weight kernel size KH x KW + Per output channel bias data. + [pad_top, pad_bottom, pad_left, pad_right] @@ -125,14 +135,17 @@ + [stride_y, stride_x] + [dilation_y, dilation_x] + Input tensor zero point. Must be zero for non-int8 types. @@ -142,6 +155,7 @@ Output tensor + @@ -174,15 +188,18 @@ Input tensor + Weight kernel size KDxKHxKW + Per output channel bias data. + [pad_d0, pad_d1, pad_top, pad_bottom, pad_left, pad_right] @@ -192,15 +209,18 @@ + [stride_d, stride_y, stride_x] + [dilation_d, dilation_y, dilation_x] + Input tensor zero point. Must be zero for non-int8 types. @@ -210,6 +230,7 @@ Output tensor + @@ -242,14 +263,17 @@ Input tensor + Weight kernel size KH x KW + Per output channel bias data. + [pad_top, pad_bottom, pad_left, pad_right] @@ -257,14 +281,17 @@ + [stride_y, stride_x] + [dilation_y, dilation_x] + Input tensor zero point. Must be zero for non-int8 types. @@ -274,6 +301,7 @@ Output tensor + @@ -308,18 +336,22 @@ Real part of the complex input. H,W must be powers of two. + Imaginary part of the complex input. H,W must be powers of two. + false for forward FFT, true for inverse FFT Real part of the complex output. + Imaginary part of the complex output. + @@ -335,12 +367,15 @@ Input tensor + Weights + Per output channel bias data. + Input tensor zero point. Must be zero for non-int8 types. @@ -350,6 +385,7 @@ Output tensor + @@ -382,9 +418,11 @@ Input tensor A, N matrices of size HxC + Input tensor B, N matrices of size CxW + Input tensor A zero point. Must be zero for non-int8 types. @@ -394,6 +432,7 @@ Output tensor, N matrices of size HxW + @@ -424,16 +463,19 @@ Input tensor 4D + [kernel_y, kernel_x] + [stride_y, stride_x] + [pad_top, pad_bottom, pad_left, pad_right] @@ -441,9 +483,11 @@ + Output tensor 4D + @@ -471,12 +515,15 @@ Real input. H,W must be powers of two. + Real part of the complex output + Imaginary part of the complex output. + @@ -492,14 +539,17 @@ Input tensor + Weight kernel size KH x KW + Per output channel bias data. + [out_pad_top, out_pad_bottom, out_pad_left, out_pad_right] @@ -507,14 +557,17 @@ + [stride_y, stride_x] + [N,OH,OW,OC] + Input tensor zero point. Must be zero for non-int8 types. @@ -524,6 +577,7 @@ Output tensor + @@ -559,6 +613,7 @@ Input tensor + Minimum clip value @@ -568,6 +623,7 @@ Output tensor of same type and shape as input + @@ -594,9 +650,11 @@ Input tensor + Output tensor of same type and shape as input + @@ -621,9 +679,11 @@ Input tensor + Output tensor of same type and shape as input + @@ -649,13 +709,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -680,9 +743,11 @@ Input tensor + Input tensor with the same rank as input1 + If true then the shift is rounded @@ -690,6 +755,7 @@ Output tensor with broadcast shape if necessary + @@ -704,13 +770,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -725,13 +794,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -746,13 +818,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -767,13 +842,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -786,13 +864,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -805,13 +886,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -826,13 +910,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -847,13 +934,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -866,13 +956,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -885,13 +978,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -916,13 +1012,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -947,9 +1046,11 @@ Input tensor + Input tensor with the same rank as input1 + Result right shift (int32_t data type only) @@ -957,6 +1058,7 @@ Output tensor with broadcast shape if necessary + @@ -984,13 +1086,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -1014,13 +1119,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -1045,13 +1153,16 @@ Input tensor + Lookup table tensor + Output tensor + @@ -1071,9 +1182,11 @@ Input tensor + Output tensor of same type, size as the input tensor + @@ -1099,9 +1212,11 @@ Input tensor + Output tensor of same type, size as the input tensor + @@ -1117,9 +1232,11 @@ Input tensor + Output tensor of same type, size as the input tensor + @@ -1144,9 +1261,11 @@ Input tensor + Output tensor of same type, size as the input tensor + @@ -1160,9 +1279,11 @@ Input tensor + Output tensor of same type, size as the input tensor + @@ -1187,9 +1308,11 @@ Input tensor + Output tensor of same type, size as the input tensor + @@ -1214,9 +1337,11 @@ Input tensor + Output tensor of same type, size as the input tensor + @@ -1241,9 +1366,11 @@ Input tensor + Output tensor of same type, size as the input tensor + @@ -1257,6 +1384,7 @@ Input tensor + Input 1 zero point. Must be zero for non-int8 types. @@ -1266,6 +1394,7 @@ Output tensor of same type, size as the input tensor + @@ -1294,9 +1423,11 @@ Input tensor + Output tensor of same type, size as the input tensor + @@ -1321,9 +1452,11 @@ Input tensor + Output tensor of same type, size as the input tensor + @@ -1349,16 +1482,20 @@ Input selector tensor + Input value tensor if input1 is True + Input value tensor if input1 is False + Output tensor of same type as input2 and input3, with broadcast shape if necessary + @@ -1388,13 +1525,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -1420,13 +1560,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -1452,13 +1595,16 @@ Input tensor + Input tensor with the same rank as input1 + Output tensor with broadcast shape if necessary + @@ -1485,13 +1631,15 @@ REDUCE_ALL - Input tensor with rank from 1 to 4 + Input tensor + Axis to reduce, in range from 0 to rank(shape1)-1 Output tensor. Same rank as the input tensor. + @@ -1503,13 +1651,15 @@ REDUCE_ANY - Input tensor with rank from 1 to 4 + Input tensor + Axis to reduce, in range from 0 to rank(shape1)-1 Output tensor. Same rank as the input tensor. + @@ -1521,13 +1671,15 @@ REDUCE_MAX - Input tensor with rank from 1 to 4 + Input tensor + Axis to reduce, in range from 0 to rank(shape1)-1 Output tensor. Same rank as the input tensor. + @@ -1553,13 +1705,15 @@ REDUCE_MIN - Input tensor with rank from 1 to 4 + Input tensor + Axis to reduce, in range from 0 to rank(shape1)-1 Output tensor. Same rank as the input tensor. + @@ -1585,13 +1739,15 @@ REDUCE_PRODUCT - Input tensor with rank from 1 to 4 + Input tensor + Axis to reduce, in range from 0 to rank(shape1)-1 Output tensor. Same rank as the input tensor. + @@ -1615,12 +1771,14 @@ Input tensor with rank from 1 to 4 + Axis to reduce, in range from 0 to rank(shape1)-1 Output tensor. Same rank as the input tensor. + @@ -1648,6 +1806,7 @@ List of input tensors. All inputs must have the same rank and data type + Axis along which concatenation is to occur, in range from 0 to rank(shape)-1 @@ -1655,6 +1814,7 @@ Output tensor + @@ -1681,10 +1841,12 @@ PAD - Input tensor with minimum rank of one. + Input tensor + Number of pad elements at the start and end of each dimension + Constant value to be used as padding @@ -1692,6 +1854,7 @@ Output tensor of same type as the input tensor + @@ -1720,13 +1883,16 @@ Input tensor + List of values, with each element giving the size of the result tensor for the given dimension. At most one dimension may be given as -1 to automatically calculate the dimension size. + Output tensor of same type, size as the input tensor + @@ -1753,14 +1919,16 @@ REVERSE - Input tensor with minimum rank of one. + Input tensor + Axis to reverse, in range from 0 to rank(shape)-1 Output tensor. Same shape as input tensor + @@ -1787,18 +1955,22 @@ SLICE - Input tensor with minimum rank of one. + Input tensor + List of integer coordinates, of length equal to the rank of input1. Start coordinate for slicing. + List of integer size values, of length equal to the rank of input1. Size of the input to be used. + Output tensor of same type as the input tensor + @@ -1825,14 +1997,17 @@ used. TILE - Input tensor with minimum rank of one. + Input tensor + Number of times to replicate input1 in each dimension + Output tensor of same type, rank as the input tensor + @@ -1859,14 +2034,17 @@ used. TRANSPOSE - Input tensor with minimum rank of one. + Input tensor + List of integers of length equal to the rank of input1. Values must be valid dimensions within shape1, and may not be repeated. + Output tensor of same type, rank as the input tensor + @@ -1896,12 +2074,15 @@ used. 3D value tensor + 2D index tensor + 3D output tensor + @@ -1928,15 +2109,19 @@ used. 3D values in tensor + 2D index tensor + 3D input tensor + 3D output tensor + @@ -1965,23 +2150,28 @@ used. Input tensor + [scale_y_n, scale_y_d, scale_x_n, scale_x_d] + [offset_y, offset_x] + [border_y, border_x] + BILINEAR or NEAREST Output tensor + @@ -2014,9 +2204,11 @@ used. Input tensor + Output tensor + @@ -2130,9 +2322,11 @@ used. Input tensor + Output tensor with the same shape as input + Input tensor zero point. Must be zero for non-int8 types. @@ -2142,9 +2336,11 @@ used. Scaling multiplier array + Scaling shift array + if (scale32) mul_t=int32_t else mul_t=int16_t @@ -2186,9 +2382,11 @@ used. Constant values + Output tensor of the same type, size as the input tensor + @@ -2217,9 +2415,11 @@ used. Input tensor + Output tensor of the same type, size as the input tensor + @@ -2252,6 +2452,7 @@ used. Input condition as a size 1 tensor + TOSA graph to execute if condition is true diff --git a/tosa.xsd b/tosa.xsd index ca99a8e..fe08885 100644 --- a/tosa.xsd +++ b/tosa.xsd @@ -125,6 +125,29 @@ + + + + + + + + + + + + + + + + + + + + + @@ -152,6 +175,7 @@ + -- cgit v1.2.1