aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominic Symes <dominic.symes@arm.com>2022-11-04 18:00:03 +0000
committerEric Kunze <eric.kunze@arm.com>2022-12-05 19:18:51 +0000
commite4d6a1b99337f33cfaf343005e355ef7a68b2be9 (patch)
tree32ae772f418c53ad90e7f069caf59f51dfb7b6f0
parent1cf84e95f85d510f55720fb98694530923ba9a1c (diff)
downloadspecification-e4d6a1b99337f33cfaf343005e355ef7a68b2be9.tar.gz
Add Levels defintion
Add definition of Level 1.0. Signed-off-by: Dominic Symes <dominic.symes@arm.com> Change-Id: I1b34ae22396f273cc5ecdf99198fdbece6e2809c
-rw-r--r--chapters/activation_funcs.adoc1
-rw-r--r--chapters/comparison.adoc6
-rw-r--r--chapters/control_flow.adoc4
-rw-r--r--chapters/data_layout.adoc14
-rw-r--r--chapters/ewise_binary.adoc34
-rw-r--r--chapters/ewise_ternary.adoc2
-rw-r--r--chapters/ewise_unary.adoc22
-rw-r--r--chapters/image.adoc2
-rw-r--r--chapters/introduction.adoc26
-rw-r--r--chapters/operators.adoc5
-rw-r--r--chapters/pseudocode.adoc6
-rw-r--r--chapters/reduction.adoc12
-rw-r--r--chapters/scatter_gather.adoc4
-rw-r--r--chapters/tensor_ops.adoc22
-rw-r--r--chapters/type_conversion.adoc4
-rwxr-xr-xtools/genspec.py10
-rw-r--r--tools/tosa.py10
-rw-r--r--tosa.xml104
-rw-r--r--tosa.xsd47
19 files changed, 201 insertions, 134 deletions
diff --git a/chapters/activation_funcs.adoc b/chapters/activation_funcs.adoc
index 54697d2..3bbeb30 100644
--- a/chapters/activation_funcs.adoc
+++ b/chapters/activation_funcs.adoc
@@ -18,7 +18,6 @@ No zero point subtraction is done to the values, thus to clamp to the zero point
include::{generated}/operators/CLAMP.adoc[]
-*Operation Function:*
[source,c++]
----
ERROR_IF(max_val < min_val);
diff --git a/chapters/comparison.adoc b/chapters/comparison.adoc
index 00ecdd9..f4da361 100644
--- a/chapters/comparison.adoc
+++ b/chapters/comparison.adoc
@@ -15,8 +15,6 @@ Elementwise comparison operation
include::{generated}/operators/EQUAL.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -39,8 +37,6 @@ Elementwise greater than comparison operation
include::{generated}/operators/GREATER.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -63,8 +59,6 @@ Elementwise comparison operation
include::{generated}/operators/GREATER_EQUAL.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
diff --git a/chapters/control_flow.adoc b/chapters/control_flow.adoc
index de6bdda..49fab74 100644
--- a/chapters/control_flow.adoc
+++ b/chapters/control_flow.adoc
@@ -17,8 +17,6 @@ Evaluates a Boolean condition and then takes one of two distinct execution paths
include::{generated}/operators/COND_IF.adoc[]
-*Operation Function:*
-
[source,c++]
----
ERROR_IF(tensor_list_shape(input_list) != tosa_input_shape(then_graph));
@@ -39,8 +37,6 @@ Generates and evaluates a Bool condition and either executes a loop body or exit
include::{generated}/operators/WHILE_LOOP.adoc[]
-*Operation Function:*
-
[source,c++]
----
ERROR_IF(tensor_list_shape(input_list) != tosa_list_shape(output_list));
diff --git a/chapters/data_layout.adoc b/chapters/data_layout.adoc
index e7aadfe..395cb6b 100644
--- a/chapters/data_layout.adoc
+++ b/chapters/data_layout.adoc
@@ -15,8 +15,6 @@ No data conversion happens during a concat operation.
include::{generated}/operators/CONCAT.adoc[]
-*Operation Function:*
-
[source,c]
----
ERROR_IF(axis < 0 || axis >= rank(shapes1[0]));
@@ -52,8 +50,6 @@ The pad_const value includes the zero point if the tensor uses a zero point.
include::{generated}/operators/PAD.adoc[]
-*Operation Function:*
-
[source,c++]
----
// Check output shape matches the padded input shape
@@ -82,8 +78,6 @@ Returns a tensor with the same type/values as the input, with a new shape specif
include::{generated}/operators/RESHAPE.adoc[]
-*Operation Function:*
-
[source,c++]
----
ERROR_IF(tensor_size(shape1) != tensor_size(shape));
@@ -106,8 +100,6 @@ Returns a tensor with the same type/values as the input, with the data reversed
include::{generated}/operators/REVERSE.adoc[]
-*Operation Function:*
-
[source,c++]
----
ERROR_IF(axis < 0 || axis >= rank(shape));
@@ -126,8 +118,6 @@ No data conversion happens during a slice operation.
include::{generated}/operators/SLICE.adoc[]
-*Operation Function:*
-
[source,c++]
----
ERROR_IF(rank(input1) != length(start) || rank(input1) != length(size));
@@ -157,8 +147,6 @@ Replicates input1 multiples times along each dimension.
include::{generated}/operators/TILE.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -179,8 +167,6 @@ Each value in the perms list must be a valid dimension of the input tensor and m
include::{generated}/operators/TRANSPOSE.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in perms) {
diff --git a/chapters/ewise_binary.adoc b/chapters/ewise_binary.adoc
index bf16469..5c34249 100644
--- a/chapters/ewise_binary.adoc
+++ b/chapters/ewise_binary.adoc
@@ -16,8 +16,6 @@ Axis of size 1 will be broadcast, as necessary. Rank of input tensors must match
include::{generated}/operators/ADD.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -37,8 +35,6 @@ Axis of size 1 will be broadcast, as necessary. Rank of input tensors must match
include::{generated}/operators/ARITHMETIC_RIGHT_SHIFT.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -68,8 +64,6 @@ Axis of size 1 will be broadcast as necessary. Rank of input tensors must match.
include::{generated}/operators/BITWISE_AND.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -89,8 +83,6 @@ Axis of size 1 will be broadcast as necessary. Rank of input tensors must match.
include::{generated}/operators/BITWISE_OR.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -110,8 +102,6 @@ Axis of size 1 will be broadcast as necessary. Rank of input tensors must match.
include::{generated}/operators/BITWISE_XOR.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -134,8 +124,6 @@ Quantized integer divide should use TABLE (for 1/x) and MUL.
include::{generated}/operators/INTDIV.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -159,8 +147,6 @@ Axis of size 1 will be broadcast, as necessary. Rank of input tensors must match
include::{generated}/operators/LOGICAL_AND.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -180,8 +166,6 @@ Axis of size 1 will be broadcast, as necessary. Rank of input tensors must match
include::{generated}/operators/LOGICAL_LEFT_SHIFT.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -202,8 +186,6 @@ Axis of size 1 will be broadcast, as necessary. Rank of input tensors must match
include::{generated}/operators/LOGICAL_RIGHT_SHIFT.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -224,8 +206,6 @@ Axis of size 1 will be broadcast as necessary. Rank of input tensors must match.
include::{generated}/operators/LOGICAL_OR.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -245,8 +225,6 @@ Axis of size 1 will be broadcast as necessary. Rank of input tensors must match.
include::{generated}/operators/LOGICAL_XOR.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -266,8 +244,6 @@ Axis of size 1 will be broadcast, as necessary. Rank of input tensors must match
include::{generated}/operators/MAXIMUM.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -287,8 +263,6 @@ Axis of size 1 will be broadcast, as necessary. Rank of input tensors must match
include::{generated}/operators/MINIMUM.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -308,8 +282,6 @@ Axis of size 1 will be broadcast, as necessary. Rank of input tensors must match
include::{generated}/operators/MUL.adoc[]
-*Operation Function:*
-
[source,c++]
----
ERROR_IF(in_t != int32_t && shift > 0);
@@ -339,8 +311,6 @@ Axis of size 1 will be broadcast, as necessary. Rank of input tensors must match
include::{generated}/operators/POW.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -360,8 +330,6 @@ Axis of size 1 will be broadcast as necessary. Rank of input tensors must match.
include::{generated}/operators/SUB.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -392,8 +360,6 @@ An int16_t to int16_t table lookup can be constructed in TOSA as follows:
include::{generated}/operators/TABLE.adoc[]
-*Operation Function:*
-
[source,c++]
----
REQUIRE(length(table) == TABLE_SIZE);
diff --git a/chapters/ewise_ternary.adoc b/chapters/ewise_ternary.adoc
index 0391ea6..eb30a01 100644
--- a/chapters/ewise_ternary.adoc
+++ b/chapters/ewise_ternary.adoc
@@ -15,8 +15,6 @@ Elementwise select of the output based on a condition.
include::{generated}/operators/SELECT.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
diff --git a/chapters/ewise_unary.adoc b/chapters/ewise_unary.adoc
index 289b657..f630a48 100644
--- a/chapters/ewise_unary.adoc
+++ b/chapters/ewise_unary.adoc
@@ -22,8 +22,6 @@ include::{generated}/operators/ABS.adoc[]
|Output|+infinity|+infinity|+0|+0|NaN
|===
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -43,8 +41,6 @@ Elementwise bitwise NOT of input tensor.
include::{generated}/operators/BITWISE_NOT.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -67,8 +63,6 @@ include::{generated}/operators/CEIL.adoc[]
|Output|-infinity|+infinity|-0|+0|NaN
|===
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -84,8 +78,6 @@ Elementwise count leading zeros operation
include::{generated}/operators/CLZ.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -108,8 +100,6 @@ include::{generated}/operators/EXP.adoc[]
|Output|+0|+infinity|1|1|NaN
|===
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -132,8 +122,6 @@ include::{generated}/operators/FLOOR.adoc[]
|Output|-infinity|+infinity|-0|+0|NaN
|===
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -156,8 +144,6 @@ include::{generated}/operators/LOG.adoc[]
|Output|NaN|+infinity|-infinity|-infinity|NaN
|===
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -173,8 +159,6 @@ Elementwise logical NOT of input.
include::{generated}/operators/LOGICAL_NOT.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -197,8 +181,6 @@ include::{generated}/operators/NEGATE.adoc[]
|Output|+infinity|-infinity|+0|-0|NaN
|===
-*Operation Function:*
-
[source,c++]
----
ERROR_IF(in_out_t != int8_t && input1_zp != 0) // Zero point only for int8_t
@@ -225,8 +207,6 @@ include::{generated}/operators/RECIPROCAL.adoc[]
|Output|-0|+0|-infinity|+infinity|NaN
|===
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -249,8 +229,6 @@ include::{generated}/operators/RSQRT.adoc[]
|Output|NaN|+0|-infinity|+infinity|NaN
|===
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
diff --git a/chapters/image.adoc b/chapters/image.adoc
index bcef73f..8abc878 100644
--- a/chapters/image.adoc
+++ b/chapters/image.adoc
@@ -59,8 +59,6 @@ include::{generated}/operators/RESIZE.adoc[]
|BILINEAR|Bilinear interpoloation
|===
-*Operation Function*
-
[source,c++]
----
// Ensure the image size is supported by GPU APIs and that for integer
diff --git a/chapters/introduction.adoc b/chapters/introduction.adoc
index 848359b..5a2b9a1 100644
--- a/chapters/introduction.adoc
+++ b/chapters/introduction.adoc
@@ -106,6 +106,26 @@ The following table summarizes the three profiles:
|Main Training|TOSA-MT|Yes|Yes|Yes
|===
+=== Levels
+
+A TOSA level defines operator parameter ranges that an implementation shall support.
+This is distinct from a profile that defines the operations and data-types supported.
+This version of the specification defines two TOSA levels:
+
+* No level : allows the full range of parameters specified by the operations according to the operation data types.
+* Level 8K : ranges are expected to be sufficient for applications with frame sizes up to 8K.
+
+Later versions of the specification may define additional levels.
+The following table defines the value ranges for Level 1.0.
+These ranges are checked using the LEVEL_CHECK() function with the operator descriptions.
+
+.Level maximums
+|===
+| Level | tosa_level_t | MAX_RANK | MAX_KERNEL | MAX_STRIDE | MAX_SCALE
+| None | tosa_level_none | NA | NA | NA | NA
+| 8K | tosa_level_8k | 6 | 8192 | 8192 | 64
+|===
+
=== Status
The TOSA specification is a work in progress.
@@ -118,7 +138,7 @@ The TOSA specification is a work in progress.
=== Compliance
-This section defines when a TOSA implementation is compliant to a given TOSA specification profile.
+This section defines when a TOSA implementation is compliant to a given TOSA specification profile and level.
The term conformant will mean the same as compliant.
==== Baseline Inference Profile Compliance
@@ -141,11 +161,11 @@ In terms of psuedo-code, if *graph* is a TOSA graph consisting of Baseline Infer
[source,c++]
----
-bool tosa_test_compliance(tosa_graph_t graph, tosa_list_t input_list) {
+bool tosa_test_compliance(tosa_graph_t graph, tosa_list_t input_list, tosa_level_t level) {
shape_list_t output_list_spec = tosa_allocate_list(tosa_output_shape(graph));
shape_list_t output_list_test = tosa_allocate_list(tosa_output_shape(graph));
tosa_graph_result = tosa_valid // result starts as valid
- tosa_execute_graph(graph, input_list, output_list_spec);
+ tosa_execute_graph(graph, input_list, output_list_spec, level);
if (tosa_graph_result == tosa_unpredictable) {
return true; // No requirement to match an unpredictable result
}
diff --git a/chapters/operators.adoc b/chapters/operators.adoc
index bec93c1..d6d1f13 100644
--- a/chapters/operators.adoc
+++ b/chapters/operators.adoc
@@ -45,7 +45,7 @@ The following function denotes the execution of a TOSA graph, on an input tensor
[source,c++]
----
-tosa_execute_graph(tosa_graph_t graph, tosa_list_t input_list, tosa_list_t output_list) {
+tosa_execute_graph(tosa_graph_t graph, tosa_list_t input_list, tosa_list_t output_list, tosa_level_t level) {
ERROR_IF(tensor_list_shape(input_list) != tosa_input_shape(graph));
ERROR_IF(tensor_list_shape(output_list) != tosa_output_shape(graph));
for_each(operator in graph order) {
@@ -53,7 +53,8 @@ tosa_execute_graph(tosa_graph_t graph, tosa_list_t input_list, tosa_list_t outpu
ERROR_IF(operator attributes do not meet requirement of operator Arguments attributes)
ERROR_IF(operator output tensors do not meet requirement of operator Arguments outputs)
ERROR_IF(operator data types do not meet requirement of operator Supported Data Types)
- <Execute operator as defined by the Operation Function pseduo-code>
+ // Execute the operator as defined by the operation function pseduo-code
+ tosa_execute_operator(operator, level);
}
}
----
diff --git a/chapters/pseudocode.adoc b/chapters/pseudocode.adoc
index b931822..f4fd885 100644
--- a/chapters/pseudocode.adoc
+++ b/chapters/pseudocode.adoc
@@ -48,6 +48,12 @@ void ERROR_IF(condition) {
tosa_graph_result = tosa_error;
}
}
+
+void LEVEL_CHECK(condition) {
+ // If a level is specified and the level condition fails then
+ // the result is unpredictable.
+ REQUIRE(condition);
+}
----
=== Tensor Access Helpers
diff --git a/chapters/reduction.adoc b/chapters/reduction.adoc
index 3746460..713404c 100644
--- a/chapters/reduction.adoc
+++ b/chapters/reduction.adoc
@@ -15,8 +15,6 @@ Reduce a tensor along the given axis with a logical AND operation
include::{generated}/operators/REDUCE_ALL.adoc[]
-*Operation Function:*
-
[source,c]
----
ERROR_IF(axis < 0 || axis >= rank(shape1));
@@ -42,8 +40,6 @@ Reduce a tensor along the given axis with a logical OR operation
include::{generated}/operators/REDUCE_ANY.adoc[]
-*Operation Function:*
-
[source,c]
----
ERROR_IF(axis < 0 || axis >= rank(shape1));
@@ -69,8 +65,6 @@ Reduce a tensor along the given axis with a maximum operation
include::{generated}/operators/REDUCE_MAX.adoc[]
-*Operation Function:*
-
[source,c]
----
ERROR_IF(axis < 0 || axis >= rank(shape1));
@@ -94,8 +88,6 @@ Reduce a tensor along the given axis with a minimum operation
include::{generated}/operators/REDUCE_MIN.adoc[]
-*Operation Function:*
-
[source,c]
----
ERROR_IF(axis < 0 || axis >= rank(shape1));
@@ -119,8 +111,6 @@ Reduce a tensor along the given axis by computing the product of the axis.
include::{generated}/operators/REDUCE_PRODUCT.adoc[]
-*Operation Function:*
-
[source,c]
----
ERROR_IF(axis < 0 || axis >= rank(shape1));
@@ -144,8 +134,6 @@ Reduce a tensor along the given axis by computing the sum of the axis.
include::{generated}/operators/REDUCE_SUM.adoc[]
-*Operation Function:*
-
[source,c]
----
ERROR_IF(axis < 0 || axis >= rank(shape1));
diff --git a/chapters/scatter_gather.adoc b/chapters/scatter_gather.adoc
index 43cc047..89942f2 100644
--- a/chapters/scatter_gather.adoc
+++ b/chapters/scatter_gather.adoc
@@ -16,8 +16,6 @@ N is the number of batches, W the number of indices in each batch, K the range o
include::{generated}/operators/GATHER.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(0 <= n < N, 0 <= w < W, 0 <= c < C) {
@@ -37,8 +35,6 @@ In use cases that require multiple updates to the same output position, these mu
include::{generated}/operators/SCATTER.adoc[]
-*Operation Function:*
-
[source,c++]
----
diff --git a/chapters/tensor_ops.adoc b/chapters/tensor_ops.adoc
index 3ebb2c2..b8527bf 100644
--- a/chapters/tensor_ops.adoc
+++ b/chapters/tensor_ops.adoc
@@ -15,8 +15,6 @@ This returns the index with the largest value across the given axis of the input
include::{generated}/operators/ARGMAX.adoc[]
-*Operation Function:*
-
[source,c++]
----
ERROR_IF(axis < 0 || axis >= rank(shape1) || rank(shape1) > 4);
@@ -54,8 +52,6 @@ When calculating the average, only the number of valid input tensor values, but
include::{generated}/operators/AVG_POOL2D.adoc[]
-*Operation Function:*
-
[source,c++]
----
ERROR_IF(in_out_t != int8_t && input_zp != 0); // Zero point only for int8_t
@@ -105,8 +101,6 @@ Performs a 2D convolution over the given tensor input, using the weight tensor.
include::{generated}/operators/CONV2D.adoc[]
-*Operation Function*
-
[source,c++]
----
ERROR_IF(in_t != int8_t && input_zp != 0); // Zero point only for int8_t
@@ -144,8 +138,6 @@ Performs a 3D convolution over the given input tensor.
include::{generated}/operators/CONV3D.adoc[]
-*Operation Function*
-
[source,c++]
----
ERROR_IF(in_t != int8_t && input_zp != 0); // Zero point only for int8_t
@@ -186,8 +178,6 @@ Performs 2D convolutions separately over each channel of the given tensor input,
include::{generated}/operators/DEPTHWISE_CONV2D.adoc[]
-*Operation Function*
-
[source,c++]
----
ERROR_IF(in_t != int8_t && input_zp != 0); // Zero point only for int8_t
@@ -238,8 +228,6 @@ image::inverse_fft2d.svg["inverse FFT definition", align="center"]
include::{generated}/operators/FFT2D.adoc[]
-*Operation Function*
-
[source,c++]
----
ERROR_IF(!power_of_two(H));
@@ -272,8 +260,6 @@ Performs a fully connected network.
include::{generated}/operators/FULLY_CONNECTED.adoc[]
-*Operation Function*
-
[source,c++]
----
ERROR_IF(in_t != int8_t && input_zp != 0); // Zero point only for int8_t
@@ -298,8 +284,6 @@ Performs two dimensional matrix multiplications. This allows both inputs to be a
include::{generated}/operators/MATMUL.adoc[]
-*Operation Function*
-
[source,c++]
----
ERROR_IF(in_t != int8_t && (A_zp != 0 || B_zp != 0)); // Zero point only for int8_t
@@ -322,8 +306,6 @@ This performs a max pooling over the given input tensor. A sliding window of siz
include::{generated}/operators/MAX_POOL2D.adoc[]
-*Operation Function:*
-
[source,c++]
----
ERROR_IF(kernel_y < 1 || kernel_x < 1); // kernel size must be >= 1
@@ -363,8 +345,6 @@ image::forward_fft2d.svg["forward FFT definition", align="center"]
include::{generated}/operators/RFFT2D.adoc[]
-*Operation Function*
-
[source,c++]
----
ERROR_IF(!power_of_two(H));
@@ -390,8 +370,6 @@ Performs a 2D transposed convolution over the given tensor input, using the weig
include::{generated}/operators/TRANSPOSE_CONV2D.adoc[]
-*Operation Function*
-
[source,c++]
----
ERROR_IF(in_t != int8_t && input_zp != 0); // Zero point only allowed for int8_t
diff --git a/chapters/type_conversion.adoc b/chapters/type_conversion.adoc
index 3ff190b..d6cd1b2 100644
--- a/chapters/type_conversion.adoc
+++ b/chapters/type_conversion.adoc
@@ -15,8 +15,6 @@ Casts a tensor from one data type to another.
include::{generated}/operators/CAST.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
@@ -45,8 +43,6 @@ Rescale quantized values into a new domain. This function scales by factor: mult
include::{generated}/operators/RESCALE.adoc[]
-*Operation Function:*
-
[source,c++]
----
for_each(index in shape) {
diff --git a/tools/genspec.py b/tools/genspec.py
index c871b75..33e8e35 100755
--- a/tools/genspec.py
+++ b/tools/genspec.py
@@ -44,6 +44,16 @@ class TOSASpecAsciidocGenerator:
entry += "\n"
file.write(entry)
file.write("|===\n")
+ file.write("\n*Operation Function:*\n\n")
+ leveltext = ""
+ for arg in op.arguments:
+ if (len(arg.levellimits) > 0):
+ for limit in arg.levellimits:
+ leveltext += " LEVEL_CHECK(" + limit[0] + " <= " + limit[1] + ");\n"
+ if (len(leveltext) > 0):
+ file.write(
+ f"[source,c++]\n----\nif (level != tosa_level_none) {{\n{leveltext}}}\n----\n"
+ )
def generate(self, outdir):
opdir = os.path.join(outdir, "operators")
diff --git a/tools/tosa.py b/tools/tosa.py
index 87b4f1a..2c2f8ec 100644
--- a/tools/tosa.py
+++ b/tools/tosa.py
@@ -9,12 +9,13 @@ class TOSAOperatorArgumentCategory:
class TOSAOperatorArgument:
- def __init__(self, name, description, categories, ty, shape):
+ def __init__(self, name, description, categories, ty, shape, levellimits):
self.name = name
self.description = description
self.categories = categories
self.type = ty
self.shape = shape
+ self.levellimits = levellimits
class TOSAOperatorDataTypeSupport:
@@ -87,6 +88,11 @@ class TOSASpec:
argcats = []
argtype = arg.get("type")
shape = arg.get("shape")
+ levellimits = []
+ for levellimit in arg.findall("levellimit"):
+ value = levellimit.get("value")
+ limit = levellimit.get("limit")
+ levellimits.append([value, limit])
cats = re.findall(
r"(input|output|attribute)\(?([A-Z,]+)?\)?", arg.get("category")
@@ -94,4 +100,4 @@ class TOSASpec:
for cat in cats:
argcats.append(TOSAOperatorArgumentCategory(cat[0], cat[1].split(",")))
- return TOSAOperatorArgument(name, desc, argcats, argtype, shape)
+ return TOSAOperatorArgument(name, desc, argcats, argtype, shape, levellimits)
diff --git a/tosa.xml b/tosa.xml
index fbf344d..5a04023 100644
--- a/tosa.xml
+++ b/tosa.xml
@@ -6,6 +6,10 @@
<profile name="MI">Main Inference</profile>
<profile name="MT">Main Training</profile>
</profiles>
+ <levels>
+ <level name="none" max_rank="32" max_kernel="2147483647" max_stride="2147483647" max_scale="2048">No level</level>
+ <level name="8K" max_rank="6" max_kernel="8192" max_stride="8192" max_scale="64" >Level 8K</level>
+ </levels>
<operators>
<operatorgroup name="tensor">
<operator>
@@ -48,12 +52,20 @@
</argument>
<argument category="attribute" name="kernel" type="int32_t*" shape="[2]">
<description>[kernel_y, kernel_x]</description>
+ <levellimit value="kernel_y" limit="MAX_KERNEL"/>
+ <levellimit value="kernel_x" limit="MAX_KERNEL"/>
</argument>
<argument category="attribute" name="stride" type="int32_t*" shape="[2]">
<description>[stride_y, stride_x]</description>
+ <levellimit value="stride_y" limit="MAX_STRIDE"/>
+ <levellimit value="stride_x" limit="MAX_STRIDE"/>
</argument>
<argument category="attribute" name="pad" type="int32_t*" shape="[4]">
<description>[pad_top, pad_bottom, pad_left, pad_right]</description>
+ <levellimit value="pad_top" limit="MAX_KERNEL"/>
+ <levellimit value="pad_bottom" limit="MAX_KERNEL"/>
+ <levellimit value="pad_left" limit="MAX_KERNEL"/>
+ <levellimit value="pad_right" limit="MAX_KERNEL"/>
</argument>
<argument category="attribute" name="input_zp" type="in_out_t" shape="-">
<description>Input tensor zero point. Must be zero for non-int8 types.</description>
@@ -96,15 +108,23 @@
</argument>
<argument category="input" name="weight" type="weight_t*" shape="[OC,KH,KW,IC]">
<description>Weight kernel size KH x KW</description>
+ <levellimit value="dilation_y * KH" limit="MAX_KERNEL"/>
+ <levellimit value="dilation_x * KW" limit="MAX_KERNEL"/>
</argument>
<argument category="input" name="bias" type="out_t*" shape="[OC]">
<description>Per output channel bias data.</description>
</argument>
<argument category="attribute" name="pad" type="int32_t*" shape="[4]">
<description>[pad_top, pad_bottom, pad_left, pad_right]</description>
+ <levellimit value="pad_top" limit="MAX_KERNEL"/>
+ <levellimit value="pad_bottom" limit="MAX_KERNEL"/>
+ <levellimit value="pad_left" limit="MAX_KERNEL"/>
+ <levellimit value="pad_right" limit="MAX_KERNEL"/>
</argument>
<argument category="attribute" name="stride" type="int32_t*" shape="[2]">
<description>[stride_y, stride_x]</description>
+ <levellimit value="stride_y" limit="MAX_STRIDE"/>
+ <levellimit value="stride_x" limit="MAX_STRIDE"/>
</argument>
<argument category="attribute" name="dilation" type="int32_t*" shape="[2]">
<description>[dilation_y, dilation_x]</description>
@@ -152,15 +172,27 @@
</argument>
<argument category="input" name="weight" type="weight_t*" shape="[OC,KD,KH,KW,IC]">
<description>Weight kernel size KDxKHxKW</description>
+ <levellimit value="dilation_d * KD" limit="MAX_KERNEL"/>
+ <levellimit value="dilation_y * KH" limit="MAX_KERNEL"/>
+ <levellimit value="dilation_x * KW" limit="MAX_KERNEL"/>
</argument>
<argument category="input" name="bias" type="out_t*" shape="[OC]">
<description>Per output channel bias data.</description>
</argument>
<argument category="attribute" name="pad" type="int32_t*" shape="[6]">
<description>[pad_d0, pad_d1, pad_top, pad_bottom, pad_left, pad_right]</description>
+ <levellimit value="pad_d0" limit="MAX_KERNEL"/>
+ <levellimit value="pad_d1" limit="MAX_KERNEL"/>
+ <levellimit value="pad_top" limit="MAX_KERNEL"/>
+ <levellimit value="pad_bottom" limit="MAX_KERNEL"/>
+ <levellimit value="pad_left" limit="MAX_KERNEL"/>
+ <levellimit value="pad_right" limit="MAX_KERNEL"/>
</argument>
<argument category="attribute" name="stride" type="int32_t*" shape="[3]">
<description>[stride_d, stride_y, stride_x]</description>
+ <levellimit value="stride_y" limit="MAX_STRIDE"/>
+ <levellimit value="stride_x" limit="MAX_STRIDE"/>
+ <levellimit value="stride_d" limit="MAX_STRIDE"/>
</argument>
<argument category="attribute" name="dilation" type="int32_t*" shape="[3]">
<description>[dilation_d, dilation_y, dilation_x]</description>
@@ -208,15 +240,23 @@
</argument>
<argument category="input" name="weight" type="weight_t*" shape="[KH,KW,C,M]">
<description>Weight kernel size KH x KW</description>
+ <levellimit value="dilation_y * KH" limit="MAX_KERNEL"/>
+ <levellimit value="dilation_x * KW" limit="MAX_KERNEL"/>
</argument>
<argument category="input" name="bias" type="out_t*" shape="[C*M]">
<description>Per output channel bias data.</description>
</argument>
<argument category="attribute" name="pad" type="int32_t*" shape="[4]">
<description>[pad_top, pad_bottom, pad_left, pad_right]</description>
+ <levellimit value="pad_top" limit="MAX_KERNEL"/>
+ <levellimit value="pad_bottom" limit="MAX_KERNEL"/>
+ <levellimit value="pad_left" limit="MAX_KERNEL"/>
+ <levellimit value="pad_right" limit="MAX_KERNEL"/>
</argument>
<argument category="attribute" name="stride" type="int32_t*" shape="[2]">
<description>[stride_y, stride_x]</description>
+ <levellimit value="stride_y" limit="MAX_STRIDE"/>
+ <levellimit value="stride_x" limit="MAX_STRIDE"/>
</argument>
<argument category="attribute" name="dilation" type="int32_t*" shape="[2]">
<description>[dilation_y, dilation_x]</description>
@@ -261,6 +301,8 @@
<arguments>
<argument category="input" name="input_real" type="in_out_t*" shape="[N,H,W]">
<description>Real part of the complex input. H,W must be powers of two.</description>
+ <levellimit value="H" limit="MAX_KERNEL"/>
+ <levellimit value="W" limit="MAX_KERNEL"/>
</argument>
<argument category="input" name="input_imag" type="in_out_t*" shape="[N,H,W]">
<description>Imaginary part of the complex input. H,W must be powers of two.</description>
@@ -380,12 +422,20 @@
</argument>
<argument category="attribute" name="kernel" type="int32_t*" shape="[2]">
<description>[kernel_y, kernel_x]</description>
+ <levellimit value="kernel_y" limit="MAX_KERNEL"/>
+ <levellimit value="kernel_x" limit="MAX_KERNEL"/>
</argument>
<argument category="attribute" name="stride" type="int32_t*" shape="[2]">
<description>[stride_y, stride_x]</description>
+ <levellimit value="stride_y" limit="MAX_STRIDE"/>
+ <levellimit value="stride_x" limit="MAX_STRIDE"/>
</argument>
<argument category="attribute" name="pad" type="int32_t*" shape="[4]">
<description>[pad_top, pad_bottom, pad_left, pad_right]</description>
+ <levellimit value="pad_top" limit="MAX_KERNEL"/>
+ <levellimit value="pad_bottom" limit="MAX_KERNEL"/>
+ <levellimit value="pad_left" limit="MAX_KERNEL"/>
+ <levellimit value="pad_right" limit="MAX_KERNEL"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="[N,OH,OW,C]">
<description>Output tensor 4D</description>
@@ -414,6 +464,8 @@
<arguments>
<argument category="input" name="input" type="in_out_t*" shape="[N,H,W]">
<description>Real input. H,W must be powers of two.</description>
+ <levellimit value="H" limit="MAX_KERNEL"/>
+ <levellimit value="W" limit="MAX_KERNEL"/>
</argument>
<argument category="output" name="output_real" type="in_out_t*" shape="[N,H/2 + 1,W/2 + 1]">
<description>Real part of the complex output</description>
@@ -438,15 +490,23 @@
</argument>
<argument category="input" name="weight" type="weight_t*" shape="[OC,KH,KW,IC]">
<description>Weight kernel size KH x KW</description>
+ <levellimit value="KH" limit="MAX_KERNEL"/>
+ <levellimit value="KW" limit="MAX_KERNEL"/>
</argument>
<argument category="input" name="bias" type="out_t*" shape="[OC]">
<description>Per output channel bias data.</description>
</argument>
<argument category="attribute" name="out_pad" type="int32_t*" shape="[4]">
<description>[out_pad_top, out_pad_bottom, out_pad_left, out_pad_right]</description>
+ <levellimit value="out_pad_top" limit="MAX_KERNEL"/>
+ <levellimit value="out_pad_bottom" limit="MAX_KERNEL"/>
+ <levellimit value="out_pad_left" limit="MAX_KERNEL"/>
+ <levellimit value="out_pad_right" limit="MAX_KERNEL"/>
</argument>
<argument category="attribute" name="stride" type="int32_t*" shape="[2]">
<description>[stride_y, stride_x]</description>
+ <levellimit value="stride_y" limit="MAX_STRIDE"/>
+ <levellimit value="stride_x" limit="MAX_STRIDE"/>
</argument>
<argument category="attribute" name="out_shape" type="int32_t*" shape="[4]">
<description>[N,OH,OW,OC]</description>
@@ -493,6 +553,7 @@
<arguments>
<argument category="input" name="input" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="attribute" name="min_val" type="in_out_t" shape="-">
<description>Minimum clip value</description>
@@ -527,6 +588,7 @@
<arguments>
<argument category="input" name="input" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type and shape as input</description>
@@ -553,6 +615,7 @@
<arguments>
<argument category="input" name="input" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type and shape as input</description>
@@ -587,6 +650,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -620,6 +684,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -640,6 +705,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -660,6 +726,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -680,6 +747,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -700,6 +768,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -718,6 +787,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -736,6 +806,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -756,6 +827,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -776,6 +848,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -794,6 +867,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -812,6 +886,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -842,6 +917,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -875,6 +951,7 @@
</argument>
<argument category="output" name="output" type="out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -908,6 +985,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -937,6 +1015,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -967,6 +1046,7 @@
</argument>
<argument category="output" name="output" type="out_t*" shape="shape">
<description>Output tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -985,6 +1065,7 @@
<arguments>
<argument category="input" name="input1" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, size as the input tensor</description>
@@ -1012,6 +1093,7 @@
<arguments>
<argument category="input" name="input1" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, size as the input tensor</description>
@@ -1029,6 +1111,7 @@
<arguments>
<argument category="input" name="input1" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, size as the input tensor</description>
@@ -1055,6 +1138,7 @@
<arguments>
<argument category="input" name="input1" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, size as the input tensor</description>
@@ -1070,6 +1154,7 @@
<arguments>
<argument category="input" name="input1" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, size as the input tensor</description>
@@ -1096,6 +1181,7 @@
<arguments>
<argument category="input" name="input1" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, size as the input tensor</description>
@@ -1122,6 +1208,7 @@
<arguments>
<argument category="input" name="input1" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, size as the input tensor</description>
@@ -1148,6 +1235,7 @@
<arguments>
<argument category="input" name="input1" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, size as the input tensor</description>
@@ -1199,6 +1287,7 @@
<arguments>
<argument category="input" name="input1" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, size as the input tensor</description>
@@ -1225,6 +1314,7 @@
<arguments>
<argument category="input" name="input1" type="in_out_t*" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, size as the input tensor</description>
@@ -1262,6 +1352,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type as input2 and input3, with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -1298,6 +1389,7 @@
</argument>
<argument category="output" name="output" type="out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -1329,6 +1421,7 @@
</argument>
<argument category="output" name="output" type="out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -1360,6 +1453,7 @@
</argument>
<argument category="output" name="output" type="out_t*" shape="shape">
<description>Output tensor with broadcast shape if necessary</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -1555,6 +1649,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -1591,6 +1686,7 @@
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type as the input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -1618,12 +1714,14 @@
<arguments>
<argument category="input" name="input1" type="in_out_t*" shape="shape1">
<description>Input tensor</description>
+ <levellimit value="rank(shape1)" limit="MAX_RANK"/>
</argument>
<argument category="attribute" name="new_shape" type="int32_t" shape="[rank(output)]">
<description>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.</description>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, size as the input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -1651,6 +1749,7 @@
<arguments>
<argument category="input" name="input" type="in_out_t*" shape="shape">
<description>Input tensor with rank from 1 to 4</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="attribute" name="axis" type="int32_t" shape="-">
<description>Axis to reverse, in range from 0 to rank(shape)-1</description>
@@ -1760,6 +1859,7 @@ used.</description>
</argument>
<argument category="output" name="output" type="in_out_t*" shape="shape">
<description>Output tensor of same type, rank as the input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
</arguments>
<types>
@@ -1863,6 +1963,8 @@ used.</description>
</argument>
<argument category="attribute" name="scale" type="int16_t*" shape="[4]">
<description>[scale_y_n, scale_y_d, scale_x_n, scale_x_d]</description>
+ <levellimit value="scale_y_n/scale_y_d" limit="MAX_SCALE"/>
+ <levellimit value="scale_x_n/scale_x_d" limit="MAX_SCALE"/>
</argument>
<argument category="attribute" name="offset" type="int16_t*" shape="[2]">
<description>[offset_y, offset_x]</description>
@@ -1906,6 +2008,7 @@ used.</description>
<arguments>
<argument category="input" name="input" type="in_t" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="out_t" shape="shape">
<description>Output tensor</description>
@@ -2021,6 +2124,7 @@ used.</description>
<arguments>
<argument category="input" name="input" type="in_t" shape="shape">
<description>Input tensor</description>
+ <levellimit value="rank(shape)" limit="MAX_RANK"/>
</argument>
<argument category="output" name="output" type="out_t" shape="shape">
<description>Output tensor with the same shape as input</description>
diff --git a/tosa.xsd b/tosa.xsd
index 8f57131..1a37bc4 100644
--- a/tosa.xsd
+++ b/tosa.xsd
@@ -11,6 +11,22 @@
</xs:restriction>
</xs:simpleType>
+<xs:simpleType name="levelname">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="none"/>
+ <xs:enumeration value="8K"/>
+ </xs:restriction>
+</xs:simpleType>
+
+<xs:simpleType name="levelmax">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="MAX_KERNEL"/>
+ <xs:enumeration value="MAX_STRIDE"/>
+ <xs:enumeration value="MAX_SCALE"/>
+ <xs:enumeration value="MAX_RANK"/>
+ </xs:restriction>
+</xs:simpleType>
+
<xs:simpleType name="datatype">
<xs:restriction base="xs:string">
<xs:enumeration value="bool_t"/>
@@ -64,6 +80,27 @@
</xs:complexType>
</xs:element>
+<xs:element name="level">
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="name" type="levelname" use="required"/>
+ <xs:attribute name="max_rank" type="xs:int" use="required"/>
+ <xs:attribute name="max_kernel" type="xs:int" use="required"/>
+ <xs:attribute name="max_stride" type="xs:int" use="required"/>
+ <xs:attribute name="max_scale" type="xs:int" use="required"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+</xs:element>
+
+<xs:element name="levellimit">
+ <xs:complexType>
+ <xs:attribute name="value" type="xs:string" use="required"/>
+ <xs:attribute name="limit" type="levelmax" use="required"/>
+ </xs:complexType>
+</xs:element>
+
<xs:element name="profiles">
<xs:complexType>
<xs:sequence>
@@ -72,6 +109,14 @@
</xs:complexType>
</xs:element>
+<xs:element name="levels">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="level" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+</xs:element>
+
<!-- TODO pattern for attribute name -->
<!-- TODO enumerations/patterns for attribute type -->
<!-- TODO enumerations/patterns for attribute shape -->
@@ -79,6 +124,7 @@
<xs:complexType>
<xs:sequence>
<xs:element name="description" type="xs:string"/>
+ <xs:element ref="levellimit" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="category" type="argumentcategory" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
@@ -161,6 +207,7 @@
<xs:complexType>
<xs:sequence>
<xs:element ref="profiles"/>
+ <xs:element ref="levels"/>
<xs:element ref="operators"/>
</xs:sequence>
</xs:complexType>