summaryrefslogtreecommitdiff
path: root/mlir/lib/Dialect/XeGPU/TransformOps/XeGPUTransformOps.cpp
diff options
context:
space:
mode:
authorTuomas Kärnä <tuomas.karna@intel.com>2025-11-12 20:57:51 +0200
committerGitHub <noreply@github.com>2025-11-12 18:57:51 +0000
commit7f4a3a98a262f019067c94f5f47e40c5ec1ed380 (patch)
tree8b41b37b3ec2d5f47700f534427ffa91611e8251 /mlir/lib/Dialect/XeGPU/TransformOps/XeGPUTransformOps.cpp
parentec4207baed7bb45a14436480697c283a21bc036f (diff)
[MLIR][XeGPU][TransformOps] Add convert_layout op (#167342)
Adds `transform.xegpu.convert_layout` transform op that inserts an `xegpu.convert_layout` op for a given `Value`.
Diffstat (limited to 'mlir/lib/Dialect/XeGPU/TransformOps/XeGPUTransformOps.cpp')
-rw-r--r--mlir/lib/Dialect/XeGPU/TransformOps/XeGPUTransformOps.cpp104
1 files changed, 104 insertions, 0 deletions
diff --git a/mlir/lib/Dialect/XeGPU/TransformOps/XeGPUTransformOps.cpp b/mlir/lib/Dialect/XeGPU/TransformOps/XeGPUTransformOps.cpp
index d2235f18ceae..e301d4d9bd10 100644
--- a/mlir/lib/Dialect/XeGPU/TransformOps/XeGPUTransformOps.cpp
+++ b/mlir/lib/Dialect/XeGPU/TransformOps/XeGPUTransformOps.cpp
@@ -537,6 +537,110 @@ void transform::InsertPrefetchOp::getEffects(
modifiesPayload(effects);
}
+void transform::ConvertLayoutOp::build(
+ OpBuilder &builder, OperationState &ostate, Value target,
+ ArrayRef<OpFoldResult> mixedInputSgLayout,
+ ArrayRef<OpFoldResult> mixedInputSgData,
+ ArrayRef<OpFoldResult> mixedInputInstData,
+ ArrayRef<OpFoldResult> mixedTargetSgLayout,
+ ArrayRef<OpFoldResult> mixedTargetSgData,
+ ArrayRef<OpFoldResult> mixedTargetInstData) {
+ SmallVector<int64_t> staticInputSgLayout, staticInputSgData,
+ staticInputInstData;
+ SmallVector<Value> dynamicInputSgLayout, dynamicInputSgData,
+ dynamicInputInstData;
+ dispatchIndexOpFoldResults(mixedInputSgLayout, dynamicInputSgLayout,
+ staticInputSgLayout);
+ dispatchIndexOpFoldResults(mixedInputSgData, dynamicInputSgData,
+ staticInputSgData);
+ dispatchIndexOpFoldResults(mixedInputInstData, dynamicInputInstData,
+ staticInputInstData);
+ SmallVector<int64_t> staticTargetSgLayout, staticTargetSgData,
+ staticTargetInstData;
+ SmallVector<Value> dynamicTargetSgLayout, dynamicTargetSgData,
+ dynamicTargetInstData;
+ dispatchIndexOpFoldResults(mixedTargetSgLayout, dynamicTargetSgLayout,
+ staticTargetSgLayout);
+ dispatchIndexOpFoldResults(mixedTargetSgData, dynamicTargetSgData,
+ staticTargetSgData);
+ dispatchIndexOpFoldResults(mixedTargetInstData, dynamicTargetInstData,
+ staticTargetInstData);
+ build(builder, ostate, target.getType(),
+ /*target=*/target,
+ /*input_sg_layout=*/dynamicInputSgLayout,
+ /*input_sg_data=*/dynamicInputSgData,
+ /*input_inst_data=*/dynamicInputInstData,
+ /*target_sg_layout=*/dynamicTargetSgLayout,
+ /*target_sg_data=*/dynamicTargetSgData,
+ /*target_inst_data=*/dynamicTargetInstData,
+ /*static_input_sg_layout=*/staticInputSgLayout,
+ /*static_input_sg_data=*/staticInputSgData,
+ /*static_input_inst_data=*/staticInputInstData,
+ /*static_target_sg_layout=*/staticTargetSgLayout,
+ /*static_target_sg_data=*/staticTargetSgData,
+ /*static_target_inst_data=*/staticTargetInstData);
+}
+
+DiagnosedSilenceableFailure
+transform::ConvertLayoutOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
+ transform::TransformState &state) {
+ auto targetValues = state.getPayloadValues(getTarget());
+ if (!llvm::hasSingleElement(targetValues))
+ return emitDefiniteFailure()
+ << "requires exactly one target value handle (got "
+ << llvm::range_size(targetValues) << ")";
+ auto value = *targetValues.begin();
+
+ // Construct layout attributes.
+ xegpu::LayoutAttr inputLayoutAttr = nullptr;
+ auto status = getLayoutAttrFromOperands(
+ getContext(), state, (*this), getMixedInputSgLayout(),
+ getMixedInputSgData(), getMixedInputInstData(), inputLayoutAttr);
+ if (!status.succeeded())
+ return status;
+
+ xegpu::LayoutAttr targetLayoutAttr = nullptr;
+ status = getLayoutAttrFromOperands(
+ getContext(), state, (*this), getMixedTargetSgLayout(),
+ getMixedTargetSgData(), getMixedTargetInstData(), targetLayoutAttr);
+ if (!status.succeeded())
+ return status;
+
+ // Find first user op to define insertion point for layout conversion.
+ if (value.use_empty())
+ return emitSilenceableFailure(getLoc())
+ << "Value has no users to insert layout conversion.";
+ Operation *userOp = *value.getUsers().begin();
+
+ // Emit convert_layout op.
+ rewriter.setInsertionPoint(userOp);
+ auto convLayoutOp =
+ xegpu::ConvertLayoutOp::create(rewriter, value.getLoc(), value.getType(),
+ value, inputLayoutAttr, targetLayoutAttr);
+ // Replace load op result with the converted layout.
+ rewriter.replaceUsesWithIf(
+ value, convLayoutOp.getResult(), [&](OpOperand &use) {
+ return use.getOwner() != convLayoutOp.getOperation();
+ });
+
+ results.set(llvm::cast<OpResult>(getResult()), {convLayoutOp});
+ return DiagnosedSilenceableFailure::success();
+}
+
+void transform::ConvertLayoutOp::getEffects(
+ ::llvm::SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
+ onlyReadsHandle(getTargetMutable(), effects);
+ onlyReadsHandle(getInputSgLayoutMutable(), effects);
+ onlyReadsHandle(getInputSgDataMutable(), effects);
+ onlyReadsHandle(getInputInstDataMutable(), effects);
+ onlyReadsHandle(getTargetSgLayoutMutable(), effects);
+ onlyReadsHandle(getTargetSgDataMutable(), effects);
+ onlyReadsHandle(getTargetInstDataMutable(), effects);
+ producesHandle(getOperation()->getOpResults(), effects);
+ modifiesPayload(effects);
+}
+
namespace {
class XeGPUTransformDialectExtension
: public transform::TransformDialectExtension<