@@ -8795,19 +8795,20 @@ ConvertAtenOp<Aten__InterpolateSizeListScaleListOp>::matchAndRewriteImpl(
87958795 return success ();
87968796}
87978797
8798- // Template to create supporting tril mask tensor for aten.tril
8798+ // Template to create supporting mask tensor for aten.tril/triu
87998799template <typename T>
8800- Value createTrilMask (PatternRewriter &rewriter, Operation *op,
8801- ArrayRef<int64_t > shape, int64_t h, int64_t w,
8802- int64_t diagonal) {
8800+ Value createTrilOrTriuMask (PatternRewriter &rewriter, Operation *op,
8801+ ArrayRef<int64_t > shape, int64_t h, int64_t w,
8802+ int64_t diagonal, bool isTril ) {
88038803 SmallVector<T> vec;
88048804
88058805 for (int64_t i = 0 ; i < h; i++) {
88068806 for (int64_t j = 0 ; j < w; j++) {
88078807 // Positive diagonal value includes as many diagonals above the main
88088808 // diagonal, while negative diagonal value excludes as many diagonals
88098809 // below the main diagonal.
8810- if (i >= j - diagonal) {
8810+ auto cmp = isTril ? i >= j - diagonal : i <= j - diagonal;
8811+ if (cmp) {
88118812 vec.push_back (static_cast <T>(1 ));
88128813 } else {
88138814 vec.push_back (static_cast <T>(0 ));
@@ -8818,13 +8819,10 @@ Value createTrilMask(PatternRewriter &rewriter, Operation *op,
88188819 return tosa::getConstTensor<T>(rewriter, op, vec, shape).value ();
88198820}
88208821
8821- // Legalization for aten.tril
8822- template <>
8823- LogicalResult ConvertAtenOp<AtenTrilOp>::matchAndRewriteImpl(
8824- AtenTrilOp op, OpAdaptor adaptor,
8825- ConversionPatternRewriter &rewriter) const {
8826- auto self = adaptor.getSelf ();
8827-
8822+ template <typename AtenOpT>
8823+ LogicalResult convertTrilOrTriu (AtenOpT op, Value self, Value diagonalVal,
8824+ bool isTril, const TypeConverter *typeConverter,
8825+ ConversionPatternRewriter &rewriter) {
88288826 // Not a ranked tensor type
88298827 auto selfType = dyn_cast<RankedTensorType>(self.getType ());
88308828 if (!selfType)
@@ -8841,27 +8839,33 @@ LogicalResult ConvertAtenOp<AtenTrilOp>::matchAndRewriteImpl(
88418839 return rewriter.notifyMatchFailure (
88428840 op, " Currently only static shapes are supported" );
88438841
8844- const TypeConverter *typeConverter = this ->getTypeConverter ();
88458842 RankedTensorType resultType = cast<RankedTensorType>(
88468843 typeConverter->convertType (op->getResult (0 ).getType ()));
88478844 if (!resultType)
88488845 return rewriter.notifyMatchFailure (op, " Result type cannot be empty" );
88498846
8847+ // clang-format off
88508848 // Get height, width of input tensor, and diagonal arg to create
88518849 // a const mask tensor to multiply with input.
88528850 // This mask tensor has the same height and width of input tensor
8853- // and consists of 1's for the lower triangle part and 0's for the rest.
8854- // For example, with h=4, w=6, diagonal=1:
8851+ // and consists of 1's for the lower/higher triangle part and 0's for the rest.
8852+ // For tril with h=4, w=6, diagonal=1:
88558853 // tensor([[1, 1, 0, 0, 0, 0],
88568854 // [1, 1, 1, 0, 0, 0],
88578855 // [1, 1, 1, 1, 0, 0],
88588856 // [1, 1, 1, 1, 1, 0]])
8857+ // For triu with h=4, w=6, diagonal=1:
8858+ // tensor([[0, 1, 1, 1, 1, 1],
8859+ // [0, 0, 1, 1, 1, 1],
8860+ // [0, 0, 0, 1, 1, 1],
8861+ // [0, 0, 0, 0, 1, 1]])
8862+ // clang-format on
88598863 auto selfShape = selfType.getShape ();
88608864 int64_t h = selfShape[selfRank - 2 ];
88618865 int64_t w = selfShape[selfRank - 1 ];
88628866 int64_t diagonal;
88638867
8864- if (!matchPattern (op. getDiagonal () , m_TorchConstantInt (&diagonal)))
8868+ if (!matchPattern (diagonalVal , m_TorchConstantInt (&diagonal)))
88658869 return rewriter.notifyMatchFailure (op, " Diagonal value is not an integer" );
88668870
88678871 // Define shape for mask tensor based on rank
@@ -8871,39 +8875,56 @@ LogicalResult ConvertAtenOp<AtenTrilOp>::matchAndRewriteImpl(
88718875 maskShape.push_back (h);
88728876 maskShape.push_back (w);
88738877
8874- Value trilMask = TypeSwitch<Type, Value>(resultType. getElementType ())
8875- . Case <mlir::FloatType>([&]( auto ) {
8876- return createTrilMask< float >(rewriter, op, maskShape,
8877- h, w, diagonal);
8878- })
8879- . Case <mlir::IntegerType>([&]( auto intType) {
8880- switch (intType. getWidth () ) {
8881- case 1 :
8882- return createTrilMask< bool >(rewriter, op, maskShape,
8883- h, w, diagonal);
8884- case 32 :
8885- return createTrilMask< int32_t >(
8886- rewriter, op, maskShape, h, w, diagonal);
8887- case 64 :
8888- return createTrilMask< int64_t >(
8889- rewriter, op, maskShape, h, w, diagonal);
8890- }
8891- llvm_unreachable ( " Invalid integer width " );
8892- } );
8893-
8894- if ( mlir::tosa::EqualizeRanks (rewriter, op-> getLoc (), self, trilMask)
8895- .failed ())
8878+ Value mask =
8879+ TypeSwitch<Type, Value>(resultType. getElementType ())
8880+ . Case <mlir::FloatType>([&]( auto ) {
8881+ return createTrilOrTriuMask< float >(rewriter, op, maskShape, h, w,
8882+ diagonal, isTril);
8883+ })
8884+ . template Case <mlir::IntegerType>([&]( auto intType ) {
8885+ switch (intType. getWidth ()) {
8886+ case 1 :
8887+ return createTrilOrTriuMask< bool >(rewriter, op, maskShape, h, w,
8888+ diagonal, isTril);
8889+ case 32 :
8890+ return createTrilOrTriuMask< int32_t >( rewriter, op, maskShape, h,
8891+ w, diagonal, isTril);
8892+ case 64 :
8893+ return createTrilOrTriuMask< int64_t >( rewriter, op, maskShape, h,
8894+ w, diagonal, isTril);
8895+ }
8896+ llvm_unreachable ( " Invalid integer width " );
8897+ });
8898+
8899+ if ( mlir::tosa::EqualizeRanks (rewriter, op-> getLoc (), self, mask) .failed ())
88968900 return rewriter.notifyMatchFailure (
88978901 op, " Failed to equalize ranks among operands and result" );
88988902
8899- auto result =
8900- tosa::createMulOpAndCast (rewriter, op, resultType, self, trilMask,
8901- /* shift=*/ 0 );
8903+ auto result = tosa::createMulOpAndCast (rewriter, op, resultType, self, mask,
8904+ /* shift=*/ 0 );
89028905 rewriter.replaceOp (op, result.getResult ());
89038906
89048907 return success ();
89058908}
89068909
8910+ // Legalization for aten.triu
8911+ template <>
8912+ LogicalResult ConvertAtenOp<AtenTriuOp>::matchAndRewriteImpl(
8913+ AtenTriuOp op, OpAdaptor adaptor,
8914+ ConversionPatternRewriter &rewriter) const {
8915+ return convertTrilOrTriu (op, adaptor.getSelf (), op.getDiagonal (),
8916+ /* isTril=*/ false , getTypeConverter (), rewriter);
8917+ }
8918+
8919+ // Legalization for aten.tril
8920+ template <>
8921+ LogicalResult ConvertAtenOp<AtenTrilOp>::matchAndRewriteImpl(
8922+ AtenTrilOp op, OpAdaptor adaptor,
8923+ ConversionPatternRewriter &rewriter) const {
8924+ return convertTrilOrTriu (op, adaptor.getSelf (), op.getDiagonal (),
8925+ /* isTril=*/ true , getTypeConverter (), rewriter);
8926+ }
8927+
89078928// Legalization for aten.flip
89088929template <>
89098930LogicalResult ConvertAtenOp<AtenFlipOp>::matchAndRewriteImpl(
@@ -11756,6 +11777,7 @@ std::set<StringRef> populateTorchToTosaConversionPatternsAndIllegalOps(
1175611777 INSERT_ATENOP_PATTERN (AtenIscloseOp);
1175711778 INSERT_ATENOP_PATTERN (Aten__InterpolateSizeListScaleListOp);
1175811779 INSERT_ATENOP_PATTERN (AtenTrilOp);
11780+ INSERT_ATENOP_PATTERN (AtenTriuOp);
1175911781 INSERT_ATENOP_PATTERN (AtenDiagonalOp);
1176011782 INSERT_ATENOP_PATTERN (AtenIndexSelectOp);
1176111783 INSERT_ATENOP_PATTERN (AtenFlipOp);
0 commit comments