[Torch] support float_power and threshold ops (#3854)

byteir
yyp0 2024-11-07 16:27:51 +08:00 committed by Yuanqiang Liu
parent c71728b182
commit 6413e4a687
5 changed files with 110 additions and 8 deletions

View File

@ -5187,6 +5187,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,

View File

@ -9916,6 +9916,63 @@ public:
};
} // 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> {
@ -10181,6 +10238,9 @@ public:
addPatternIfTargetOpIsIllegal<DecomposeAtenConv1dOp>(patterns);
addPatternIfTargetOpIsIllegal<DecomposeAtenConv2dOp>(patterns);
addPatternIfTargetOpIsIllegal<DecomposeAtenConv3dOp>(patterns);
addPatternIfTargetOpIsIllegal<DecomposeAtenThresholdOp>(patterns);
addPatternIfTargetOpIsIllegal<DecomposeAtenFloatPowerTensorTensorOp>(
patterns);
addPatternIfTargetOpIsIllegal<
DecomposeAtenFMaxMinOp<AtenFmaxOp, AtenMaximumOp>>(patterns);

View File

@ -854,14 +854,6 @@ FX_IMPORTER_STABLEHLO_XFAIL_SET = {
"TensorToFloatZeroRank_basic",
"TensorToFloat_basic",
"TensorToInt_basic",
"TestMultipleTensorAndPrimitiveTypesReturn_basic",
"Threshold1dFloatModule_basic",
"Threshold1dIntI32Module_basic",
"Threshold1dIntModule_basic",
"Threshold2dFloatModule_basic",
"Threshold2dIntModule_basic",
"Threshold3dFloatModule_basic",
"Threshold3dIntModule_basic",
"ThresholdBackward1dFloatModule_basic",
"ThresholdBackward1dIntModule_basic",
"ThresholdBackward1dMixedModule_basic",
@ -2367,6 +2359,7 @@ ONNX_XFAIL_SET = {
"ElementwiseFminModule_basic",
"ElementwiseFmaxModule_basic",
"Exp2StaticModule_basic",
"FloatPowerTensorTensorStaticModule_basic",
"MultinomialModule2D_basic",
"MultinomialModule2D_F32",
"PixelShuffleModuleStaticRank4Float32_basic",
@ -2390,6 +2383,7 @@ ONNX_XFAIL_SET = {
"SliceCopy_Module_basic",
"StdCorrectionLargeInputModule_basic",
"TupleModule_basic",
"ThresholdStaticModule_basic",
"VarCorrectionLargeInputModule_basic",
# Failure - incorrect shape
"ArangeStartOutDtypeModule_basic",

View File

@ -498,6 +498,7 @@ def emit_ops(emitter_td: TextEmitter, registry: Registry):
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)")

View File

@ -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__()