Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion mlir/lib/Dialect/Linalg/Utils/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,8 +596,17 @@ computeSliceParameters(OpBuilder &builder, Location loc, Value valueToTile,
auto m = map.getSubMap({r});
LLVM_DEBUG(llvm::dbgs() << "computeSliceParameters: submap: " << m << "\n");
IRRewriter rewriter(builder);
OpFoldResult offset = makeComposedFoldedAffineApply(rewriter, loc, m, lbs);
// The offset of the slice is map(lbs) - map(0).
SmallVector<Attribute> zeros(lbs.size(), rewriter.getIndexAttr(0));
SmallVector<Attribute> mAtZero;
auto res = m.constantFold(zeros, mAtZero);
assert(succeeded(res));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the res is not used anyway... So in non-debug builds this will show up as warning/error (if warnings are converted to error). What is the constantFold for?

Could you also add a message to the assert.

Copy link
Contributor Author

@mgehre-amd mgehre-amd Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The m.constantFold is evaluating the affine map m with all inputs being zero.
The constantFold returns failure() when the affine map has symbols, but afaik linalg guarantees that the affine map has no symbols, thus the evaluation of m into a constant is always possible. (Thus the assert; I added a message to it).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also added [[maybe_unused]] to res to avoid errors in non-debug configs.

auto atZeroInt = getConstantIntValue(mAtZero[0]);
assert(atZeroInt);
OpFoldResult offset = makeComposedFoldedAffineApply(
rewriter, loc, m.getResult(0) - *atZeroInt, lbs);
sliceParams.offsets.push_back(offset);

OpFoldResult closedIntSize =
makeComposedFoldedAffineApply(rewriter, loc, m, subShapeSizes);
// Resulting size needs to be made half open interval again.
Expand Down
25 changes: 25 additions & 0 deletions mlir/test/Dialect/Linalg/tile-offset.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: mlir-opt %s -transform-interpreter -split-input-file | FileCheck %s

// CHECK-LABEL: func @tile_offset
// CHECK-SAME: %[[ARG0:[a-zA-Z0-9_]+]]:
func.func @tile_offset(%arg0 : tensor<9xf32>) -> tensor<6xf32> {
%empty = tensor.empty() : tensor<6xf32>
// CHECK: scf.for %[[ITER:[a-zA-Z0-9_]+]] =
// CHECK: tensor.extract_slice %[[ARG0]][%[[ITER]]] [6] [1]
%generic = linalg.generic
{indexing_maps = [affine_map<(d0) -> (d0 + 3)>,
affine_map<(d0) -> (d0)>],
iterator_types = ["parallel"]} ins(%arg0: tensor<9xf32>) outs(%empty : tensor<6xf32>) {
^bb0(%in : f32, %out: f32):
linalg.yield %in : f32
} -> tensor<6xf32>
return %generic : tensor<6xf32>
}

module attributes {transform.with_named_sequence} {
transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {
%0 = transform.structured.match ops{["linalg.generic"]} in %arg1 : (!transform.any_op) -> !transform.any_op
%1, %loop = transform.structured.tile_using_for %0 tile_sizes [3] : (!transform.any_op) -> (!transform.any_op, !transform.any_op)
transform.yield
}
}
Loading