Expressions in Relay
The Relay IR is a pure, expression-oriented language. The below sections describe the different expressions in Relay and give details of their semantics.
Dataflow and Control Fragments
For the purposes of comparing Relay to traditional computational graph-based IRs, it can be useful to consider Relay expressions in terms of dataflow and control fragments. Each portion of a Relay program containing expressions that only affect the dataflow can be viewed as a traditional computation graph when writing and expressing transformations.
The dataflow fragment covers the set of Relay expressions that do not involve control flow. That is, any portion of a program containing only the following constructs corresponds to a pure computation graph:
- Variables
- Tuple Construction and Projection
- Let Bindings
- Graph Bindings
- Calls to Operators and ADT Constructors
Control flow expressions allow the graph topology to change based on the value of previously executed expressions. The control fragment in Relay includes the following constructs:
- If-Then-Else Expressions
- ADT Matching Expressions
- Recursive Calls in Functions
From the point of view of a computation graph, a function is a subgraph and a function call inlines the subgraph, substituting its arguments for the free variables in the subgraph with corresponding names. Thus, if a function's body uses only dataflow constructs, a call to that function is in the dataflow fragment; conversely, if the function's body contains control flow, a call to that function is not part of the dataflow fragment.
Variables
Inspired by LLVM, Relay explicitly distinguishes between local and
global variables both in the AST and in the text format. In the text
format, global and local variables are distinguished by prefixes, or
sigils. Global variables are prefixed with @
and local variables
with %
.
This explicit distinction makes certain optimizations easier to implement. For example, inlining a global definition requires no analysis: simply substituting the definition suffices.
Global Variable
Global identifiers are prefixed by the @
sigil, such as "@global
".
A global identifier always references a globally visible definition
contained in the globally visible environment, known as the
module. Global identifiers must be
unique.
See GlobalVar
for
its implementation and documentation.