CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
136 lines
6.2 KiB
Markdown
136 lines
6.2 KiB
Markdown
# Tensor Operator Set Architecture (TOSA) Dialect
|
|
|
|
[TOC]
|
|
|
|
## Rationale
|
|
|
|
The MLIR TOSA dialect implements the [TOSA
|
|
specification](https://www.mlplatform.org/tosa/tosa_spec.html). This document
|
|
describes the decision process for how TOSA expresses operators in
|
|
high level dialects.
|
|
|
|
TOSA was developed after parallel efforts to rationalize the top-down picture
|
|
from multiple high-level frameworks, as well as a bottom-up view of different
|
|
hardware target concerns (CPU, GPU and NPU), and reflects a set of choices
|
|
that attempt to manage both sets of requirements.
|
|
|
|
## TOSA and Tensor Level Expressiveness
|
|
|
|
TOSA endeavors to provide an operator set that tries to fulfil the following
|
|
expressiveness goals at the *tensor level of abstraction* :
|
|
|
|
### Complete
|
|
|
|
This is driven by the top-down perspective, needing to express as much of
|
|
multiple high level frameworks fully in TOSA, as possible. This was originally
|
|
done from an operator frequency analysis done upon dozens of high level
|
|
networks in different frameworks, to select the most frequently occurring ones
|
|
and establish a common set of tensor-level operators that could express them.
|
|
|
|
TOSA categorizes its operator set into classes and attempts to address major
|
|
functional operations at the tensor level, including compute, reduction,
|
|
elementwise transformations, comparison and control flow.
|
|
|
|
### Minimal
|
|
|
|
This takes the bottom-up approach - keep the TOSA operator set minimal in
|
|
order to bound the design of hardware, operator kernels, code generation
|
|
strategies and associated considerations that effect the executability of TOSA
|
|
content.
|
|
|
|
In this regard TOSA seeks to avoid creating compound operators, instead
|
|
leaving it to compiler backend to fuse multiple TOSA ops if required. This
|
|
choice also benefits the numerical precision goal, since it is easier to fuse the
|
|
numerical functionality of successive operators, than to split the numerical
|
|
functionality of a compound operator.
|
|
|
|
### Numerical Precision
|
|
|
|
TOSA began as a means to address operator-level numerical precision for
|
|
code generation and hardware development. It therefore incorporates precision
|
|
detail into the operator set.
|
|
|
|
In this regard, TOSA operators are best understood as a combination of the visible
|
|
quantization information embedded within an operation, together with the
|
|
functional information about how that information is used, as described in the
|
|
specification of the operation.
|
|
|
|
## TOSA Operator Rationale
|
|
|
|
The general basis of selection of the operator set that constitutes TOSA is
|
|
described in the TOSA specification document under Section 1.3 Operator
|
|
Selection. Explanation of the thinking behind some operators is listed here:
|
|
|
|
### COND\_IF and WHILE\_LOOP
|
|
|
|
Several neural networks express conditional control flow at the tensor level.
|
|
A survey of multiple high level frameworks indicated that conditional if and
|
|
a loop construct are common in all major frameworks, with some variation.
|
|
Since TOSA endeavors to be complete in expressing tensor level functionality
|
|
including control flow, it implements these constructs.
|
|
|
|
The COND\_IF and WHILE\_LOOP operators implement such structured control
|
|
flow forms and should be lowerable to corresponding ops in the scf dialect.
|
|
Since the dialect seeks to remain isomorphic with an external, serialized form,
|
|
the decision was to keep these ops in the dialect (as opposed to deferring
|
|
completely to scf), and this may be re-evaluated if this turns out to not yield
|
|
the expected value.
|
|
|
|
## Using TOSA In A Compiler
|
|
|
|
The TOSA specification describes each operator in functional detail. It is
|
|
expected that compilers that use TOSA will use its builders to construct the
|
|
operators so that the quantization information for the operator is correctly
|
|
generated.
|
|
|
|
The functional steps described in the pseudocode of the specification enables
|
|
the construction of code generation for that operation, or decisions on the
|
|
design of underlying hardware. The functional pseudocode also describes
|
|
how the quantization parameters are utilized within the operation.
|
|
|
|
### Quantization Parameters in Ops vs Tensors
|
|
|
|
TOSA uses the quantization parameters embedded in the input and output
|
|
tensors to construct the quantization attributes that sit within the operator.
|
|
Once these attributes are constructed, the quantization information within
|
|
the tensors are no longer necessary for code generation.
|
|
|
|
This enables the tensors to be subsequently interpreted simply as contiguous
|
|
buffers containing raw data, with no 'meta information' in the form of the
|
|
quantization_type. Precision related manipulation of the input or output are
|
|
instead described by the operator itself which describes, for example, when
|
|
the zero point is applied, or when the scale multiplication is done.
|
|
|
|
However, TOSA does *not* eliminate the existing MLIR QuantOps quantization
|
|
type information within the tensors; this leaves the choice of how to handle
|
|
quantization information, to later backend code generation steps.
|
|
|
|
Maintaining the ability to overlap these different representations of
|
|
quantization parameters (i.e. tensor-carried vs op-carried) is an important
|
|
capability when considering progressive lowering between uses that expect one
|
|
scheme vs the other.
|
|
|
|
## Operation definitions
|
|
|
|
[include "Dialects/TosaOps.md"]
|
|
|
|
### Operation purity
|
|
Some TOSA operations may exhibit undefined behaviour. In the TOSA specification
|
|
this is indicated by a `REQUIRE` condition in the operation pesudo-code. An
|
|
implementation is not required to detect unpredictable behaviour, see
|
|
[Section 4.3](https://www.mlplatform.org/tosa/tosa_spec_1_0_0.html#_operator_validation_helpers).
|
|
|
|
If an operation can exhibit undefined behaviour, speculating or reordering it
|
|
may change program behaviour. For example, `INTDIV` may exhibit undefined
|
|
behaviour if the divisor is zero. If such an operation were speculated it could
|
|
be executed in situations where the original program would not have executed
|
|
it.
|
|
|
|
Therefore, operations that may exhibit undefined behaviour must not declare
|
|
the `AlwaysSpeculatable` trait and should not be treated as `Pure`.
|
|
|
|
Conversely, most TOSA operations are functional tensor computations and do not
|
|
mutate external system resources. These operations therefore typically declare
|
|
the `NoMemoryEffect` trait. Variable operations are an example of an exception
|
|
to this rule.
|