mlir.dialects._loop_transform_ops_gen¶
Attributes¶
Classes¶
Collects patterns for canonicalizing operations inside SCF loop bodies. |
|
Collects patterns for performing structural conversions of SCF operations. |
|
Collects patterns that lower structured control flow ops to unstructured |
|
Converts the |
|
Converts the |
|
This transform hoists loop-invariant subset ops out of the targeted |
|
Given a perfect loop nest identified by the outermost loop, |
|
Fuses the |
|
Moves the loop into a separate function with the specified name and replaces |
|
Rewrite the given loop with a main loop and a partial (first or last) loop. |
|
Transforms the given loops one by one to achieve software pipelining for |
|
Promotes the given target loop op if it has a single iteration. I.e., the |
|
Unrolls & jams each loop associated with the given handle to have up to the given |
|
Unrolls each loop associated with the given handle to have up to the given |
|
Converts the |
|
Given an scf.if conditional, inject user-defined information that it is |
Functions¶
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Module Contents¶
- mlir.dialects._loop_transform_ops_gen._ods_ir¶
- class mlir.dialects._loop_transform_ops_gen.ApplyForLoopCanonicalizationPatternsOp(*, loc=None, ip=None)¶
Bases:
_ods_irCollects patterns for canonicalizing operations inside SCF loop bodies. At the moment, only affine.min/max computations with iteration variables, loop bounds and loop steps are canonicalized.
- OPERATION_NAME = 'transform.apply_patterns.scf.for_loop_canonicalization'¶
- _ODS_REGIONS = (0, True)¶
- mlir.dialects._loop_transform_ops_gen.apply_patterns_scf_for_loop_canonicalization(*, loc=None, ip=None) ApplyForLoopCanonicalizationPatternsOp¶
- class mlir.dialects._loop_transform_ops_gen.ApplySCFStructuralConversionPatternsOp(*, loc=None, ip=None)¶
Bases:
_ods_irCollects patterns for performing structural conversions of SCF operations.
- OPERATION_NAME = 'transform.apply_conversion_patterns.scf.structural_conversions'¶
- _ODS_REGIONS = (0, True)¶
- mlir.dialects._loop_transform_ops_gen.apply_conversion_patterns_scf_structural_conversions(*, loc=None, ip=None) ApplySCFStructuralConversionPatternsOp¶
- class mlir.dialects._loop_transform_ops_gen.ApplySCFToControlFlowPatternsOp(*, loc=None, ip=None)¶
Bases:
_ods_irCollects patterns that lower structured control flow ops to unstructured control flow.
- OPERATION_NAME = 'transform.apply_conversion_patterns.scf.scf_to_control_flow'¶
- _ODS_REGIONS = (0, True)¶
- mlir.dialects._loop_transform_ops_gen.apply_conversion_patterns_scf_scf_to_control_flow(*, loc=None, ip=None) ApplySCFToControlFlowPatternsOp¶
- class mlir.dialects._loop_transform_ops_gen.ForallToForOp(transformed, target, *, loc=None, ip=None)¶
Bases:
_ods_irConverts the
scf.foralloperation pointed to by the given handle into a set of nestedscf.foroperations. Each new operation corresponds to one induction variable of the original “multifor” loop.The operand handle must be associated with exactly one payload operation.
Loops with shared outputs are currently not supported.
Return Modes¶
Consumes the operand handle. Produces a silenceable failure if the operand is not associated with a single
scf.forallpayload operation. Returns as many handles as the givenforallop has induction variables that are associated with the generatedscf.forloops. Produces a silenceable failure if another number of resulting handles is requested.- OPERATION_NAME = 'transform.loop.forall_to_for'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- transformed() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_forall_to_for(transformed, target, *, loc=None, ip=None) _ods_ir | _ods_ir | ForallToForOp¶
- class mlir.dialects._loop_transform_ops_gen.ForallToParallelOp(transformed, target, *, loc=None, ip=None)¶
Bases:
_ods_irConverts the
scf.foralloperation pointed to by the given handle into anscf.paralleloperation.The operand handle must be associated with exactly one payload operation.
Loops with outputs are not supported.
Return Modes¶
Consumes the operand handle. Produces a silenceable failure if the operand is not associated with a single
scf.forallpayload operation. Returns a handle to the newscf.paralleloperation. Produces a silenceable failure if another number of resulting handles is requested.- OPERATION_NAME = 'transform.loop.forall_to_parallel'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- transformed() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_forall_to_parallel(transformed, target, *, loc=None, ip=None) _ods_ir | _ods_ir | ForallToParallelOp¶
- class mlir.dialects._loop_transform_ops_gen.HoistLoopInvariantSubsetsOp(target, *, loc=None, ip=None)¶
Bases:
_ods_irThis transform hoists loop-invariant subset ops out of the targeted loop-like op. It looks for matching subset extraction/insertion op pairs and hoists them. The loop body operates on a newly introduced region iter_arg.
Subset ops are hoisted only from the targeted op. If subset ops should be hoisted from an entire loop nest, this transformation must be applied to each loop-like op of the loop nest, starting with the innermost loop and ending with the outermost loop.
Example:
%r = scf.for ... iter_args(%t = %a) -> (tensor<?xf32>) { %0 = tensor.extract_slice %t[0][5][1] : tensor<?xf32> to tensor<5xf32> %1 = "test.foo"(%0) : (tensor<5xf32>) -> (tensor<5xf32>) %2 = tensor.insert_slice %1 into %t[0][5][1] : tensor<5xf32> into tensor<?xf32> scf.yield %2 : tensor<?xf32> }Is transformed to:
%0 = tensor.extract_slice %a[0][5][1] : tensor<?xf32> to tensor<5xf32> %new_loop:2 = scf.for ... iter_args(%t = %a, %h = %0) -> (tensor<?xf32>) { %1 = "test.foo"(%h) : (tensor<5xf32>) -> (tensor<5xf32>) scf.yield %t, %2 : tensor<?xf32>, tensor<5xf32> } %r = tensor.insert_slice %new_loop#1 into %new_loop#0 : tensor<5xf32> into tensor<?xf32>Subset ops are hoisted only if there are no conflicting subset ops. E.g., if there were a second overlapping extraction in the above example, no ops could be hoisted safely.
This transform reads the target handle and modifies the payload. This transform does not invalidate any handles, but loop-like ops are replaced with new loop-like ops when a subset op is hoisted. The transform rewriter updates all handles accordingly.
- OPERATION_NAME = 'transform.loop.hoist_loop_invariant_subsets'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_hoist_loop_invariant_subsets(target, *, loc=None, ip=None) HoistLoopInvariantSubsetsOp¶
- class mlir.dialects._loop_transform_ops_gen.LoopCoalesceOp(transformed, target, *, loc=None, ip=None)¶
Bases:
_ods_irGiven a perfect loop nest identified by the outermost loop, perform loop coalescing in a bottom-up one-by-one manner.
Return modes¶
The return handle points to the coalesced loop if coalescing happens, or the given input loop if coalescing does not happen.
- OPERATION_NAME = 'transform.loop.coalesce'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- transformed() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_coalesce(transformed, target, *, loc=None, ip=None) _ods_ir¶
- class mlir.dialects._loop_transform_ops_gen.LoopFuseSiblingOp(fused_loop, target, source, *, loc=None, ip=None)¶
Bases:
_ods_irFuses the
targetloop into thesourceloop assuming they are independent of each other. In the fused loop, the arguments, body and results oftargetare placed before those ofsource.For fusion of two
scf.forloops, the bounds and step size must match. For fusion of twoscf.forallloops, the bounds and the mapping must match. Otherwise a silencable failure is produced.The
targetandsourcehandles must refer to exactly one operation, otherwise a definite failure is produced. It is the responsibility of the user to ensure that thetargetandsourceloops are independent of each other – this op will only perform rudimentary legality checks.Return modes¶
This operation consumes the
targetandsourcehandles and produces thefused_loophandle, which points to the fused loop.- OPERATION_NAME = 'transform.loop.fuse_sibling'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- source() _ods_ir¶
- fused_loop() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_fuse_sibling(fused_loop, target, source, *, loc=None, ip=None) _ods_ir¶
- class mlir.dialects._loop_transform_ops_gen.LoopOutlineOp(function, call, target, func_name, *, loc=None, ip=None)¶
Bases:
_ods_irMoves the loop into a separate function with the specified name and replaces the loop in the Payload IR with a call to that function. Takes care of forwarding values that are used in the loop as function arguments. If the operand is associated with more than one loop, each loop will be outlined into a separate function. The provided name is used as a base for forming actual function names following
SymbolTableauto-renaming scheme to avoid duplicate symbols. Expects that all ops in the Payload IR have aSymbolTableancestor (typically true because of the top-level module).Return Modes¶
Returns a handle to the list of outlined functions and a handle to the corresponding function call operations in the same order as the operand handle.
Produces a definite failure if outlining failed for any of the targets.
- OPERATION_NAME = 'transform.loop.outline'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- func_name() _ods_ir¶
- function() _ods_ir¶
- call() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_outline(function, call, target, func_name, *, loc=None, ip=None) _ods_ir¶
- class mlir.dialects._loop_transform_ops_gen.LoopPeelOp(peeled_loop, remainder_loop, target, *, peel_front=None, fail_if_already_divisible=None, loc=None, ip=None)¶
Bases:
_ods_irRewrite the given loop with a main loop and a partial (first or last) loop. When the
peelFrontoption is set to true, the first iteration is peeled off. Otherwise, updates the given loop so that its step evenly divides its range and puts the remaining iteration into a separate loop or a conditional.In the absence of sufficient static information, this op may peel a loop, even if the step always divides the range evenly at runtime.
Return modes¶
This operation ignores non-scf::ForOp ops and drops them in the return. The op returns two loops, the peeled loop which has trip count divisible by the step, and the remainder loop.
When
peelFrontis true, the first result (remainder loop) executes all but the first iteration of the target loop. The second result (peeled loop) corresponds to the first iteration of the loop which can be canonicalized away in the following optimizations.When
peelFrontis false, the first result (peeled loop) is the portion of the target loop with the highest upper bound that is divisible by the step. The second result (remainder loop) contains the remaining iterations.Note that even though the Payload IR modification may be performed in-place, this operation consumes the operand handle and produces a new one.
Return Modes¶
Produces a definite failure if peeling fails.
- OPERATION_NAME = 'transform.loop.peel'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- peel_front() _ods_ir¶
- fail_if_already_divisible() _ods_ir¶
- peeled_loop() _ods_ir¶
- remainder_loop() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_peel(peeled_loop, remainder_loop, target, *, peel_front=None, fail_if_already_divisible=None, loc=None, ip=None) _ods_ir¶
- class mlir.dialects._loop_transform_ops_gen.LoopPipelineOp(transformed, target, *, iteration_interval=None, read_latency=None, loc=None, ip=None)¶
Bases:
_ods_irTransforms the given loops one by one to achieve software pipelining for each of them. That is, performs some amount of reads from memory before the loop rather than inside the loop, the same amount of writes into memory after the loop, and updates each iteration to read the data for a following iteration rather than the current one.
The amount is specified by the attributes.
The values read and about to be stored are transferred as loop iteration arguments. Currently supports memref and vector transfer operations as memory reads/writes.
Return modes¶
This operation ignores non-scf::For ops and drops them in the return. If all the operations referred to by the
targetPDLOperation pipeline properly, the transform succeeds. Otherwise the transform produces a silenceable failure. The return handle points to only the subset of successfully produced pipelined loops, which can be empty.- OPERATION_NAME = 'transform.loop.pipeline'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- iteration_interval() _ods_ir¶
- read_latency() _ods_ir¶
- transformed() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_pipeline(transformed, target, *, iteration_interval=None, read_latency=None, loc=None, ip=None) _ods_ir¶
- class mlir.dialects._loop_transform_ops_gen.LoopPromoteIfOneIterationOp(target, *, loc=None, ip=None)¶
Bases:
_ods_irPromotes the given target loop op if it has a single iteration. I.e., the loop op is removed and only the body remains.
Return modes¶
This transform fails if the target is mapped to ops that are loops. Ops are considered loops if they implement the
LoopLikeOpInterface. Otherwise, this transform always succeeds. The transform consumes the target handle and modifies the payload.- OPERATION_NAME = 'transform.loop.promote_if_one_iteration'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_promote_if_one_iteration(target, *, loc=None, ip=None) LoopPromoteIfOneIterationOp¶
- class mlir.dialects._loop_transform_ops_gen.LoopUnrollAndJamOp(target, factor, *, loc=None, ip=None)¶
Bases:
_ods_irUnrolls & jams each loop associated with the given handle to have up to the given number of loop body copies per iteration. If the unroll factor is larger than the loop trip count, the latter is used as the unroll factor instead.
Return modes¶
This operation ignores non-
scf.for, non-affine.forops and drops them in the return. If all the operations referred to by thetargetoperand unroll properly, the transform succeeds. Otherwise the transform produces a silenceable failure.Does not return handles as the operation may result in the loop being removed after a full unrolling.
- OPERATION_NAME = 'transform.loop.unroll_and_jam'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- factor() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_unroll_and_jam(target, factor, *, loc=None, ip=None) LoopUnrollAndJamOp¶
- class mlir.dialects._loop_transform_ops_gen.LoopUnrollOp(target, factor, *, loc=None, ip=None)¶
Bases:
_ods_irUnrolls each loop associated with the given handle to have up to the given number of loop body copies per iteration. If the unroll factor is larger than the loop trip count, the latter is used as the unroll factor instead.
Return modes¶
This operation ignores non-
scf.for, non-affine.forops and drops them in the return. If all the operations referred to by thetargetoperand unroll properly, the transform succeeds. Otherwise the transform produces a silenceable failure.Does not return handles as the operation may result in the loop being removed after a full unrolling.
- OPERATION_NAME = 'transform.loop.unroll'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- factor() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_unroll(target, factor, *, loc=None, ip=None) LoopUnrollOp¶
- class mlir.dialects._loop_transform_ops_gen.ParallelForToNestedForOps(transformed, target, *, loc=None, ip=None)¶
Bases:
_ods_irConverts the
scf.paralleloperation pointed to by the given handle into a set of nestedscf.foroperations. Each new operation corresponds to one dimension of the original parallel loop.The operand handle must be associated with exactly one payload operation.
Loops with shared outputs are currently not supported.
Return Modes¶
Consumes the operand handle. Produces a silenceable failure if the operand is not associated with a single
scf.parallelpayload operation. Returns as many handles as the givenparallelop has dimensions that are associated with the generatedscf.forloops. Produces a silenceable failure if another number of resulting handles is requested.- OPERATION_NAME = 'transform.loop.parallel_for_to_nested_fors'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- transformed() _ods_ir¶
- mlir.dialects._loop_transform_ops_gen.loop_parallel_for_to_nested_fors(transformed, target, *, loc=None, ip=None) _ods_ir | _ods_ir | ParallelForToNestedForOps¶
- class mlir.dialects._loop_transform_ops_gen.TakeAssumedBranchOp(target, *, take_else_branch=None, loc=None, ip=None)¶
Bases:
_ods_irGiven an scf.if conditional, inject user-defined information that it is always safe to execute only the if or else branch.
This is achieved by just replacing the scf.if by the content of one of its branches.
This is particularly useful for user-controlled rewriting of conditionals that exist solely to guard against out-of-bounds behavior.
At the moment, no assume or assert operation is emitted as it is not always desirable. In the future, this may be controlled by a dedicated attribute.
Return modes¶
The transform only consumes its operand and does not produce any result. The transform definitely fails if
take_else_branchis specified and theelseregion is empty.- OPERATION_NAME = 'transform.scf.take_assumed_branch'¶
- _ODS_REGIONS = (0, True)¶
- target() _ods_ir¶
- take_else_branch() bool¶
- mlir.dialects._loop_transform_ops_gen.scf_take_assumed_branch(target, *, take_else_branch=None, loc=None, ip=None) TakeAssumedBranchOp¶