‘dfg’ Dialect

The dfg dialect groups together a set of types, operations and transformations that are useful to implement a structured abstraction on dataflow graphs. These abstractions are useful for constructing KPN/SDF-like dataflow graphs, which include definitions of nodes, edges and their connections.

Operations

dfg.channel (dfg::ChannelOp)

Defines a channel with one input and one output port

The channel operation produces a typed channel (i.e. an edge in the dataflow graph) that links two nodes (i.e. process or operator) in the dataflow graph. The input of a channel will be connected to an output port of a node, which means its type is dfg::InputType, same for output port.

A channel can also be sized manually with a 32-bit integer, otherwise, it indicates an unbounded FIFO channel. The token flows in the channel can also be of memref/tensor type, which implicitly enables multiple read/write as in KPN MoC.

Examples:

%input, %output = dfg.channel() : type
$input, %output = dfg.channel(size) : shape x type

Interfaces: DFG_EdgeInterface, MemoryEffectsOpInterface, OpAsmOpInterface

Attributes:

AttributeMLIR TypeDescription
token_type::mlir::TypeAttrany type attribute
buffer_size::mlir::IntegerAttr32-bit signless integer attribute

Results:

Result

Description

input_port

Sending channel end type

output_port

Receiving channel end type

dfg.embed (dfg::EmbedOp)

Embed a region as a subgraph in another.

The embed operation embed a region into another region. The syntax and usage of this operation is similar to instantiate operation.

dfg.region @child inputs(...) outputs(...) {...}
dfg.region @parent inputs(...) outputs(...) {
    dfg.embed @child inputs(...) outputs(...) : (...) -> (...)
}

Traits: AttrSizedOperandSegments

Interfaces: DFG_GraphInterface, DFG_NodeInterface

Attributes:

AttributeMLIR TypeDescription
actor::mlir::SymbolRefAttrsymbol reference attribute
offloaded::mlir::dfg::OffloadHardwareAttrThe hardware back to be offloaded to

Operands:

Operand

Description

inputs

variadic of Receiving channel end type

outputs

variadic of Sending channel end type

dfg.instantiate (dfg::InstantiateOp)

Instantiates an DFG node.

The instantiate operation instantiate an operator or process in a region with a set of inputs and outputs. InstantiateOp creates a DFG node with a set of input and output values.

dfg.operator @operator inputs(...) outputs(...) {...}
dfg.process @process inputs(...) outputs(...) {...}
dfg.region @graph inputs(...) outputs(...) {
    dfg.instantiate @operator inputs(...) outputs(...) : (...) -> (...)
    dfg.instantiate @process inputs(...) outputs(...) : (...) -> (...)
}

Traits: AttrSizedOperandSegments

Interfaces: DFG_NodeInterface

Attributes:

AttributeMLIR TypeDescription
actor::mlir::SymbolRefAttrsymbol reference attribute
offloaded::mlir::dfg::OffloadHardwareAttrThe hardware back to be offloaded to

Operands:

Operand

Description

inputs

variadic of Receiving channel end type

outputs

variadic of Sending channel end type

dfg.loop (dfg::LoopOp)

Defines the repeatedly executed body of a process.

The loop operation defines the repeatedly executed body of a process. During each iteration, operations in the body can pull tokens from the process input ports, perform computations, and push tokens to the process output ports.

The inputs and outputs lists identify the process ports that are monitored for stream termination. A port is closed when no further tokens will be transferred through it. When closure is observed on the listed input ports, the process loop terminates and closure propagates through its listed output ports. This allows downstream processes, and eventually the whole dataflow graph, to shut down.

Example:

dfg.process @add inputs(%a: !dfg.output<type>) outputs(%b: !dfg.input<type>)
{
    dfg.loop inputs(%a: !dfg.output<type>) outputs(%b: !dfg.input<type>) {
        ops ...
    }
}

Traits: AttrSizedOperandSegments, AutomaticAllocationScope, HasParent<ProcessOp>, NoTerminator, RecursiveMemoryEffects

Operands:

Operand

Description

input_channels

variadic of Receiving channel end type

output_channels

variadic of Sending channel end type

dfg.operator (dfg::OperatorOp)

Defines an DFG node in SDF MoC

The operator operation defines one node (actor) in the SDF dataflow model. An operator is a special case of process, which only write values into output ports once at the end.

Example:

dfg.operator @node inputs(%in0: i32, %in1: i32) outputs(%out0: i32, %out1: i32)
{
    ops ...
    dfg.output ...
}

Traits: AffineScope, AutomaticAllocationScope, HasParent<ModuleOp>, IsolatedFromAbove, SingleBlockImplicitTerminator<OutputOp>, SingleBlock

Interfaces: DFG_NodeInterface, OpAsmOpInterface

Attributes:

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute
function_type::mlir::TypeAttrtype attribute of function type

dfg.output (dfg::OutputOp)

Terminator for an OperatorOp

Syntax:

operation ::= `dfg.output` attr-dict ($operands^ `:` type($operands))?

Traits: HasParent<OperatorOp>, Terminator

Operands:

Operand

Description

operands

variadic of any non-token type

dfg.process (dfg::ProcessOp)

Defines a process in the KPN MoC

The process operation defines one node (actor) in the KPN dataflow model. A process is a symbol at module scope and can be connected to other processes through its input and output ports.

The port interface is described by function_type:

  • function inputs represent incoming channel ends

  • function results represent outgoing channel ends

A process can have one region with other IRs inside or none with a link to a library call.

Example:

dfg.process @node inputs(%in0: !dfg.output<type>, %in1: !dfg.output<type>)
                  outputs(%out0: !dfg.input<type>, %out1: !dfg.input<type>)
{
    ops ...
}

Traits: AffineScope, AutomaticAllocationScope, HasParent<ModuleOp>, IsolatedFromAbove, NoTerminator

Interfaces: DFG_NodeInterface, OpAsmOpInterface

Attributes:

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute
function_type::mlir::TypeAttrtype attribute of function type
multiplicity::mlir::DenseI64ArrayAttri64 dense array attribute

dfg.pull (dfg::PullOp)

Pulls a token from an input port of a node.

The pull operation reads a token out from an input port of a node, which is connected via a channel to an output port of another node. An optional set of indices must be used if the read port has a shape, indicating a set of ports to be chosen from.

Example:

dfg.process @pull inputs(%in0: !dfg.output<type>, %in1: !dfg.output<shapextype>)
{
    %0 = arith.constant ... : index
    %token0 = dfg.pull %in0 : !dfg.output<type>
    %token1 = dfg.pull %in1[%0] : !dfg.output<shapextype>
}

Interfaces: OpAsmOpInterface

Operands:

Operand

Description

read_port

Receiving channel end type

indices

variadic of index

Results:

Result

Description

token

any non-token type

dfg.pull_as_memref (dfg::PullAsMemRefOp)

Pulls as a memref from a shaped input port of a node.

Interfaces: OpAsmOpInterface

Operands:

Operand

Description

read_port

Receiving channel end type

Results:

Result

Description

token_memref

memref of any non-token type values

dfg.pull_as_tensor (dfg::PullAsTensorOp)

Pulls as a tensor from a shaped input port of a node.

Interfaces: OpAsmOpInterface

Operands:

Operand

Description

read_port

Receiving channel end type

Results:

Result

Description

token_tensor

ranked tensor of any non-token type values

dfg.push (dfg::PushOp)

Pushes a token to an output port of a node.

The push operation writes a token to an output port of a node, which is connected via a channel to an input port of another node. An optional set of indices must be used if the port has a shape.

Example:

dfg.process @push outputs(%out0: !dfg.input<type>, %out1: !dfg.input<shapextype>)
{
    %0 = arith.constant ... : index
    %1 = arith.constant ... : type
    %token0 = dfg.push %1 to %out0 : !dfg.input<type>
    %token1 = dfg.push %1 to %out1[%0] : !dfg.input<shapextype>
}

Operands:

Operand

Description

token

any non-token type

write_port

Sending channel end type

indices

variadic of index

dfg.push_memref (dfg::PushMemRefOp)

Pushes a memref to a shaped output port of a node.

Operands:

Operand

Description

token_memref

memref of any non-token type values

write_port

Sending channel end type

dfg.push_tensor (dfg::PushTensorOp)

Pushes a tensor to a shaped output port of a node.

Operands:

Operand

Description

token_tensor

ranked tensor of any non-token type values

write_port

Sending channel end type

dfg.region (dfg::RegionOp)

Defines a region(subgraph) in the DFG.

The region operation defines one node(subgraph) or the entire graph in the dataflow graph model. A region can be embedded into another region as subgraph, which content can only be an instantiation of a node(processes/operators/regions) and their connections(channels). A region’s input/output ports must be connected/used.

Example:

dfg.region @node inputs(%in0: !dfg.output<type>, %in1: !dfg.output<type>)
                 outputs(%out0: !dfg.input<type>, %out1: !dfg.input<type>)
{
    %0:2 = dfg.channel ...
    dfg.instantiate @process ...
    dfg.instantiate @operator ...
    dfg.embed @region ...
}

Traits: IsolatedFromAbove, NoTerminator

Interfaces: DFG_GraphInterface, DFG_NodeInterface, OpAsmOpInterface

Attributes:

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute
function_type::mlir::TypeAttrtype attribute of function type

Types

InputType

Sending channel end type

The input type represents the sending end of a dataflow edge in a dataflow graph. This type takes an optional shape and a scalar MLIR type as element type, such as: !dfg.input<i32>, !dfg.input<2xi32>, !dfg.input<2x2xi32>

Parameters:

Parameter

C++ type

Description

shape

::llvm::ArrayRef<int64_t>

elementType

Type

OutputType

Receiving channel end type

The output type represents the receiving end of a dataflow edge in a dataflow graph. Details are similar to dfg::InputType.

Parameters:

Parameter

C++ type

Description

shape

::llvm::ArrayRef<int64_t>

elementType

Type

Enums

OffloadHardware

The hardware back to be offloaded to

Cases:

Symbol

Value

String

EmitHLS

0

emithls

MDC

1

mdc

CGRA

2

cgra