diff --git a/docs/Changelog.md b/docs/Changelog.md
index 8107fbfd86c..385afb2ca94 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -25735,6 +25735,35 @@ This version of the operator has been available since version 21 of the default
Constrain output to int64 tensor.
+### **Swish-22**
+
+ Swish function, takes one input data (Tensor) and produces one output data (Tensor) of the same shape, where $Swish(x) = x * sigmoid(beta * x)$.
+
+#### Version
+
+This version of the operator has been available since version 21 of the default ONNX operator set.
+
+#### Inputs
+
+
+- X (differentiable) : T
+- Input tensor
+
+
+#### Outputs
+
+
+- Y (differentiable) : T
+- Output tensor
+
+
+#### Type Constraints
+
+
+- T : tensor(float16), tensor(float), tensor(double)
+- Constrain input and output types to float tensors.
+
+
### **Size-21**
Takes a tensor as input and outputs a int64 scalar that equals to the total number of elements of the input tensor.
diff --git a/docs/Operators.md b/docs/Operators.md
index e1601a74d89..5d5bcd49552 100644
--- a/docs/Operators.md
+++ b/docs/Operators.md
@@ -142,6 +142,7 @@ For an operator input/output's differentiability, it can be differentiable,
|Sin|22, 7|
|Sinh|22, 9|
|Size|21, 19, 13, 1|
+|Swish|22|
|Slice|13, 11, 10, 1|
|SpaceToDepth|13, 1|
|Split|18, 13, 11, 2, 1|
diff --git a/onnx/backend/test/case/node/swish.py b/onnx/backend/test/case/node/swish.py
new file mode 100644
index 00000000000..e4282b8eacd
--- /dev/null
+++ b/onnx/backend/test/case/node/swish.py
@@ -0,0 +1,28 @@
+# Copyright (c) ONNX Project Contributors
+#
+# SPDX-License-Identifier: Apache-2.0
+
+import numpy as np
+
+import onnx
+from onnx.backend.test.case.base import Base
+from onnx.backend.test.case.node import expect
+
+
+def swish(x: np.ndarray, alpha: np.float16) -> np.ndarray:
+ return x * 1 / (1 + np.exp(np.negative(x * alpha)))
+
+
+class Swish(Base):
+ @staticmethod
+ def export() -> None:
+ node = onnx.helper.make_node(
+ "Swish",
+ inputs=["x"],
+ outputs=["y"],
+ )
+
+ x = np.array([3, 4, 5]).astype(np.float32)
+ y = swish(x, alpha=1.0)
+
+ expect(node, inputs=[x], outputs=[y], name="test_swish")
diff --git a/onnx/defs/math/defs.cc b/onnx/defs/math/defs.cc
index c315a2a7b7f..a64d2c635bb 100644
--- a/onnx/defs/math/defs.cc
+++ b/onnx/defs/math/defs.cc
@@ -621,6 +621,35 @@ ONNX_OPERATOR_SET_SCHEMA(
.SetContextDependentFunctionBodyBuilder(BuildContextDependentFunctionBodyGelu)
.TypeAndShapeInferenceFunction(propagateShapeAndTypeFromFirstInput));
+static const char* Swish_ver22_doc = R"DOC(
+Swish function takes one input data (Tensor) and produces one output data (Tensor) of the same shape,
+where $Swish(x) = x * sigmoid(beta * x)$.
+)DOC";
+
+ONNX_OPERATOR_SET_SCHEMA(
+ Swish,
+ 22,
+ OpSchema()
+ .SetDoc(Swish_ver22_doc)
+ .Input(0, "X", "Input tensor", "T", OpSchema::Single, true, 1, OpSchema::Differentiable)
+ .Output(0, "Y", "Output tensor", "T", OpSchema::Single, true, 1, OpSchema::Differentiable)
+ .TypeConstraint(
+ "T",
+ {"tensor(float16)", "tensor(float)", "tensor(bfloat16)"},
+ "Constrain input and output types to float tensors.")
+ .TypeAndShapeInferenceFunction(propagateShapeAndTypeFromFirstInput)
+ .FunctionBody(
+ R"ONNX(
+ {
+ Alpha = Constant ()
+ AlphaCast = CastLike (Alpha, X)
+ AlphaMulX = Mul (AlphaCast, X)
+ SigmoidAlphaMulX = Sigmoid(AlphaMulX)
+ Y = Mul (X, SigmoidAlphaMulX)
+ }
+ )ONNX",
+ 22));
+
static const char* Exp_ver13_doc = R"DOC(
Calculates the exponential of the given input tensor, element-wise.
)DOC";
diff --git a/onnx/defs/operator_sets.h b/onnx/defs/operator_sets.h
index ad2791524e7..5574512fb16 100644
--- a/onnx/defs/operator_sets.h
+++ b/onnx/defs/operator_sets.h
@@ -1234,6 +1234,7 @@ class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Onnx, 22, RNN);
class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Onnx, 22, GRU);
class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Onnx, 22, LSTM);
class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Onnx, 22, GridSample);
+class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Onnx, 22, Swish);
// Iterate over schema from ai.onnx version 22
class OpSet_Onnx_ver22 {
@@ -1287,6 +1288,7 @@ class OpSet_Onnx_ver22 {
fn(GetOpSchema());
fn(GetOpSchema());
fn(GetOpSchema());
+ fn(GetOpSchema());
}
};
diff --git a/onnx/test/version_converter/automatic_upgrade_test.py b/onnx/test/version_converter/automatic_upgrade_test.py
index 10627b8c323..1b2e95913e8 100644
--- a/onnx/test/version_converter/automatic_upgrade_test.py
+++ b/onnx/test/version_converter/automatic_upgrade_test.py
@@ -1301,6 +1301,9 @@ def test_Sum(self) -> None:
attrs={"consumed_inputs": [0]},
)
+ def test_Swish(self) -> None:
+ self._test_op_upgrade("Swish", 22)
+
def test_Tanh(self) -> None:
self._test_op_upgrade("Tanh", 1, attrs={"consumed_inputs": [0]})