Files
2026-07-13 12:40:42 +08:00

983 lines
32 KiB
Python

# Copyright (c) 2018 PaddlePaddle 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
import numpy as np
from op_test import (
OpTest,
check_cudnn_version_and_compute_capability,
convert_float_to_uint16,
get_device_place,
get_places,
is_custom_device,
)
from utils import dygraph_guard, static_guard
import paddle
import paddle.nn.functional as F
from paddle import base, compat
from paddle.base import core
np.random.seed(10)
def stable_softmax(x):
"""Compute the softmax of vector x in a numerically stable way."""
# clip to shiftx, otherwise, when calc loss with
# log(exp(shiftx)), may get log(0)=INF
shiftx = (x - np.max(x)).clip(-64.0)
exps = np.exp(shiftx)
return exps / np.sum(exps)
def ref_softmax(x, axis=None, dtype=None):
x_t = x.copy()
if dtype is not None:
x_t = x_t.astype(dtype)
if axis is None:
axis = -1
return np.apply_along_axis(stable_softmax, axis, x_t)
class TestSoftmaxOp(OpTest):
def get_x_shape(self):
return [10, 10]
def get_axis(self):
return -1
def setUp(self):
self.op_type = "softmax"
self.prim_op_type = "comp"
self.python_api = F.softmax
self.public_python_api = F.softmax
self.use_cudnn = False
self.use_onednn = False
# explicitly use float32 for ROCm, as MIOpen does not yet support float64
self.dtype = np.float32 if core.is_compiled_with_rocm() else np.float64
self.init_kernel_type()
self.shape = self.get_x_shape()
self.axis = self.get_axis()
np.random.seed(0)
x = np.random.uniform(0.1, 1, self.shape).astype(self.dtype)
out = np.apply_along_axis(stable_softmax, self.axis, x)
self.inputs = {'X': OpTest.np_dtype_to_base_dtype(x)}
self.outputs = {'Out': out}
self.attrs = {
'axis': self.axis,
'use_cudnn': self.use_cudnn,
'use_onednn': self.use_onednn,
}
self.enable_cinn = True
def init_kernel_type(self):
pass
def test_check_output(self):
# TODO(wangzhongpu): support onednn op in dygraph mode
if self.use_cudnn:
place = get_device_place()
self.check_output_with_place(
place,
atol=1e-5,
check_prim=False,
check_pir=True,
check_prim_pir=True,
check_pir_onednn=self.check_pir_onednn,
check_symbol_infer=False,
)
else:
self.check_output(
check_prim=False,
check_pir=True,
check_prim_pir=True,
check_pir_onednn=self.check_pir_onednn,
check_symbol_infer=False,
)
def test_check_grad(self):
# TODO(wangzhongpu): support onednn op in dygraph mode
if self.use_cudnn or self.dtype == np.float16:
place = get_device_place()
if core.is_float16_supported(place):
self.check_grad_with_place(
place,
["X"],
"Out",
max_relative_error=0.01,
check_dygraph=(not self.use_onednn),
check_pir=True,
check_prim_pir=True,
check_pir_onednn=self.check_pir_onednn,
)
else:
self.check_grad(
["X"],
"Out",
max_relative_error=0.01,
check_dygraph=(not self.use_onednn),
check_prim=False,
check_pir=True,
check_prim_pir=True,
check_pir_onednn=self.check_pir_onednn,
)
class TestSoftmaxOpfp32(TestSoftmaxOp):
def init_kernel_type(self):
self.dtype = np.float32
class TestSoftmaxOp_ZeroDim1(TestSoftmaxOp):
def setUp(self):
self.op_type = "softmax"
self.prim_op_type = "comp"
self.python_api = F.softmax
self.public_python_api = F.softmax
self.use_cudnn = False
self.use_onednn = False
# explicitly use float32 for ROCm, as MIOpen does not yet support float64
self.dtype = np.float32 if core.is_compiled_with_rocm() else np.float64
self.init_kernel_type()
np.random.seed(0)
x = np.random.uniform(0.1, 1, []).astype(self.dtype)
out = np.array(1.0).astype(self.dtype)
self.inputs = {'X': OpTest.np_dtype_to_base_dtype(x)}
self.outputs = {'Out': out}
self.attrs = {
'axis': -1,
'use_cudnn': self.use_cudnn,
'use_onednn': self.use_onednn,
}
self.enable_cinn = False
def test_check_output(self):
# TODO(wangzhongpu): support onednn op in dygraph mode
if self.use_cudnn:
place = get_device_place()
self.check_output_with_place(
place,
atol=1e-5,
check_pir=True,
check_prim_pir=True,
check_pir_onednn=self.check_pir_onednn,
check_symbol_infer=False,
)
else:
self.check_output(
check_prim=False,
check_pir=True,
check_prim_pir=True,
check_pir_onednn=self.check_pir_onednn,
check_symbol_infer=False,
)
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxOp_ZeroDim2(TestSoftmaxOp):
def setUp(self):
self.op_type = "softmax"
self.python_api = F.softmax
self.public_python_api = F.softmax
self.prim_op_type = "comp"
self.use_cudnn = True
self.use_onednn = False
# explicitly use float32 for ROCm, as MIOpen does not yet support float64
self.dtype = np.float32 if core.is_compiled_with_rocm() else np.float64
np.random.seed(0)
x = np.random.uniform(0.1, 1, []).astype(self.dtype)
out = np.array(1.0).astype(self.dtype)
self.inputs = {'X': OpTest.np_dtype_to_base_dtype(x)}
self.outputs = {'Out': out}
self.attrs = {
'axis': -1,
'use_cudnn': self.use_cudnn,
'use_onednn': self.use_onednn,
}
self.enable_cinn = False
def test_check_output(self):
# TODO(wangzhongpu): support onednn op in dygraph mode
if self.use_cudnn:
place = get_device_place()
self.check_output_with_place(
place,
check_prim=False,
atol=1e-5,
check_pir=True,
check_prim_pir=True,
check_pir_onednn=self.check_pir_onednn,
check_symbol_infer=False,
)
else:
self.check_output(
check_prim=False,
check_pir=True,
check_prim_pir=True,
check_pir_onednn=self.check_pir_onednn,
check_symbol_infer=False,
)
class TestSoftmaxOp2(TestSoftmaxOp):
def get_x_shape(self):
return [2, 3, 4, 5]
class TestSoftmaxOp3(TestSoftmaxOp):
def get_x_shape(self):
return [2, 3, 4, 5]
def get_axis(self):
return 0
class TestSoftmaxOp4(TestSoftmaxOp):
def get_x_shape(self):
return [2, 3, 4, 5]
def get_axis(self):
return 1
class TestSoftmaxOp5(TestSoftmaxOp):
def get_x_shape(self):
return [2, 3, 4, 5]
def get_axis(self):
return 2
class TestSoftmaxOp6(TestSoftmaxOp):
def get_x_shape(self):
return [2, 3, 4, 5]
def get_axis(self):
return 3
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp(TestSoftmaxOp):
def init_kernel_type(self):
self.use_cudnn = True
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp2(TestSoftmaxCUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5]
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp3(TestSoftmaxCUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5]
def get_axis(self):
return 0
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp4(TestSoftmaxCUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5]
def get_axis(self):
return 1
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp5(TestSoftmaxCUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5]
def get_axis(self):
return 2
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp6(TestSoftmaxCUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5]
def get_axis(self):
return 3
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp7(TestSoftmaxCUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5, 6]
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp8(TestSoftmaxCUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5, 6]
def get_axis(self):
return 0
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp9(TestSoftmaxCUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5, 6]
def get_axis(self):
return 1
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp10(TestSoftmaxCUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5, 6]
def get_axis(self):
return 2
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp11(TestSoftmaxCUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5, 6]
def get_axis(self):
return 3
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxCUDNNOp12(TestSoftmaxCUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5, 6]
def get_axis(self):
return 4
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxFP16Op(TestSoftmaxOp):
def init_kernel_type(self):
self.dtype = np.float16
def test_check_output(self):
if core.is_compiled_with_cuda() or is_custom_device():
place = get_device_place()
if core.is_float16_supported(place):
self.check_output_with_place(
place,
atol=1e-3,
check_prim=False,
check_pir=True,
check_prim_pir=True,
check_pir_onednn=self.check_pir_onednn,
)
# FIXME: If the x_shape is [10, 10], gradient failed.
def test_check_grad(self):
pass
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxFP16Op2(TestSoftmaxFP16Op):
def get_x_shape(self):
return [2, 3, 4, 10]
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxFP16CUDNNOp(TestSoftmaxOp):
def init_kernel_type(self):
self.use_cudnn = True
self.dtype = np.float16
def test_check_output(self):
if core.is_compiled_with_cuda() or is_custom_device():
place = get_device_place()
if core.is_float16_supported(place):
self.check_output_with_place(
place,
atol=1e-3,
check_prim=False,
check_pir=True,
check_prim_pir=True,
check_pir_onednn=self.check_pir_onednn,
)
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device()),
"core is not compiled with CUDA",
)
class TestSoftmaxFP16CUDNNOp2(TestSoftmaxFP16CUDNNOp):
def get_x_shape(self):
return [2, 3, 4, 5]
@unittest.skipIf(
not (core.is_compiled_with_cuda() or is_custom_device())
or core.is_compiled_with_rocm(),
"core is not compiled with CUDA",
)
class TestSoftmaxBF16Op(OpTest):
def setUp(self):
self.op_type = "softmax"
self.prim_op_type = "comp"
self.python_api = F.softmax
self.public_python_api = F.softmax
self.use_cudnn = self.init_cudnn()
self.use_onednn = False
self.dtype = np.uint16
self.shape = [10, 10]
self.axis = -1
np.random.seed(0)
x = np.random.uniform(0.1, 1, self.shape).astype(np.float32)
out = np.apply_along_axis(stable_softmax, self.axis, x)
self.inputs = {
'X': OpTest.np_dtype_to_base_dtype(convert_float_to_uint16(x))
}
self.outputs = {'Out': convert_float_to_uint16(out)}
self.attrs = {
'axis': self.axis,
'use_cudnn': self.use_cudnn,
'use_onednn': self.use_onednn,
}
def init_cudnn(self):
return False
def test_check_output(self):
place = get_device_place()
self.check_output_with_place(
place,
check_dygraph=(not self.use_onednn),
check_prim=False,
check_pir=(not self.use_onednn),
check_prim_pir=(not self.use_onednn),
check_pir_onednn=self.check_pir_onednn,
check_symbol_infer=False,
)
def test_check_grad(self):
place = get_device_place()
self.check_grad_with_place(
place,
["X"],
"Out",
numeric_grad_delta=0.05,
check_dygraph=(not self.use_onednn),
check_prim=False,
check_pir=(not self.use_onednn),
check_prim_pir=(not self.use_onednn),
check_pir_onednn=self.check_pir_onednn,
)
@unittest.skipIf(
not check_cudnn_version_and_compute_capability(8100, 8),
"only support compiled with CUDA or custom device, and for CUDA cudnn version need larger than 8.1.0 and device's compute capability is at least 8.0",
)
class TestSoftmaxBF16CUDNNOp(TestSoftmaxBF16Op):
def init_cudnn(self):
return True
class TestSoftmaxAPI(unittest.TestCase):
def setUp(self):
self.place = get_device_place()
self.x_np = np.random.uniform(-1.0, 1.0, [2, 3, 4, 5]).astype('float32')
self.out_ref = np.apply_along_axis(stable_softmax, -1, self.x_np)
self.executed_api()
def executed_api(self):
self.softmax = F.softmax
def test_static_check(self):
with static_guard():
with paddle.static.program_guard(paddle.static.Program()):
x = paddle.static.data('X', self.x_np.shape, 'float32')
out1 = self.softmax(x)
m = paddle.nn.Softmax()
out2 = m(x)
exe = paddle.static.Executor(self.place)
res = exe.run(feed={'X': self.x_np}, fetch_list=[out1, out2])
out_ref = ref_softmax(self.x_np, axis=-1, dtype=None)
for r in res:
np.testing.assert_allclose(out_ref, r, rtol=1e-05)
def test_dygraph_check(self):
paddle.disable_static(self.place)
x = paddle.to_tensor(self.x_np)
out1 = self.softmax(x)
x = paddle.to_tensor(self.x_np)
m = paddle.nn.Softmax()
out2 = m(x)
out_ref = ref_softmax(self.x_np, axis=-1, dtype=None)
for r in [out1, out2]:
np.testing.assert_allclose(out_ref, r.numpy(), rtol=1e-05)
out1 = self.softmax(x, axis=0)
x = paddle.to_tensor(self.x_np)
m = paddle.nn.Softmax(axis=0)
out2 = m(x)
out_ref = ref_softmax(self.x_np, axis=0, dtype=None)
for r in [out1, out2]:
np.testing.assert_allclose(out_ref, r.numpy(), rtol=1e-05)
# explicitly use float32 for ROCm, as MIOpen does not yet support float64
if core.is_compiled_with_rocm():
out = self.softmax(x, dtype=np.float32)
out_ref = ref_softmax(self.x_np, axis=-1, dtype=np.float32)
else:
out = self.softmax(x, dtype=np.float64)
out_ref = ref_softmax(self.x_np, axis=-1, dtype=np.float64)
np.testing.assert_allclose(out_ref, out.numpy(), rtol=1e-05)
paddle.enable_static()
def test_error(self):
with (
static_guard(),
paddle.static.program_guard(paddle.static.Program()),
):
# The input type must be Variable.
self.assertRaises(TypeError, self.softmax, 1)
# The input dtype must be float16, float32, float64.
x_int32 = paddle.static.data(
name='x_int32', shape=[2, 3], dtype='int32'
)
self.assertRaises(TypeError, self.softmax, x_int32)
if core.is_compiled_with_cuda() or is_custom_device():
x_fp16 = paddle.static.data(
name='x_fp16', shape=[2, 3], dtype='float16'
)
self.softmax(x_fp16)
class TestSoftmaxAPI_ZeroDim(unittest.TestCase):
def test_dygraph(self):
paddle.disable_static()
x = paddle.rand([])
x.stop_gradient = False
x.retain_grads()
out = paddle.nn.functional.softmax(x)
out.retain_grads()
out.backward()
self.assertEqual(x.shape, [])
self.assertEqual(x.grad.shape, [])
self.assertEqual(out.shape, [])
self.assertEqual(out.grad.shape, [])
paddle.enable_static()
def test_static(self):
with static_guard():
main_prog = base.Program()
with base.program_guard(main_prog, base.Program()):
x = paddle.rand([])
x.stop_gradient = False
out = paddle.nn.functional.softmax(x)
# Test compile shape
self.assertEqual(tuple(x.shape), ())
self.assertEqual(tuple(out.shape), ())
exe = base.Executor()
result = exe.run(main_prog, fetch_list=[x, out])
# Test runtime shape
self.assertEqual(tuple(result[0].shape), ())
self.assertEqual(tuple(result[1].shape), ())
class TestSoftmaxInplaceAPI(TestSoftmaxAPI):
def executed_api(self):
self.softmax = F.softmax_
class TestSoftmaxAPI_ZeroSize(unittest.TestCase):
def test_dygraph(self):
for place in get_places():
paddle.disable_static(place)
x = paddle.rand([0, 2, 3])
x.stop_gradient = False
x.retain_grads()
out = paddle.nn.functional.softmax(x)
out.retain_grads()
out.backward()
np.testing.assert_allclose(out.numpy(), np.random.random([0, 2, 3]))
np.testing.assert_allclose(x.grad.shape, x.shape)
paddle.enable_static()
class TestSoftmaxCompatibility(unittest.TestCase):
def setUp(self):
self.input = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]
self.axes = [0, 1]
self.places = [paddle.CPUPlace()]
if paddle.base.core.is_compiled_with_cuda() or is_custom_device():
self.places.append(get_device_place())
def test_gather_with_param_aliases(self):
with dygraph_guard():
for place in self.places:
paddle.device.set_device(place)
for axis in self.axes:
input_tensor = paddle.to_tensor(self.input, dtype='float32')
for param_x in ['x', 'input']:
for param_axis in ['axis', 'dim']:
kwargs = {param_x: input_tensor, param_axis: axis}
result = paddle.nn.functional.softmax(**kwargs)
expected = np.exp(
input_tensor.numpy()
- np.max(
input_tensor.numpy(),
axis=axis,
keepdims=True,
)
)
expected = expected / np.sum(
expected, axis=axis, keepdims=True
)
np.testing.assert_allclose(
(
result.numpy()
if place.is_cpu_place()
else result.cpu().numpy()
),
expected,
rtol=1e-5,
err_msg=f"Failed at axis={axis}, param_x={param_x}, param_axis={param_axis}",
)
class TestSoftmaxAPI_CompatibleWithTorch1(TestSoftmaxAPI):
# paddle.nn.functional.softmax(x, axis=-1, dtype=None, name=None)
def setUp(self):
self.place = get_device_place()
self.executed_api()
self.x_np_list = [
np.random.uniform(-1.0, 1.0, list(range(2, ndim + 2))).astype(
'float32'
)
for ndim in range(1, 6)
]
self.out_ref_list = [
ref_softmax(x_np, axis=-1, dtype=None) for x_np in self.x_np_list
]
def test_static_check(self):
with static_guard():
for x_np, out_ref in zip(self.x_np_list, self.out_ref_list):
func = F.softmax
with paddle.static.program_guard(paddle.static.Program()):
x = paddle.static.data('X', x_np.shape, 'float32')
out1 = func(x=x, axis=-1)
out2 = func(x)
exe = paddle.static.Executor(self.place)
res = exe.run(feed={'X': x_np}, fetch_list=[out1, out2])
for rr in res:
np.testing.assert_allclose(out_ref, rr, rtol=1e-05)
def test_dygraph_check(self):
paddle.disable_static(self.place)
for x_np, out_ref in zip(self.x_np_list, self.out_ref_list):
func = F.softmax
x = paddle.to_tensor(x_np)
out1 = func(x=x, axis=-1)
x = paddle.to_tensor(x_np)
out2 = func(x)
for r in [out1, out2]:
np.testing.assert_allclose(out_ref, r.numpy(), rtol=1e-05)
# explicitly use float32 for ROCm, as MIOpen does not yet support float64
if core.is_compiled_with_rocm():
out = func(x, dtype=np.float32)
out_ref = ref_softmax(x_np, axis=-1, dtype=np.float32)
else:
out = func(x, dtype=np.float64)
out_ref = ref_softmax(x_np, axis=-1, dtype=np.float64)
np.testing.assert_allclose(out_ref, out.numpy(), rtol=1e-05)
paddle.enable_static()
class TestSoftmaxAPI_CompatibleWithTorch2(TestSoftmaxAPI):
# paddle.softmax(Tensor input, int dim, dtype = None, *, Tensor out = None)
# paddle.Tensor.softmax(dim, dtype = None)
# paddle.special.softmax(input, dim, *, dtype=None)
# torch.nn.functional.softmax(input, dim=None, _stacklevel=3, dtype=None)
# torch.softmax(Tensor input, int dim, dtype = None, *, Tensor out = None)
# torch.Tensor.softmax(int dim, dtype = None)
# torch.special.softmax(input, dim, *, dtype=None)
def _get_softmax_dim(self, ndim: int) -> int:
if ndim == 0 or ndim == 1 or ndim == 3:
ret = 0
else:
ret = 1
return ret
def setUp(self):
self.place = get_device_place()
self.executed_api()
self.x_np_list = [
np.random.uniform(-1.0, 1.0, list(range(2, ndim + 2))).astype(
'float32'
)
for ndim in range(1, 6)
]
self.out_ref_list = [
ref_softmax(x_np, axis=self._get_softmax_dim(x_np.ndim), dtype=None)
for x_np in self.x_np_list
]
def test_static_check(self):
with static_guard():
for x_np, out_ref in zip(self.x_np_list, self.out_ref_list):
func = compat.nn.functional.softmax
with paddle.static.program_guard(paddle.static.Program()):
x = paddle.static.data('X', x_np.shape, 'float32')
out1 = func(input=x, dim=None, _stacklevel=3)
out2 = func(x, None, 3)
exe = paddle.static.Executor(self.place)
res = exe.run(feed={'X': x_np}, fetch_list=[out1, out2])
for rr in res:
np.testing.assert_allclose(out_ref, rr, rtol=1e-05)
func = paddle.softmax
with paddle.static.program_guard(paddle.static.Program()):
x = paddle.static.data('X', x_np.shape, 'float32')
# pir can not support out
out1 = func(input=x, dim=None, out=None)
out2 = func(x, out=None)
exe = paddle.static.Executor(self.place)
res = exe.run(
feed={'X': x_np},
fetch_list=[out1, out2],
)
for rr in res:
np.testing.assert_allclose(out_ref, rr, rtol=1e-05)
func = paddle.special.softmax
with paddle.static.program_guard(paddle.static.Program()):
x = paddle.static.data('X', x_np.shape, 'float32')
out1 = func(input=x, dim=None)
out2 = func(x)
exe = paddle.static.Executor(self.place)
res = exe.run(
feed={'X': x_np},
fetch_list=[out1, out2],
)
for rr in res:
np.testing.assert_allclose(out_ref, rr, rtol=1e-05)
func = paddle.Tensor.softmax
with paddle.static.program_guard(paddle.static.Program()):
x = paddle.static.data('X', x_np.shape, 'float32')
out1 = func(input=x, dim=None)
out2 = func(x)
exe = paddle.static.Executor(self.place)
res = exe.run(feed={'X': x_np}, fetch_list=[out1, out2])
for rr in res:
np.testing.assert_allclose(out_ref, rr, rtol=1e-05)
def test_dygraph_check(self):
paddle.disable_static(self.place)
for x_np, out_ref in zip(self.x_np_list, self.out_ref_list):
func = compat.nn.functional.softmax
x = paddle.to_tensor(x_np)
out1 = func(input=x, dim=None, _stacklevel=3)
x = paddle.to_tensor(x_np)
out2 = func(x, None, 3)
for r in [out1, out2]:
np.testing.assert_allclose(out_ref, r.numpy(), rtol=1e-05)
# explicitly use float32 for ROCm, as MIOpen does not yet support float64
if core.is_compiled_with_rocm():
out = func(x, dtype=np.float32)
out_ref = ref_softmax(
x_np,
axis=self._get_softmax_dim(x_np.ndim),
dtype=np.float32,
)
else:
out = func(x, dtype=np.float64)
out_ref = ref_softmax(
x_np,
axis=self._get_softmax_dim(x_np.ndim),
dtype=np.float64,
)
np.testing.assert_allclose(out_ref, out.numpy(), rtol=1e-05)
func = paddle.softmax
x = paddle.to_tensor(x_np)
result1 = paddle.zeros(shape=x_np.shape, dtype='float32')
out1 = func(input=x, dim=None, out=result1)
x = paddle.to_tensor(x_np)
result2 = paddle.zeros(shape=x_np.shape, dtype='float32')
out2 = func(x, out=result2)
for r in [out1, out2, result1, result2]:
np.testing.assert_allclose(out_ref, r.numpy(), rtol=1e-05)
# explicitly use float32 for ROCm, as MIOpen does not yet support float64
if core.is_compiled_with_rocm():
out = func(x, dtype=np.float32)
out_ref = ref_softmax(
x_np,
axis=self._get_softmax_dim(x_np.ndim),
dtype=np.float32,
)
else:
out = func(x, dtype=np.float64)
out_ref = ref_softmax(
x_np,
axis=self._get_softmax_dim(x_np.ndim),
dtype=np.float64,
)
np.testing.assert_allclose(out_ref, out.numpy(), rtol=1e-05)
func = paddle.special.softmax
x = paddle.to_tensor(x_np)
out1 = func(input=x, dim=None)
x = paddle.to_tensor(x_np)
out2 = func(x)
for r in [out1, out2]:
np.testing.assert_allclose(out_ref, r.numpy(), rtol=1e-05)
# explicitly use float32 for ROCm, as MIOpen does not yet support float64
if core.is_compiled_with_rocm():
out = func(x, dtype=np.float32)
out_ref = ref_softmax(
x_np,
axis=self._get_softmax_dim(x_np.ndim),
dtype=np.float32,
)
else:
out = func(x, dtype=np.float64)
out_ref = ref_softmax(
x_np,
axis=self._get_softmax_dim(x_np.ndim),
dtype=np.float64,
)
np.testing.assert_allclose(out_ref, out.numpy(), rtol=1e-05)
func = paddle.Tensor.softmax
x = paddle.to_tensor(x_np)
out1 = func(input=x, dim=None)
x = paddle.to_tensor(x_np)
out2 = func(x)
for r in [out1, out2]:
np.testing.assert_allclose(out_ref, r.numpy(), rtol=1e-05)
# explicitly use float32 for ROCm, as MIOpen does not yet support float64
if core.is_compiled_with_rocm():
out = func(x, dtype=np.float32)
out_ref = ref_softmax(
x_np,
axis=self._get_softmax_dim(x_np.ndim),
dtype=np.float32,
)
else:
out = func(x, dtype=np.float64)
out_ref = ref_softmax(
x_np,
axis=self._get_softmax_dim(x_np.ndim),
dtype=np.float64,
)
np.testing.assert_allclose(out_ref, out.numpy(), rtol=1e-05)
paddle.enable_static()
def test_forbid_keywords(self):
with (
static_guard(),
paddle.static.program_guard(paddle.static.Program()),
):
x = paddle.static.data('X', [2, 3], 'float32')
self.assertRaises(
TypeError, compat.nn.functional.softmax, x=x, axis=-1
)
self.assertRaises(
TypeError, compat.nn.functional.softmax, x=x, dim=-1
)
self.assertRaises(
TypeError, compat.nn.functional.softmax, input=x, axis=-1
)
if core.is_compiled_with_cuda() or is_custom_device():
compat.nn.functional.softmax(input=x, dim=-1)
if __name__ == "__main__":
unittest.main()