diff --git a/docs/source/experimental.rst b/docs/source/experimental.rst
index 5a24a9306e842b96ad38551bbb949a462adb4997..ff50e8fd50d9fdb9552b4e37fdccded4494c1020 100644
--- a/docs/source/experimental.rst
+++ b/docs/source/experimental.rst
@@ -175,6 +175,8 @@ Experimental features
.. autofunction:: oneflow.experimental.nn.Upsample
.. autofunction:: oneflow.experimental.nn.UpsamplingNearest2d
.. autofunction:: oneflow.experimental.nn.UpsamplingBilinear2d
+.. autofunction:: oneflow.experimental.floor
+.. autofunction:: oneflow.experimental.Tensor.floor
.. autofunction:: oneflow.experimental.addmm
.. autofunction:: oneflow.experimental.Tensor.addmm
.. autofunction:: oneflow.experimental.clamp
diff --git a/oneflow/python/nn/modules/floor.py b/oneflow/python/nn/modules/floor.py
new file mode 100644
index 0000000000000000000000000000000000000000..9ed9433b2de58ef8981e4f15b3f1fe8bad0d3f91
--- /dev/null
+++ b/oneflow/python/nn/modules/floor.py
@@ -0,0 +1,88 @@
+"""
+Copyright 2020 The OneFlow Authors. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+import collections
+from typing import Optional, Sequence, Union
+
+import oneflow as flow
+from oneflow.python.oneflow_export import oneflow_export, experimental_api
+from oneflow.python.nn.module import Module
+from oneflow.python.framework.tensor import register_tensor_op
+from oneflow.python.nn.modules.utils import _check_axis
+
+
+class Floor(Module):
+ def __init__(self) -> None:
+ super().__init__()
+ self._op = flow.builtin_op("floor").Input("x").Output("y").Build()
+
+ def forward(self, x):
+ return self._op(x)[0]
+
+
+@oneflow_export("floor")
+@experimental_api
+def floor_op(x):
+
+ r"""
+ Returns a new tensor with the arcsine of the elements of :attr:`input`.
+
+ .. math::
+ \text{out}_{i} = \lfloor \text{input}_{i} \rfloor
+
+ Args:
+ input (Tensor): the input tensor.
+
+ For example:
+
+ .. code-block:: python
+
+ >>> import oneflow.experimental as flow
+ >>> import numpy as np
+ >>> flow.enable_eager_execution()
+ >>> input = flow.Tensor(np.array([-0.5, 1.5, 0, 0.8]), dtype=flow.float32)
+ >>> output = flow.floor(input)
+ >>> output.shape
+ flow.Size([4])
+ >>> output.numpy()
+ array([-1., 1., 0., 0.], dtype=float32)
+
+ >>> input1 = flow.Tensor(np.array([[0.8, 1.0], [-0.6, 2.5]]), dtype=flow.float32)
+ >>> output1 = input1.floor()
+ >>> output1.shape
+ flow.Size([2, 2])
+ >>> output1.numpy()
+ array([[ 0., 1.],
+ [-1., 2.]], dtype=float32)
+
+ """
+
+ return Floor()(x)
+
+
+@register_tensor_op("floor")
+@experimental_api
+def floor_op_tensor(input):
+ r"""
+ See :func:`oneflow.experimental.floor`
+ """
+ return Floor()(input)
+
+
+if __name__ == "__main__":
+ import doctest
+
+ doctest.testmod(raise_on_error=True)
diff --git a/oneflow/python/test/modules/test_floor.py b/oneflow/python/test/modules/test_floor.py
new file mode 100644
index 0000000000000000000000000000000000000000..940b372ebd0981d9b2984a2fa25afed6c65a8c10
--- /dev/null
+++ b/oneflow/python/test/modules/test_floor.py
@@ -0,0 +1,60 @@
+"""
+Copyright 2020 The OneFlow Authors. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+import unittest
+from collections import OrderedDict
+
+import numpy as np
+
+import oneflow.experimental as flow
+from test_util import GenArgList
+
+
+def _test_floor(test_case, shape, device):
+ np_input = np.random.randn(*shape)
+ of_input = flow.Tensor(
+ np_input, dtype=flow.float32, device=flow.device(device), requires_grad=True
+ )
+
+ of_out = flow.floor(of_input)
+ np_out = np.floor(np_input)
+ test_case.assertTrue(
+ np.allclose(of_out.numpy(), np_out, 1e-5, 1e-5, equal_nan=True)
+ )
+
+ of_out = of_out.sum()
+ of_out.backward()
+ np_out_grad = np.zeros_like(of_out, dtype=np.float32)
+
+ test_case.assertTrue(
+ np.allclose(of_input.grad.numpy(), np_out_grad, 1e-4, 1e-4, equal_nan=True)
+ )
+
+
+@unittest.skipIf(
+ not flow.unittest.env.eager_execution_enabled(),
+ ".numpy() doesn't work in lazy mode",
+)
+class TestFloor(flow.unittest.TestCase):
+ def test_floor(test_case):
+ arg_dict = OrderedDict()
+ arg_dict["shape"] = [(2,), (2, 3), (2, 4, 5, 6)]
+ arg_dict["device"] = ["cpu", "cuda"]
+ for arg in GenArgList(arg_dict):
+ _test_floor(test_case, *arg)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/oneflow/python/test/modules/test_math_ops.py b/oneflow/python/test/modules/test_math_ops.py
index 0f6707da045a5099cb923c0ed476faed5539c35d..e80caa5c00819eed2ab5cb0f95dbffbe854e9f84 100644
--- a/oneflow/python/test/modules/test_math_ops.py
+++ b/oneflow/python/test/modules/test_math_ops.py
@@ -635,6 +635,24 @@ def _test_topk_original(test_case, device):
)
+@unittest.skipIf(
+ not flow.unittest.env.eager_execution_enabled(),
+ ".numpy() doesn't work in lazy mode",
+)
+class TestPow(flow.unittest.TestCase):
+ def test_pow(test_case):
+ input = flow.Tensor(np.array([1, 2, 3, 4, 5, 6]), dtype=flow.float32)
+ of_out = flow.pow(input, 2.1)
+ np_out = np.power(input.numpy(), 2.1)
+ test_case.assertTrue(np.allclose(of_out.numpy(), np_out, 1e-5, 1e-5))
+
+ def test_pow_tensor_function(test_case):
+ input = flow.Tensor(np.array([1, 2, 3, 4, 5, 6]), dtype=flow.float32)
+ of_out = input.pow(2.1)
+ np_out = np.power(input.numpy(), 2.1)
+ test_case.assertTrue(np.allclose(of_out.numpy(), np_out, 1e-5, 1e-5))
+
+
@unittest.skipIf(
not flow.unittest.env.eager_execution_enabled(),
".numpy() doesn't work in lazy mode",
diff --git a/oneflow/python/test/tensor/test_tensor.py b/oneflow/python/test/tensor/test_tensor.py
index 4722a8afc8873129a68b849ae9c9824fca753f25..2629f609303617b112c64db14fd236b18b272e5a 100644
--- a/oneflow/python/test/tensor/test_tensor.py
+++ b/oneflow/python/test/tensor/test_tensor.py
@@ -636,6 +636,18 @@ class TestTensor(flow.unittest.TestCase):
test_case.assertEqual(tensor.dtype, flow.float32)
test_case.assertTrue(np.allclose(tensor.numpy(), np.array(scalar), 1e-4, 1e-4))
+ @unittest.skipIf(
+ not flow.unittest.env.eager_execution_enabled(),
+ "numpy doesn't work in lazy mode",
+ )
+ def test_floor(test_case):
+ input = flow.Tensor(np.random.randn(4, 5, 6), dtype=flow.float32)
+ of_out = input.floor()
+ np_out = np.floor(input.numpy())
+ test_case.assertTrue(
+ np.allclose(of_out.numpy(), np_out, 1e-5, 1e-5, equal_nan=True)
+ )
+
@unittest.skipIf(
not flow.unittest.env.eager_execution_enabled(),
"numpy doesn't work in lazy mode",