MLIR

Multi-Level IR Compiler Framework

'omp' Dialect

Operation definition 

omp.atomic.capture (::mlir::omp::AtomicCaptureOp) 

performs an atomic capture

Syntax:

operation ::= `omp.atomic.capture` oilist(`memory_order` `(` custom<ClauseAttr>($memory_order_val) `)`
              |`hint` `(` custom<SynchronizationHint>($hint_val) `)`)
              $region attr-dict

This operation performs an atomic capture.

hint is the value of hint (as used in the hint clause). It is a compile time constant. As the name suggests, this is just a hint for optimization.

memory_order indicates the memory ordering behavior of the construct. It can be one of seq_cst, acq_rel, release, acquire or relaxed.

The region has the following allowed forms:

  omp.atomic.capture {
    omp.atomic.update ...
    omp.atomic.read ...
    omp.terminator
  }

  omp.atomic.capture {
    omp.atomic.read ...
    omp.atomic.update ...
    omp.terminator
  }

  omp.atomic.capture {
    omp.atomic.read ...
    omp.atomic.write ...
    omp.terminator
  }

Traits: SingleBlockImplicitTerminator

Attributes: 

AttributeMLIR TypeDescription
hint_val::mlir::IntegerAttr64-bit signless integer attribute
memory_order_val::mlir::omp::ClauseMemoryOrderKindAttrMemoryOrderKind Clause

omp.atomic.read (::mlir::omp::AtomicReadOp) 

performs an atomic read

Syntax:

operation ::= `omp.atomic.read` $v `=` $x
              oilist( `memory_order` `(` custom<ClauseAttr>($memory_order_val) `)`
              | `hint` `(` custom<SynchronizationHint>($hint_val) `)`)
              `:` type($x) attr-dict

This operation performs an atomic read.

The operand x is the address from where the value is atomically read. The operand v is the address where the value is stored after reading.

hint is the value of hint (as specified in the hint clause). It is a compile time constant. As the name suggests, this is just a hint for optimization.

memory_order indicates the memory ordering behavior of the construct. It can be one of seq_cst, acquire or relaxed.

Attributes: 

AttributeMLIR TypeDescription
hint_val::mlir::IntegerAttr64-bit signless integer attribute
memory_order_val::mlir::omp::ClauseMemoryOrderKindAttrMemoryOrderKind Clause

Operands: 

OperandDescription
xOpenMP-compatible variable type
vOpenMP-compatible variable type

omp.atomic.update (::mlir::omp::AtomicUpdateOp) 

performs an atomic update

Syntax:

operation ::= `omp.atomic.update` oilist( `memory_order` `(` custom<ClauseAttr>($memory_order_val) `)`
              | `hint` `(` custom<SynchronizationHint>($hint_val) `)`)
              $x `:` type($x) $region attr-dict

This operation performs an atomic update.

The operand x is exactly the same as the operand x in the OpenMP Standard (OpenMP 5.0, section 2.17.7). It is the address of the variable that is being updated. x is atomically read/written.

hint is the value of hint (as used in the hint clause). It is a compile time constant. As the name suggests, this is just a hint for optimization.

memory_order indicates the memory ordering behavior of the construct. It can be one of seq_cst, release or relaxed.

The region describes how to update the value of x. It takes the value at x as an input and must yield the updated value. Only the update to x is atomic. Generally the region must have only one instruction, but can potentially have more than one instructions too. The update is sematically similar to a compare-exchange loop based atomic update.

The syntax of atomic update operation is different from atomic read and atomic write operations. This is because only the host dialect knows how to appropriately update a value. For example, while generating LLVM IR, if there are no special atomicrmw instructions for the operation-type combination in atomic update, a compare-exchange loop is generated, where the core update operation is directly translated like regular operations by the host dialect. The front-end must handle semantic checks for allowed operations.

Traits: RecursiveSideEffects, SingleBlockImplicitTerminator

Attributes: 

AttributeMLIR TypeDescription
hint_val::mlir::IntegerAttr64-bit signless integer attribute
memory_order_val::mlir::omp::ClauseMemoryOrderKindAttrMemoryOrderKind Clause

Operands: 

OperandDescription
xOpenMP-compatible variable type

omp.atomic.write (::mlir::omp::AtomicWriteOp) 

performs an atomic write

Syntax:

operation ::= `omp.atomic.write` $address `=` $value
              oilist( `hint` `(` custom<SynchronizationHint>($hint_val) `)`
              | `memory_order` `(` custom<ClauseAttr>($memory_order_val) `)`)
              `:` type($address) `,` type($value)
              attr-dict

This operation performs an atomic write.

The operand address is the address to where the value is atomically written w.r.t. multiple threads. The evaluation of value need not be atomic w.r.t. the write to address. In general, the type(address) must dereference to type(value).

hint is the value of hint (as specified in the hint clause). It is a compile time constant. As the name suggests, this is just a hint for optimization.

memory_order indicates the memory ordering behavior of the construct. It can be one of seq_cst, release or relaxed.

Attributes: 

AttributeMLIR TypeDescription
hint_val::mlir::IntegerAttr64-bit signless integer attribute
memory_order_val::mlir::omp::ClauseMemoryOrderKindAttrMemoryOrderKind Clause

Operands: 

OperandDescription
addressOpenMP-compatible variable type
valueany type

omp.barrier (::mlir::omp::BarrierOp) 

barrier construct

Syntax:

operation ::= `omp.barrier` attr-dict

The barrier construct specifies an explicit barrier at the point at which the construct appears.

omp.cancel (::mlir::omp::CancelOp) 

cancel directive

Syntax:

operation ::= `omp.cancel` `cancellation_construct_type` `(`
              custom<ClauseAttr>($cancellation_construct_type_val) `)`
              ( `if` `(` $if_expr^ `)` )? attr-dict

The cancel construct activates cancellation of the innermost enclosing region of the type specified.

Attributes: 

AttributeMLIR TypeDescription
cancellation_construct_type_val::mlir::omp::ClauseCancellationConstructTypeAttrCancellationConstructType Clause

Operands: 

OperandDescription
if_expr1-bit signless integer

omp.cancellationpoint (::mlir::omp::CancellationPointOp) 

cancellation point directive

Syntax:

operation ::= `omp.cancellationpoint` `cancellation_construct_type` `(`
              custom<ClauseAttr>($cancellation_construct_type_val) `)`
              attr-dict

The cancellation point construct introduces a user-defined cancellation point at which implicit or explicit tasks check if cancellation of the innermost enclosing region of the type specified has been activated.

Attributes: 

AttributeMLIR TypeDescription
cancellation_construct_type_val::mlir::omp::ClauseCancellationConstructTypeAttrCancellationConstructType Clause

omp.critical.declare (::mlir::omp::CriticalDeclareOp) 

declares a named critical section.

Syntax:

operation ::= `omp.critical.declare` $sym_name oilist(`hint` `(` custom<SynchronizationHint>($hint_val) `)`)
              attr-dict

Declares a named critical section.

The name can be used in critical constructs in the dialect.

Interfaces: Symbol

Attributes: 

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute
hint_val::mlir::IntegerAttr64-bit signless integer attribute

omp.critical (::mlir::omp::CriticalOp) 

critical construct

Syntax:

operation ::= `omp.critical` (`(` $name^ `)`)? $region attr-dict

The critical construct imposes a restriction on the associated structured block (region) to be executed by only a single thread at a time.

Interfaces: SymbolUserOpInterface

Attributes: 

AttributeMLIR TypeDescription
name::mlir::FlatSymbolRefAttrflat symbol reference attribute

omp.flush (::mlir::omp::FlushOp) 

flush construct

Syntax:

operation ::= `omp.flush` ( `(` $varList^ `:` type($varList) `)` )? attr-dict

The flush construct executes the OpenMP flush operation. This operation makes a thread’s temporary view of memory consistent with memory and enforces an order on the memory operations of the variables explicitly specified or implied.

Operands: 

OperandDescription
varListOpenMP-compatible variable type

omp.master (::mlir::omp::MasterOp) 

master construct

Syntax:

operation ::= `omp.master` $region attr-dict

The master construct specifies a structured block that is executed by the master thread of the team.

omp.ordered (::mlir::omp::OrderedOp) 

ordered construct without region

Syntax:

operation ::= `omp.ordered` ( `depend_type` `` $depend_type_val^ )?
              ( `depend_vec` `(` $depend_vec_vars^ `:` type($depend_vec_vars) `)` )?
              attr-dict

The ordered construct without region is a stand-alone directive that specifies cross-iteration dependences in a doacross loop nest.

The depend_type_val attribute refers to either the DEPEND(SOURCE) clause or the DEPEND(SINK: vec) clause.

The num_loops_val attribute specifies the number of loops in the doacross nest.

The depend_vec_vars is a variadic list of operands that specifies the index of the loop iterator in the doacross nest for the DEPEND(SOURCE) clause or the index of the element of “vec” for the DEPEND(SINK: vec) clause. It contains the operands in multiple “vec” when multiple DEPEND(SINK: vec) clauses exist in one ORDERED directive.

Attributes: 

AttributeMLIR TypeDescription
depend_type_val::mlir::omp::ClauseDependAttrdepend clause
num_loops_val::mlir::IntegerAttr64-bit signless integer attribute whose minimum value is 0

Operands: 

OperandDescription
depend_vec_varsany type

omp.ordered_region (::mlir::omp::OrderedRegionOp) 

ordered construct with region

Syntax:

operation ::= `omp.ordered_region` ( `simd` $simd^ )? $region attr-dict

The ordered construct with region specifies a structured block in a worksharing-loop, SIMD, or worksharing-loop SIMD region that is executed in the order of the loop iterations.

The simd attribute corresponds to the SIMD clause specified. If it is not present, it behaves as if the THREADS clause is specified or no clause is specified.

Attributes: 

AttributeMLIR TypeDescription
simd::mlir::UnitAttrunit attribute

omp.parallel (::mlir::omp::ParallelOp) 

parallel construct

Syntax:

operation ::= `omp.parallel` oilist( `reduction` `(`
              custom<ReductionVarList>(
              $reduction_vars, type($reduction_vars), $reductions
              ) `)`
              | `if` `(` $if_expr_var `:` type($if_expr_var) `)`
              | `num_threads` `(` $num_threads_var `:` type($num_threads_var) `)`
              | `allocate` `(`
              custom<AllocateAndAllocator>(
              $allocate_vars, type($allocate_vars),
              $allocators_vars, type($allocators_vars)
              ) `)`
              | `proc_bind` `(` custom<ClauseAttr>($proc_bind_val) `)`
              ) $region attr-dict

The parallel construct includes a region of code which is to be executed by a team of threads.

The optional $if_expr_var parameter specifies a boolean result of a conditional check. If this value is 1 or is not provided then the parallel region runs as normal, if it is 0 then the parallel region is executed with one thread.

The optional $num_threads_var parameter specifies the number of threads which should be used to execute the parallel region.

The $allocators_vars and $allocate_vars parameters are a variadic list of values that specify the memory allocator to be used to obtain storage for private values.

Reductions can be performed in a parallel construct by specifying reduction accumulator variables in reduction_vars and symbols referring to reduction declarations in the reductions attribute. Each reduction is identified by the accumulator it uses and accumulators must not be repeated in the same reduction. The omp.reduction operation accepts the accumulator and a partial value which is considered to be produced by the thread for the given reduction. If multiple values are produced for the same accumulator, i.e. there are multiple omp.reductions, the last value is taken. The reduction declaration specifies how to combine the values from each thread into the final value, which is available in the accumulator after all the threads complete.

The optional $proc_bind_val attribute controls the thread affinity for the execution of the parallel region.

Traits: AttrSizedOperandSegments, AutomaticAllocationScope, RecursiveSideEffects

Interfaces: OutlineableOpenMPOpInterface, ReductionClauseInterface

Attributes: 

AttributeMLIR TypeDescription
reductions::mlir::ArrayAttrsymbol ref array attribute
proc_bind_val::mlir::omp::ClauseProcBindKindAttrProcBindKind Clause

Operands: 

OperandDescription
if_expr_var1-bit signless integer
num_threads_varinteger or index
allocate_varsany type
allocators_varsany type
reduction_varsOpenMP-compatible variable type

omp.reduction.declare (::mlir::omp::ReductionDeclareOp) 

declares a reduction kind

Syntax:

operation ::= `omp.reduction.declare` $sym_name `:` $type attr-dict-with-keyword `init` $initializerRegion `combiner` $reductionRegion custom<AtomicReductionRegion>($atomicReductionRegion)

Declares an OpenMP reduction kind. This requires two mandatory and one optional region.

  1. The initializer region specifies how to initialize the thread-local reduction value. This is usually the neutral element of the reduction. For convenience, the region has an argument that contains the value of the reduction accumulator at the start of the reduction. It is expected to omp.yield the new value on all control flow paths.
  2. The reduction region specifies how to combine two values into one, i.e. the reduction operator. It accepts the two values as arguments and is expected to omp.yield the combined value on all control flow paths.
  3. The atomic reduction region is optional and specifies how two values can be combined atomically given local accumulator variables. It is expected to store the combined value in the first accumulator variable.

Note that the MLIR type system does not allow for type-polymorphic reductions. Separate reduction declarations should be created for different element and accumulator types.

For initializer and reduction regions, the operand to omp.yield must match the parent operation’s results.

Traits: IsolatedFromAbove

Interfaces: Symbol

Attributes: 

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute
type::mlir::TypeAttrany type attribute

omp.reduction (::mlir::omp::ReductionOp) 

reduction construct

Syntax:

operation ::= `omp.reduction` $operand `,` $accumulator attr-dict `:` type($accumulator)

Indicates the value that is produced by the current reduction-participating entity for a reduction requested in some ancestor. The reduction is identified by the accumulator, but the value of the accumulator may not be updated immediately.

Operands: 

OperandDescription
operandany type
accumulatorOpenMP-compatible variable type

omp.section (::mlir::omp::SectionOp) 

section directive

Syntax:

operation ::= `omp.section` $region attr-dict

A section operation encloses a region which represents one section in a sections construct. A section op should always be surrounded by an omp.sections operation.

Traits: HasParent

omp.sections (::mlir::omp::SectionsOp) 

sections construct

Syntax:

operation ::= `omp.sections` oilist( `reduction` `(`
              custom<ReductionVarList>(
              $reduction_vars, type($reduction_vars), $reductions
              ) `)`
              | `allocate` `(`
              custom<AllocateAndAllocator>(
              $allocate_vars, type($allocate_vars),
              $allocators_vars, type($allocators_vars)
              ) `)`
              | `nowait` $nowait
              ) $region attr-dict

The sections construct is a non-iterative worksharing construct that contains omp.section operations. The omp.section operations are to be distributed among and executed by the threads in a team. Each omp.section is executed once by one of the threads in the team in the context of its implicit task.

Reductions can be performed in a sections construct by specifying reduction accumulator variables in reduction_vars and symbols referring to reduction declarations in the reductions attribute. Each reduction is identified by the accumulator it uses and accumulators must not be repeated in the same reduction. The omp.reduction operation accepts the accumulator and a partial value which is considered to be produced by the section for the given reduction. If multiple values are produced for the same accumulator, i.e. there are multiple omp.reductions, the last value is taken. The reduction declaration specifies how to combine the values from each section into the final value, which is available in the accumulator after all the sections complete.

The $allocators_vars and $allocate_vars parameters are a variadic list of values that specify the memory allocator to be used to obtain storage for private values.

The nowait attribute, when present, signifies that there should be no implicit barrier at the end of the construct.

Traits: AttrSizedOperandSegments

Interfaces: ReductionClauseInterface

Attributes: 

AttributeMLIR TypeDescription
reductions::mlir::ArrayAttrsymbol ref array attribute
nowait::mlir::UnitAttrunit attribute

Operands: 

OperandDescription
reduction_varsOpenMP-compatible variable type
allocate_varsany type
allocators_varsany type

omp.simdloop (::mlir::omp::SimdLoopOp) 

simd loop construct

Syntax:

operation ::= `omp.simdloop` oilist(`if` `(` $if_expr `)`
              |`simdlen` `(` $simdlen  `)`
              |`safelen` `(` $safelen  `)`
              ) `for` custom<LoopControl>($region, $lowerBound, $upperBound, $step,
              type($step), $inclusive) attr-dict

The simd construct can be applied to a loop to indicate that the loop can be transformed into a SIMD loop (that is, multiple iterations of the loop can be executed concurrently using SIMD instructions).. The lower and upper bounds specify a half-open range: the range includes the lower bound but does not include the upper bound. If the inclusive attribute is specified then the upper bound is also included.

The body region can contain any number of blocks. The region is terminated by “omp.yield” instruction without operands.

Collapsed loops are represented by the simd-loop having a list of indices, bounds and steps where the size of the list is equal to the collapse value.

When an if clause is present and evaluates to false, the preferred number of iterations to be executed concurrently is one, regardless of whether a simdlen clause is specified.

When a simdlen clause is present, the preferred number of iterations to be executed concurrently is the value provided to the simdlen clause.

The safelen clause specifies that no two concurrent iterations within a SIMD chunk can have a distance in the logical iteration space that is greater than or equal to the value given in the clause.

omp.simdloop <clauses>
for (%i1, %i2) : index = (%c0, %c0) to (%c10, %c10) step (%c1, %c1) {
  // block operations
  omp.yield
}

Traits: AttrSizedOperandSegments

Attributes: 

AttributeMLIR TypeDescription
simdlen::mlir::IntegerAttr64-bit signless integer attribute whose value is positive
safelen::mlir::IntegerAttr64-bit signless integer attribute whose value is positive
inclusive::mlir::UnitAttrunit attribute

Operands: 

OperandDescription
lowerBoundinteger or index
upperBoundinteger or index
stepinteger or index
if_expr1-bit signless integer

omp.single (::mlir::omp::SingleOp) 

single directive

Syntax:

operation ::= `omp.single` oilist(`allocate` `(`
              custom<AllocateAndAllocator>(
              $allocate_vars, type($allocate_vars),
              $allocators_vars, type($allocators_vars)
              ) `)`
              |`nowait` $nowait
              ) $region attr-dict

The single construct specifies that the associated structured block is executed by only one of the threads in the team (not necessarily the master thread), in the context of its implicit task. The other threads in the team, which do not execute the block, wait at an implicit barrier at the end of the single construct unless a nowait clause is specified.

Traits: AttrSizedOperandSegments

Attributes: 

AttributeMLIR TypeDescription
nowait::mlir::UnitAttrunit attribute

Operands: 

OperandDescription
allocate_varsany type
allocators_varsany type

omp.target (::mlir::omp::TargetOp) 

target construct

Syntax:

operation ::= `omp.target` oilist( `if` `(` $if_expr `)`
              | `device` `(` $device `:` type($device) `)`
              | `thread_limit` `(` $thread_limit `:` type($thread_limit) `)`
              | `nowait` $nowait
              ) $region attr-dict

The target construct includes a region of code which is to be executed on a device.

The optional $if_expr parameter specifies a boolean result of a conditional check. If this value is 1 or is not provided then the target region runs on a device, if it is 0 then the target region is executed on the host device.

The optional $device parameter specifies the device number for the target region.

The optional $thread_limit specifies the limit on the number of threads

The optional $nowait elliminates the implicit barrier so the parent task can make progress even if the target task is not yet completed.

TODO: map, is_device_ptr, depend, defaultmap, in_reduction

Traits: AttrSizedOperandSegments

Attributes: 

AttributeMLIR TypeDescription
nowait::mlir::UnitAttrunit attribute

Operands: 

OperandDescription
if_expr1-bit signless integer
deviceinteger
thread_limitinteger

omp.taskgroup (::mlir::omp::TaskGroupOp) 

taskgroup construct

Syntax:

operation ::= `omp.taskgroup` oilist(`task_reduction` `(`
              custom<ReductionVarList>(
              $task_reduction_vars, type($task_reduction_vars), $task_reductions
              ) `)`
              |`allocate` `(`
              custom<AllocateAndAllocator>(
              $allocate_vars, type($allocate_vars),
              $allocators_vars, type($allocators_vars)
              ) `)`
              ) $region attr-dict

The taskgroup construct specifies a wait on completion of child tasks of the current task and their descendent tasks.

When a thread encounters a taskgroup construct, it starts executing the region. All child tasks generated in the taskgroup region and all of their descendants that bind to the same parallel region as the taskgroup region are part of the taskgroup set associated with the taskgroup region. There is an implicit task scheduling point at the end of the taskgroup region. The current task is suspended at the task scheduling point until all tasks in the taskgroup set complete execution.

The task_reduction clause specifies a reduction among tasks. For each list item, the number of copies is unspecified. Any copies associated with the reduction are initialized before they are accessed by the tasks participating in the reduction. After the end of the region, the original list item contains the result of the reduction.

The allocators_vars and allocate_vars arguments are a variadic list of values that specify the memory allocator to be used to obtain storage for private values.

Traits: AttrSizedOperandSegments, AutomaticAllocationScope

Interfaces: ReductionClauseInterface

Attributes: 

AttributeMLIR TypeDescription
task_reductions::mlir::ArrayAttrsymbol ref array attribute

Operands: 

OperandDescription
task_reduction_varsOpenMP-compatible variable type
allocate_varsany type
allocators_varsany type

omp.taskloop (::mlir::omp::TaskLoopOp) 

taskloop construct

Syntax:

operation ::= `omp.taskloop` oilist(`if` `(` $if_expr `)`
              |`final` `(` $final_expr `)`
              |`untied` $untied
              |`mergeable` $mergeable
              |`in_reduction` `(`
              custom<ReductionVarList>(
              $in_reduction_vars, type($in_reduction_vars), $in_reductions
              ) `)`
              |`reduction` `(`
              custom<ReductionVarList>(
              $reduction_vars, type($reduction_vars), $reductions
              ) `)`
              |`priority` `(` $priority `:` type($priority) `)`
              |`allocate` `(`
              custom<AllocateAndAllocator>(
              $allocate_vars, type($allocate_vars),
              $allocators_vars, type($allocators_vars)
              ) `)`
              |`grain_size` `(` $grain_size `:` type($grain_size) `)`
              |`num_tasks` `(` $num_tasks `:` type($num_tasks) `)`
              |`nogroup` $nogroup
              ) `for` custom<LoopControl>($region, $lowerBound, $upperBound, $step,
              type($step), $inclusive) attr-dict

The taskloop construct specifies that the iterations of one or more associated loops will be executed in parallel using explicit tasks. The iterations are distributed across tasks generated by the construct and scheduled to be executed.

The lowerBound and upperBound specify a half-open range: the range includes the lower bound but does not include the upper bound. If the inclusive attribute is specified then the upper bound is also included. The step specifies the loop step.

The body region can contain any number of blocks.

omp.taskloop <clauses>
for (%i1, %i2) : index = (%c0, %c0) to (%c10, %c10) step (%c1, %c1) {
  %a = load %arrA[%i1, %i2] : memref<?x?xf32>
  %b = load %arrB[%i1, %i2] : memref<?x?xf32>
  %sum = arith.addf %a, %b : f32
  store %sum, %arrC[%i1, %i2] : memref<?x?xf32>
  omp.terminator
}

For definitions of “undeferred task”, “included task”, “final task” and “mergeable task”, please check OpenMP Specification.

When an if clause is present on a taskloop construct, and if the if clause expression evaluates to false, undeferred tasks are generated. The use of a variable in an if clause expression of a taskloop construct causes an implicit reference to the variable in all enclosing constructs.

When a final clause is present on a taskloop construct and the final clause expression evaluates to true, the generated tasks will be final tasks. The use of a variable in a final clause expression of a taskloop construct causes an implicit reference to the variable in all enclosing constructs.

If the untied clause is specified, all tasks generated by the taskloop construct are untied tasks.

When the mergeable clause is present on a taskloop construct, each generated task is a mergeable task.

Reductions can be performed in a loop by specifying reduction accumulator variables in reduction_vars or in_reduction_vars and symbols referring to reduction declarations in the reductions or in_reductions attribute. Each reduction is identified by the accumulator it uses and accumulators must not be repeated in the same reduction. The omp.reduction operation accepts the accumulator and a partial value which is considered to be produced by the current loop iteration for the given reduction. If multiple values are produced for the same accumulator, i.e. there are multiple omp.reductions, the last value is taken. The reduction declaration specifies how to combine the values from each iteration into the final value, which is available in the accumulator after the loop completes.

If an in_reduction clause is present on the taskloop construct, the behavior is as if each generated task was defined by a task construct on which an in_reduction clause with the same reduction operator and list items is present. Thus, the generated tasks are participants of a reduction previously defined by a reduction scoping clause.

If a reduction clause is present on the taskloop construct, the behavior is as if a task_reduction clause with the same reduction operator and list items was applied to the implicit taskgroup construct enclosing the taskloop construct. The taskloop construct executes as if each generated task was defined by a task construct on which an in_reduction clause with the same reduction operator and list items is present. Thus, the generated tasks are participants of the reduction defined by the task_reduction clause that was applied to the implicit taskgroup construct.

When a priority clause is present on a taskloop construct, the generated tasks use the priority-value as if it was specified for each individual task. If the priority clause is not specified, tasks generated by the taskloop construct have the default task priority (zero).

The allocators_vars and allocate_vars arguments are a variadic list of values that specify the memory allocator to be used to obtain storage for private values.

If a grainsize clause is present on the taskloop construct, the number of logical loop iterations assigned to each generated task is greater than or equal to the minimum of the value of the grain-size expression and the number of logical loop iterations, but less than two times the value of the grain-size expression.

If num_tasks is specified, the taskloop construct creates as many tasks as the minimum of the num-tasks expression and the number of logical loop iterations. Each task must have at least one logical loop iteration.

By default, the taskloop construct executes as if it was enclosed in a taskgroup construct with no statements or directives outside of the taskloop construct. Thus, the taskloop construct creates an implicit taskgroup region. If the nogroup clause is present, no implicit taskgroup region is created.

Traits: AttrSizedOperandSegments, AutomaticAllocationScope, RecursiveSideEffects

Interfaces: ReductionClauseInterface

Attributes: 

AttributeMLIR TypeDescription
inclusive::mlir::UnitAttrunit attribute
untied::mlir::UnitAttrunit attribute
mergeable::mlir::UnitAttrunit attribute
in_reductions::mlir::ArrayAttrsymbol ref array attribute
reductions::mlir::ArrayAttrsymbol ref array attribute
nogroup::mlir::UnitAttrunit attribute

Operands: 

OperandDescription
lowerBoundinteger or index
upperBoundinteger or index
stepinteger or index
if_expr1-bit signless integer
final_expr1-bit signless integer
in_reduction_varsOpenMP-compatible variable type
reduction_varsOpenMP-compatible variable type
priorityinteger or index
allocate_varsany type
allocators_varsany type
grain_sizeinteger or index
num_tasksinteger or index

omp.task (::mlir::omp::TaskOp) 

task construct

Syntax:

operation ::= `omp.task` oilist(`if` `(` $if_expr `)`
              |`final` `(` $final_expr `)`
              |`untied` $untied
              |`mergeable` $mergeable
              |`in_reduction` `(`
              custom<ReductionVarList>(
              $in_reduction_vars, type($in_reduction_vars), $in_reductions
              ) `)`
              |`priority` `(` $priority `)`
              |`allocate` `(`
              custom<AllocateAndAllocator>(
              $allocate_vars, type($allocate_vars),
              $allocators_vars, type($allocators_vars)
              ) `)`
              ) $region attr-dict

The task construct defines an explicit task.

For definitions of “undeferred task”, “included task”, “final task” and “mergeable task”, please check OpenMP Specification.

When an if clause is present on a task construct, and the value of if_expr evaluates to false, an “undeferred task” is generated, and the encountering thread must suspend the current task region, for which execution cannot be resumed until execution of the structured block that is associated with the generated task is completed.

When a final clause is present on a task construct and the final_expr evaluates to true, the generated task will be a “final task”. All task constructs encountered during execution of a final task will generate final and included tasks.

If the untied clause is present on a task construct, any thread in the team can resume the task region after a suspension. The untied clause is ignored if a final clause is present on the same task construct and the final_expr evaluates to true, or if a task is an included task.

When the mergeable clause is present on a task construct, the generated task is a “mergeable task”.

The in_reduction clause specifies that this particular task (among all the tasks in current taskgroup, if any) participates in a reduction.

The priority clause is a hint for the priority of the generated task. The priority is a non-negative integer expression that provides a hint for task execution order. Among all tasks ready to be executed, higher priority tasks (those with a higher numerical value in the priority clause expression) are recommended to execute before lower priority ones. The default priority-value when no priority clause is specified should be assumed to be zero (the lowest priority).

The allocators_vars and allocate_vars arguments are a variadic list of values that specify the memory allocator to be used to obtain storage for private values.

Traits: AttrSizedOperandSegments, AutomaticAllocationScope

Interfaces: OutlineableOpenMPOpInterface, ReductionClauseInterface

Attributes: 

AttributeMLIR TypeDescription
untied::mlir::UnitAttrunit attribute
mergeable::mlir::UnitAttrunit attribute
in_reductions::mlir::ArrayAttrsymbol ref array attribute

Operands: 

OperandDescription
if_expr1-bit signless integer
final_expr1-bit signless integer
in_reduction_varsOpenMP-compatible variable type
priority32-bit signless integer
allocate_varsany type
allocators_varsany type

omp.taskwait (::mlir::omp::TaskwaitOp) 

taskwait construct

Syntax:

operation ::= `omp.taskwait` attr-dict

The taskwait construct specifies a wait on the completion of child tasks of the current task.

omp.taskyield (::mlir::omp::TaskyieldOp) 

taskyield construct

Syntax:

operation ::= `omp.taskyield` attr-dict

The taskyield construct specifies that the current task can be suspended in favor of execution of a different task.

omp.terminator (::mlir::omp::TerminatorOp) 

terminator for OpenMP regions

Syntax:

operation ::= `omp.terminator` attr-dict

A terminator operation for regions that appear in the body of OpenMP operation. These regions are not expected to return any value so the terminator takes no operands. The terminator op returns control to the enclosing op.

Traits: Terminator

Interfaces: NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

omp.threadprivate (::mlir::omp::ThreadprivateOp) 

threadprivate directive

Syntax:

operation ::= `omp.threadprivate` $sym_addr `:` type($sym_addr) `->` type($tls_addr) attr-dict

The threadprivate directive specifies that variables are replicated, with each thread having its own copy.

The current implementation uses the OpenMP runtime to provide thread-local storage (TLS). Using the TLS feature of the LLVM IR will be supported in future.

This operation takes in the address of a symbol that represents the original variable and returns the address of its TLS. All occurrences of threadprivate variables in a parallel region should use the TLS returned by this operation.

The sym_addr refers to the address of the symbol, which is a pointer to the original variable.

Operands: 

OperandDescription
sym_addrOpenMP-compatible variable type

Results: 

ResultDescription
tls_addrOpenMP-compatible variable type

omp.wsloop (::mlir::omp::WsLoopOp) 

worksharing-loop construct

Syntax:

operation ::= `omp.wsloop` oilist(`linear` `(`
              custom<LinearClause>($linear_vars, type($linear_vars),
              $linear_step_vars) `)`
              |`schedule` `(`
              custom<ScheduleClause>(
              $schedule_val, $schedule_modifier, $simd_modifier,
              $schedule_chunk_var, type($schedule_chunk_var)) `)`
              |`nowait` $nowait
              |`ordered` `(` $ordered_val `)`
              |`order` `(` custom<ClauseAttr>($order_val) `)`
              |`reduction` `(`
              custom<ReductionVarList>(
              $reduction_vars, type($reduction_vars), $reductions
              ) `)`
              ) `for` custom<LoopControl>($region, $lowerBound, $upperBound, $step,
              type($step), $inclusive) attr-dict

The worksharing-loop construct specifies that the iterations of the loop(s) will be executed in parallel by threads in the current context. These iterations are spread across threads that already exist in the enclosing parallel region. The lower and upper bounds specify a half-open range: the range includes the lower bound but does not include the upper bound. If the inclusive attribute is specified then the upper bound is also included.

The body region can contain any number of blocks. The region is terminated by “omp.yield” instruction without operands.

omp.wsloop <clauses>
for (%i1, %i2) : index = (%c0, %c0) to (%c10, %c10) step (%c1, %c1) {
  %a = load %arrA[%i1, %i2] : memref<?x?xf32>
  %b = load %arrB[%i1, %i2] : memref<?x?xf32>
  %sum = arith.addf %a, %b : f32
  store %sum, %arrC[%i1, %i2] : memref<?x?xf32>
  omp.yield
}

The linear_step_vars operand additionally specifies the step for each associated linear operand. Note that the linear_vars and linear_step_vars variadic lists should contain the same number of elements.

Reductions can be performed in a worksharing-loop by specifying reduction accumulator variables in reduction_vars and symbols referring to reduction declarations in the reductions attribute. Each reduction is identified by the accumulator it uses and accumulators must not be repeated in the same reduction. The omp.reduction operation accepts the accumulator and a partial value which is considered to be produced by the current loop iteration for the given reduction. If multiple values are produced for the same accumulator, i.e. there are multiple omp.reductions, the last value is taken. The reduction declaration specifies how to combine the values from each iteration into the final value, which is available in the accumulator after the loop completes.

The optional schedule_val attribute specifies the loop schedule for this loop, determining how the loop is distributed across the parallel threads. The optional schedule_chunk_var associated with this determines further controls this distribution.

Collapsed loops are represented by the worksharing-loop having a list of indices, bounds and steps where the size of the list is equal to the collapse value.

The nowait attribute, when present, signifies that there should be no implicit barrier at the end of the loop.

The optional ordered_val attribute specifies how many loops are associated with the worksharing-loop construct. The value of zero refers to the ordered clause specified without parameter.

The optional order attribute specifies which order the iterations of the associate loops are executed in. Currently the only option for this attribute is “concurrent”.

Traits: AttrSizedOperandSegments, RecursiveSideEffects

Interfaces: ReductionClauseInterface

Attributes: 

AttributeMLIR TypeDescription
reductions::mlir::ArrayAttrsymbol ref array attribute
schedule_val::mlir::omp::ClauseScheduleKindAttrScheduleKind Clause
schedule_modifier::mlir::omp::ScheduleModifierAttrOpenMP Schedule Modifier
simd_modifier::mlir::UnitAttrunit attribute
nowait::mlir::UnitAttrunit attribute
ordered_val::mlir::IntegerAttr64-bit signless integer attribute whose minimum value is 0
order_val::mlir::omp::ClauseOrderKindAttrOrderKind Clause
inclusive::mlir::UnitAttrunit attribute

Operands: 

OperandDescription
lowerBoundinteger or index
upperBoundinteger or index
stepinteger or index
linear_varsany type
linear_step_vars32-bit signless integer
reduction_varsOpenMP-compatible variable type
schedule_chunk_varany type

omp.yield (::mlir::omp::YieldOp) 

loop yield and termination operation

Syntax:

operation ::= `omp.yield` ( `(` $results^ `:` type($results) `)` )? attr-dict

“omp.yield” yields SSA values from the OpenMP dialect op region and terminates the region. The semantics of how the values are yielded is defined by the parent operation.

Traits: HasParent<WsLoopOp, ReductionDeclareOp, AtomicUpdateOp, SimdLoopOp>, ReturnLike, Terminator

Interfaces: NoSideEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands: 

OperandDescription
resultsany type

Attribute definition 

ClauseCancellationConstructTypeAttr 

CancellationConstructType Clause

Syntax:

!omp.cancellationconstructtype<
  ::mlir::omp::ClauseCancellationConstructType   # value
>

Parameters: 

ParameterC++ typeDescription
value::mlir::omp::ClauseCancellationConstructTypean enum of type ClauseCancellationConstructType

ClauseDependAttr 

depend clause

Syntax:

!omp.clause_depend<
  ::mlir::omp::ClauseDepend   # value
>

Parameters: 

ParameterC++ typeDescription
value::mlir::omp::ClauseDependan enum of type ClauseDepend

ClauseMemoryOrderKindAttr 

MemoryOrderKind Clause

Syntax:

!omp.memoryorderkind<
  ::mlir::omp::ClauseMemoryOrderKind   # value
>

Parameters: 

ParameterC++ typeDescription
value::mlir::omp::ClauseMemoryOrderKindan enum of type ClauseMemoryOrderKind

ClauseOrderKindAttr 

OrderKind Clause

Syntax:

!omp.orderkind<
  ::mlir::omp::ClauseOrderKind   # value
>

Parameters: 

ParameterC++ typeDescription
value::mlir::omp::ClauseOrderKindan enum of type ClauseOrderKind

ClauseProcBindKindAttr 

ProcBindKind Clause

Syntax:

!omp.procbindkind<
  ::mlir::omp::ClauseProcBindKind   # value
>

Parameters: 

ParameterC++ typeDescription
value::mlir::omp::ClauseProcBindKindan enum of type ClauseProcBindKind

ClauseScheduleKindAttr 

ScheduleKind Clause

Syntax:

!omp.schedulekind<
  ::mlir::omp::ClauseScheduleKind   # value
>

Parameters: 

ParameterC++ typeDescription
value::mlir::omp::ClauseScheduleKindan enum of type ClauseScheduleKind

ScheduleModifierAttr 

OpenMP Schedule Modifier

Syntax:

!omp.sched_mod<
  ::mlir::omp::ScheduleModifier   # value
>

Parameters: 

ParameterC++ typeDescription
value::mlir::omp::ScheduleModifieran enum of type ScheduleModifier