Skip to content

Commit 38b93c1

Browse files
authored
Adds flag for old transpose behavior on reduction conversion. (#320)
Preferably Triton Shared should not be doing any transposes for optimizations because we lack the wider analysis to understand if these transformations are going to be helpful or not. That will be a part of future work. For now, we need the old transpose behavior on the Reduce Conversion where it just transposes rank - 1 reductions to rank - 2. This old behavior is guarded by a added with a flag that is default to the new behavior.
1 parent 2e65dc9 commit 38b93c1

5 files changed

Lines changed: 45 additions & 17 deletions

File tree

include/triton-shared/Conversion/TritonArithToLinalg/ConversionPatterns.hpp

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,9 +1179,15 @@ struct MatmulConverter : public OpConversionPattern<triton::DotOp> {
11791179
};
11801180

11811181
struct ReduceConverter : public OpConversionPattern<triton::ReduceOp> {
1182-
using OpConversionPattern<triton::ReduceOp>::OpConversionPattern;
1182+
1183+
ReduceConverter(MLIRContext *context, bool transposeToRank0 = true,
1184+
PatternBenefit benefit = 1)
1185+
: OpConversionPattern(context, benefit),
1186+
transposeToRank0(transposeToRank0) {}
11831187

11841188
private:
1189+
bool transposeToRank0;
1190+
11851191
llvm::SmallVector<Operation *> getRedOps(triton::ReduceOp redOp) const {
11861192
auto reduceBlock = redOp.getBody();
11871193
return llvm::map_to_vector(reduceBlock->without_terminator(),
@@ -1307,19 +1313,32 @@ struct ReduceConverter : public OpConversionPattern<triton::ReduceOp> {
13071313
auto rank = sourceType.getRank();
13081314
auto isVectorReduce = (rank == 1);
13091315

1310-
// if it is not a vector reduce, we can transpose the source
1311-
// so that the reduction axis is the first dimension.
1312-
if (!isVectorReduce && axis != 0) {
1313-
SmallVector<int32_t> order;
1314-
order.reserve(rank);
1315-
order.push_back(axis);
1316-
for (int i = 0; i < rank; ++i) {
1317-
if (i != axis) {
1318-
order.push_back(i);
1316+
// For now we are transposing reductions from Triton Shared as an
1317+
// optimization. This should not be the job of Triton Shared so moving
1318+
// forward this will be removed. Doing the transpose here lacks a wider
1319+
// scope of analysis that might indicate that the transpose to a given axis
1320+
// is not optimal.
1321+
if (transposeToRank0) {
1322+
// if it is not a vector reduce, we can transpose the source
1323+
// so that the reduction axis is the first dimension.
1324+
if (!isVectorReduce && axis != 0) {
1325+
SmallVector<int32_t> order;
1326+
order.reserve(rank);
1327+
order.push_back(axis);
1328+
for (int i = 0; i < rank; ++i) {
1329+
if (i != axis) {
1330+
order.push_back(i);
1331+
}
13191332
}
1333+
source = getTransposedValue(source, op.getLoc(), rewriter, order);
1334+
axis = 0;
1335+
}
1336+
} else {
1337+
// preserving old behavior until we remove the transpose entirely.
1338+
if (axis == rank - 1 && !isVectorReduce) {
1339+
source = getTransposedValue(source, op.getLoc(), rewriter);
1340+
axis = rank - 2;
13201341
}
1321-
source = getTransposedValue(source, op.getLoc(), rewriter, order);
1322-
axis = 0;
13231342
}
13241343

13251344
bool convertToF32Precision = requiresF32Conversion(resType, rop);

include/triton-shared/Conversion/TritonArithToLinalg/Passes.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ def TritonArithToLinalg : Pass<"triton-arith-to-linalg", "mlir::ModuleOp"> {
1616
"Convert tt.assert to cf.assert">,
1717
Option<"tensorPtrToLinalg", "tensor-ptr-to-linalg", "bool", /*default*/"false",
1818
"Convert triton ops on tensor of pointers to linalg.generic">,
19+
Option<"transposeReduceToRank0", "transpose-reduce-to-rank0", "bool", /*default*/"true",
20+
"Transpose reductions to rank 0 which collapses remaining dimensions. Otherwise "
21+
"transpose any rank - 1 reduction to rank - 2 as the old behavior. These transposes "
22+
"are planned for removal as Triton Shared should not be responsible for this.">,
1923
];
2024
}
2125

include/triton-shared/Conversion/TritonArithToLinalg/TritonArithToLinalg.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ void populateTritonArithToLinalgCanonicalizationPatterns(
1818
void populateTritonArithToLinalgConversionPatterns(bool pidsToFuncArgs,
1919
bool addptrToLinalg,
2020
bool assertToCf,
21+
bool transposeReduceToRank0,
2122
RewritePatternSet &patterns);
2223

2324
// Expand the triton pointer ops operating on pointers to linalg
2425
void populateTritonTensorPtrConversionPatterns(RewritePatternSet &patterns);
2526

2627
std::unique_ptr<OperationPass<ModuleOp>>
27-
createTritonArithToLinalgPass(bool tensorPtrToLinalg = false);
28+
createTritonArithToLinalgPass(bool tensorPtrToLinalg = false,
29+
bool transposeReduceToRank0 = true);
2830

2931
} // namespace triton
3032
} // namespace mlir

lib/Conversion/TritonArithToLinalg/TritonArithToLinalg.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ void mlir::triton::populateTritonTensorPtrConversionPatterns(
5050

5151
void mlir::triton::populateTritonArithToLinalgConversionPatterns(
5252
bool pidsToFuncArgs, bool addptrToLinalg, bool assertToCf,
53-
RewritePatternSet &patterns) {
53+
bool transposeReduceToRank0, RewritePatternSet &patterns) {
5454

5555
if (pidsToFuncArgs) {
5656
patterns.add<GetProgramIDConverter, GetNumProgramsConverter>(
@@ -96,7 +96,7 @@ void mlir::triton::populateTritonArithToLinalgConversionPatterns(
9696
// aren't always multiple of 2s, which are sub-optimal for certain hardwares.
9797
patterns.add<ArgMinConverter>(patterns.getContext());
9898
patterns.add<ArgMaxConverter>(patterns.getContext());
99-
patterns.add<ReduceConverter>(patterns.getContext());
99+
patterns.add<ReduceConverter>(patterns.getContext(), transposeReduceToRank0);
100100

101101
// Note: the ordering here matters!
102102
// These patterns are added last to they will be tried last.

lib/Conversion/TritonArithToLinalg/TritonArithToLinalgPass.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ class TritonArithToLinalgPass
186186
}
187187

188188
triton::populateTritonArithToLinalgConversionPatterns(
189-
pidsToFuncArgs, addptrToLinalg, assertToCf, patterns);
189+
pidsToFuncArgs, addptrToLinalg, assertToCf, transposeReduceToRank0,
190+
patterns);
190191

191192
if (pidsToFuncArgs) {
192193
for (auto func : getOperation().getOps<triton::FuncOp>()) {
@@ -244,8 +245,10 @@ class TritonArithToLinalgPass
244245
} // namespace
245246

246247
std::unique_ptr<OperationPass<ModuleOp>>
247-
triton::createTritonArithToLinalgPass(bool tensorPtrToLinalg) {
248+
triton::createTritonArithToLinalgPass(bool tensorPtrToLinalg,
249+
bool transposeReduceToRank0) {
248250
TritonArithToLinalgOptions options;
249251
options.tensorPtrToLinalg = tensorPtrToLinalg;
252+
options.transposeReduceToRank0 = transposeReduceToRank0;
250253
return std::make_unique<TritonArithToLinalgPass>(options);
251254
}

0 commit comments

Comments
 (0)