Skip to content

Commit

Permalink
[Torch] support float_power and threshold ops (#3854)
Browse files Browse the repository at this point in the history
  • Loading branch information
yyp0 authored Nov 7, 2024
1 parent 2f33f31 commit dda65b1
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 7 deletions.
24 changes: 24 additions & 0 deletions include/torch-mlir/Dialect/Torch/IR/GeneratedTorchOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -5242,6 +5242,30 @@ def Torch_AtenPowScalarOp : Torch_Op<"aten.pow.Scalar", [
}];
}

def Torch_AtenFloatPowerTensorTensorOp : Torch_Op<"aten.float_power.Tensor_Tensor", [
AllowsTypeRefinement,
HasValueSemantics,
ReadOnly
]> {
let summary = "Generated op for `aten::float_power.Tensor_Tensor : (Tensor, Tensor) -> (Tensor)`";
let arguments = (ins
AnyTorchTensorType:$self,
AnyTorchTensorType:$exponent
);
let results = (outs
AnyTorchOptionalTensorType:$result
);
let hasCustomAssemblyFormat = 1;
let extraClassDefinition = [{
ParseResult AtenFloatPowerTensorTensorOp::parse(OpAsmParser &parser, OperationState &result) {
return parseDefaultTorchOp(parser, result, 2, 1);
}
void AtenFloatPowerTensorTensorOp::print(OpAsmPrinter &printer) {
printDefaultTorchOp(printer, *this, 2, 1);
}
}];
}

def Torch_AtenThresholdBackwardOp : Torch_Op<"aten.threshold_backward", [
AllowsTypeRefinement,
HasValueSemantics,
Expand Down
60 changes: 60 additions & 0 deletions lib/Dialect/Torch/Transforms/DecomposeComplexOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10439,6 +10439,63 @@ class DecomposeAtenFMaxMinOp : public OpRewritePattern<AtenFOpT> {
};
} // namespace

namespace {
class DecomposeAtenThresholdOp : public OpRewritePattern<AtenThresholdOp> {
public:
using OpRewritePattern<AtenThresholdOp>::OpRewritePattern;
LogicalResult matchAndRewrite(AtenThresholdOp op,
PatternRewriter &rewriter) const override {
Location loc = op.getLoc();
Value self = op.getSelf();
auto selfType = dyn_cast<BaseTensorType>(self.getType());
if (!selfType || !selfType.hasSizes()) {
return rewriter.notifyMatchFailure(op,
"requires input is tensor with sizes");
}

Value threshold = op.getThreshold();
Value value = op.getValue();

auto comOp = rewriter.create<AtenGtScalarOp>(
loc,
selfType.getWithSizesAndDtype(selfType.getSizes(),
rewriter.getI1Type()),
self, threshold);

rewriter.replaceOpWithNewOp<AtenWhereScalarOtherOp>(op, op.getType(), comOp,
self, value);
return success();
}
};
} // namespace

namespace {
class DecomposeAtenFloatPowerTensorTensorOp
: public OpRewritePattern<AtenFloatPowerTensorTensorOp> {
public:
using OpRewritePattern<AtenFloatPowerTensorTensorOp>::OpRewritePattern;
LogicalResult matchAndRewrite(AtenFloatPowerTensorTensorOp op,
PatternRewriter &rewriter) const override {
Location loc = op.getLoc();
Value self = op.getSelf();
Value exp = op.getExponent();

auto selfTy = dyn_cast<BaseTensorType>(self.getType());
if (!selfTy || !selfTy.hasDtype() || !selfTy.hasSizes()) {
return rewriter.notifyMatchFailure(
op, "requires input is tensor with dtype and sizes");
}

Value selfF64 =
convertTensorToDtype(rewriter, loc, self, rewriter.getF64Type());
rewriter.replaceOpWithNewOp<AtenPowTensorTensorOp>(op, op.getType(),
selfF64, exp);

return success();
}
};
} // namespace

namespace {
class DecomposeComplexOpsPass
: public DecomposeComplexOpsBase<DecomposeComplexOpsPass> {
Expand Down Expand Up @@ -10711,6 +10768,9 @@ class DecomposeComplexOpsPass
addPatternIfTargetOpIsIllegal<DecomposeAtenConv1dOp>(patterns);
addPatternIfTargetOpIsIllegal<DecomposeAtenConv2dOp>(patterns);
addPatternIfTargetOpIsIllegal<DecomposeAtenConv3dOp>(patterns);
addPatternIfTargetOpIsIllegal<DecomposeAtenThresholdOp>(patterns);
addPatternIfTargetOpIsIllegal<DecomposeAtenFloatPowerTensorTensorOp>(
patterns);

addPatternIfTargetOpIsIllegal<
DecomposeAtenFMaxMinOp<AtenFmaxOp, AtenMaximumOp>>(patterns);
Expand Down
9 changes: 2 additions & 7 deletions projects/pt1/e2e_testing/xfail_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -886,13 +886,6 @@
"TensorToFloatZeroRank_basic",
"TensorToFloat_basic",
"TensorToInt_basic",
"Threshold1dFloatModule_basic",
"Threshold1dIntI32Module_basic",
"Threshold1dIntModule_basic",
"Threshold2dFloatModule_basic",
"Threshold2dIntModule_basic",
"Threshold3dFloatModule_basic",
"Threshold3dIntModule_basic",
"ThresholdBackward1dFloatModule_basic",
"ThresholdBackward1dIntModule_basic",
"ThresholdBackward1dMixedModule_basic",
Expand Down Expand Up @@ -2717,6 +2710,7 @@
"ElementwiseFminModule_basic",
"ElementwiseFmaxModule_basic",
"Exp2StaticModule_basic",
"FloatPowerTensorTensorStaticModule_basic",
"MultinomialModule2D_basic",
"MultinomialModule2D_F32",
"PixelShuffleModuleStaticRank4Float32_basic",
Expand All @@ -2727,6 +2721,7 @@
"SliceStaticComplexInputModule_basic",
"StdCorrectionLargeInputModule_basic",
"TupleModule_basic",
"ThresholdStaticModule_basic",
"VarCorrectionLargeInputModule_basic",
# Failure - incorrect shape
"ArangeStartOutDtypeModule_basic",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ def emit_with_mutating_variants(key, **kwargs):
emit("aten::pow.Tensor_Scalar : (Tensor, Scalar) -> (Tensor)")
emit("aten::pow.Tensor_Tensor : (Tensor, Tensor) -> (Tensor)")
emit("aten::pow.Scalar : (Scalar, Tensor) -> (Tensor)")
emit("aten::float_power.Tensor_Tensor : (Tensor, Tensor) -> (Tensor)")
emit("aten::threshold_backward : (Tensor, Tensor, Scalar) -> (Tensor)")
emit("aten::floor_divide : (Tensor, Tensor) -> (Tensor)")
emit("aten::softplus : (Tensor, Scalar, Scalar) -> (Tensor)")
Expand Down
23 changes: 23 additions & 0 deletions projects/pt1/python/torch_mlir_e2e_test/test_suite/elementwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,29 @@ def ElementwiseWhereSelfModule_basic(module, tu: TestUtils):
# ==============================================================================


class FloatPowerTensorTensorStaticModule(torch.nn.Module):
def __init__(self):
super().__init__()

@export
@annotate_args(
[
None,
([3, 4], torch.float32, True),
]
)
def forward(self, x):
return torch.ops.aten.float_power(x, torch.tensor(2))


@register_test_case(module_factory=lambda: FloatPowerTensorTensorStaticModule())
def FloatPowerTensorTensorStaticModule_basic(module, tu: TestUtils):
module.forward(tu.rand(3, 4))


# ==============================================================================


class ElementwiseWhereScalarModule(torch.nn.Module):
def __init__(self):
super().__init__()
Expand Down

0 comments on commit dda65b1

Please sign in to comment.