MLIR

Multi-Level IR Compiler Framework

'async' Dialect

Types and operations for async dialect This dialect contains operations for modeling asynchronous execution.

Type constraint definition 

async value type 

token type 

async.token is a type returned by asynchronous operations, and it becomes ready when the asynchronous operations that created it is completed.

Operation definition 

async.await (::mlir::async::AwaitOp) 

waits for the argument to become ready

Syntax:

operation ::= `async.await` attr-dict $operand `:` custom<AwaitResultType>(
              type($operand), type($result)
              )

The async.await operation waits until the argument becomes ready, and for the async.value arguments it unwraps the underlying value

Example:

%0 = ... : !async.token
async.await %0 : !async.token

%1 = ... : !async.value<f32>
%2 = async.await %1 : !async.value<f32>

Operands: 

OperandDescription
operandasync value type or token type

Results: 

ResultDescription
resultany type

async.execute (::mlir::async::ExecuteOp) 

Asynchronous execute operation

The body region attached to the async.execute operation semantically can be executed concurrently with the successor operation. In the followup example “compute0” can be executed concurrently with “compute1”.

The actual concurrency semantics depends on the dialect lowering to the executable format. Fully sequential execution (“compute0” completes before “compute1” starts) is a completely legal execution.

Because concurrent execution is not guaranteed, it is illegal to create an implicit dependency from “compute1” to “compute0” (e.g. via shared global state). All dependencies must be made explicit with async execute arguments (async.token or async.value).

async.executeoperation takesasync.tokendependencies andasync.value` operands separatly, and starts execution of the attached body region only when all tokens and values become ready.

Example:

%dependency = ... : !async.token
%value = ... : !async.value<f32>

%token, %results =
  async.execute [%dependency](%value as %unwrapped: !async.value<f32>)
             -> !async.value<!some.type>
  {
    %0 = "compute0"(%unwrapped): (f32) -> !some.type
    async.yield %0 : !some.type
  }

%1 = "compute1"(...) : !some.type

In the example above asynchronous execution starts only after dependency token and value argument become ready. Unwrapped value passed to the attached body region as an %unwrapped value of f32 type.

Operands: 

OperandDescription
dependenciestoken type
operandsasync value type or token type

Results: 

ResultDescription
tokentoken type
resultsasync value type

async.yield (::mlir::async::YieldOp) 

terminator for Async execute operation

Syntax:

operation ::= `async.yield` attr-dict ($operands^ `:` type($operands))?

The async.yield is a special terminator operation for the block inside async.execute operation.

Operands: 

OperandDescription
operandsany type