forked from mindspore-Ecosystem/mindspore
Add a cpu kernel, Softsign.
This commit is contained in:
parent
0259df3437
commit
0c74da2d3c
|
@ -67,6 +67,7 @@ constexpr auto kSqrt = "Sqrt";
|
|||
constexpr auto kRsqrt = "Rsqrt";
|
||||
constexpr auto kErf = "Erf";
|
||||
constexpr auto kErfc = "Erfc";
|
||||
constexpr auto kSoftsign = "Softsign";
|
||||
|
||||
class ArithmeticSelfCpuKernelFunc : public CpuKernelFunc {
|
||||
public:
|
||||
|
@ -187,9 +188,7 @@ void Inv(ArithmeticSelfCpuKernelFunc *content, const T *in, T *out, size_t size)
|
|||
template <typename T>
|
||||
void Invert(ArithmeticSelfCpuKernelFunc *content, const T *in, T *out, size_t size) {
|
||||
if constexpr ((std::is_same_v<T, double>) || (std::is_same_v<T, float>) || (std::is_same_v<T, float16>)) {
|
||||
MS_LOG(EXCEPTION) << "For 'Invert', the dtype of 'input_x' must be int8, int16, int32, int64, uint8, uint16, "
|
||||
"uint32 or uint64, but got "
|
||||
<< typeid(T).name();
|
||||
MS_LOG(EXCEPTION) << "'Invert' cannot be instantiated.";
|
||||
return;
|
||||
} else {
|
||||
auto task = [&in, &out](size_t start, size_t end) {
|
||||
|
@ -219,7 +218,7 @@ void Gelu(ArithmeticSelfCpuKernelFunc *content, const T *in, T *out, size_t size
|
|||
template <typename T>
|
||||
void FastGelu(ArithmeticSelfCpuKernelFunc *content, const T *in, T *out, size_t size) {
|
||||
if constexpr (!std::is_same_v<T, float16> && !std::is_same_v<T, float>) {
|
||||
MS_LOG(EXCEPTION) << "For 'FastGelu', the dtype of 'input_x' must be float16, float, but got " << typeid(T).name();
|
||||
MS_LOG(EXCEPTION) << "'FastGelu' cannot be instantiated.";
|
||||
return;
|
||||
}
|
||||
auto task = [&in, &out](size_t start, size_t end) {
|
||||
|
@ -450,8 +449,7 @@ template <typename T>
|
|||
void Abs(ArithmeticSelfCpuKernelFunc *content, const T *in, T *out, size_t size) {
|
||||
if constexpr ((std::is_same_v<T, uint8_t>) || (std::is_same_v<T, uint16_t>) || (std::is_same_v<T, uint32_t>) ||
|
||||
(std::is_same_v<T, uint64_t>)) {
|
||||
MS_LOG(EXCEPTION) << "For 'Abs', the dtype of 'input_x' must be int32, int64, float32 or float64, but got "
|
||||
<< typeid(T).name();
|
||||
MS_LOG(EXCEPTION) << "'Abs' cannot be instantiated.";
|
||||
return;
|
||||
} else {
|
||||
auto task = [&in, &out](size_t start, size_t end) {
|
||||
|
@ -483,6 +481,22 @@ void Rsqrt(ArithmeticSelfCpuKernelFunc *content, const T *in, T *out, size_t siz
|
|||
ParallelLaunchAutoSearch(task, size, content, &content->parallel_search_info_);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Softsign(ArithmeticSelfCpuKernelFunc *content, const T *in, T *out, size_t size) {
|
||||
if constexpr ((std::is_same_v<T, uint8_t>) || (std::is_same_v<T, uint16_t>) || (std::is_same_v<T, uint32_t>) ||
|
||||
(std::is_same_v<T, uint64_t>)) {
|
||||
MS_LOG(EXCEPTION) << "'Softsign' cannot be instantiated.";
|
||||
return;
|
||||
} else {
|
||||
auto task = [&in, &out](size_t start, size_t end) {
|
||||
for (size_t i = start; i < end; i++) {
|
||||
out[i] = in[i] / (1.0 + abs(in[i]));
|
||||
}
|
||||
};
|
||||
ParallelLaunchAutoSearch(task, size, content, &content->parallel_search_info_);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Identity(const T *in, T *out, size_t size) {
|
||||
(void)std::copy(in, in + size, out);
|
||||
|
@ -595,7 +609,8 @@ void ArithmeticSelfCpuKernelFunc::LaunchKernel(const std::vector<AddressPtr> &in
|
|||
{prim::kPrimRint->name(), Rint<T>}, {prim::kPrimRound->name(), Round<T>},
|
||||
{prim::kPrimAbs->name(), Abs<T>}, {prim::kPrimSqrt->name(), Sqrt<T>},
|
||||
{prim::kPrimRsqrt->name(), Rsqrt<T>}, {prim::kPrimErf->name(), Erf<T>},
|
||||
{prim::kPrimErfc->name(), Erfc<T>}};
|
||||
{prim::kPrimErfc->name(), Erfc<T>}, {prim::kPrimRsqrt->name(), Rsqrt<T>},
|
||||
{prim::kPrimSoftsign->name(), Softsign<T>}};
|
||||
|
||||
const auto func_pair = arithmeticSelfFuncMap.find(kernel_name_);
|
||||
if (arithmeticSelfFuncMap.find(kernel_name_) == arithmeticSelfFuncMap.end()) {
|
||||
|
@ -771,7 +786,10 @@ static std::map<std::string, std::vector<std::pair<KernelAttr, ArithFuncCreator>
|
|||
{KernelAttr().AddInputAttr(kNumberTypeFloat64).AddOutputAttr(kNumberTypeFloat64), CreateArithSelfFunc}}},
|
||||
{kErfc,
|
||||
{{KernelAttr().AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), CreateArithSelfFunc},
|
||||
{KernelAttr().AddInputAttr(kNumberTypeFloat64).AddOutputAttr(kNumberTypeFloat64), CreateArithSelfFunc}}}};
|
||||
{KernelAttr().AddInputAttr(kNumberTypeFloat64).AddOutputAttr(kNumberTypeFloat64), CreateArithSelfFunc}}},
|
||||
{kSoftsign,
|
||||
{{KernelAttr().AddInputAttr(kNumberTypeFloat64).AddOutputAttr(kNumberTypeFloat64), CreateArithSelfFunc},
|
||||
{KernelAttr().AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), CreateArithSelfFunc}}}};
|
||||
} // namespace
|
||||
|
||||
void ArithmeticSelfCpuKernelMod::InitKernel(const CNodePtr &kernel_node) {
|
||||
|
@ -879,6 +897,8 @@ MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, Erf,
|
|||
[]() { return std::make_shared<ArithmeticSelfCpuKernelMod>(kErf); });
|
||||
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, Erfc,
|
||||
[]() { return std::make_shared<ArithmeticSelfCpuKernelMod>(kErfc); });
|
||||
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, Softsign,
|
||||
[]() { return std::make_shared<ArithmeticSelfCpuKernelMod>(kSoftsign); });
|
||||
|
||||
MS_KERNEL_FACTORY_REG(NativeCpuKernelMod, Identity, IdentityCpuKernelMod);
|
||||
} // namespace kernel
|
||||
|
|
|
@ -447,7 +447,7 @@ class Softsign(Primitive):
|
|||
TypeError: If dtype of `input_x` is neither float16 nor float32.
|
||||
|
||||
Supported Platforms:
|
||||
``Ascend``
|
||||
``Ascend`` `CPU``
|
||||
|
||||
Examples:
|
||||
>>> input_x = Tensor(np.array([0, -1, 2, 30, -30]), mindspore.float32)
|
||||
|
|
|
@ -259,6 +259,27 @@ def test_invert(shape, dtype):
|
|||
np.testing.assert_almost_equal(output.asnumpy(), expect_output)
|
||||
|
||||
|
||||
@pytest.mark.level0
|
||||
@pytest.mark.platform_x86_cpu
|
||||
@pytest.mark.env_onecard
|
||||
@pytest.mark.parametrize('shape', [(2,), (4, 5), (3, 4, 5, 6)])
|
||||
@pytest.mark.parametrize('dtype, tol', [(np.float16, 1.0e-3), (np.float32, 1.0e-5)])
|
||||
def test_softsign(shape, dtype, tol):
|
||||
"""
|
||||
Feature: ALL To ALL
|
||||
Description: test cases for Softsign
|
||||
Expectation: the result match to numpy
|
||||
"""
|
||||
softsign = P.Softsign()
|
||||
prop = 100 if np.random.random() > 0.5 else -100
|
||||
x = np.random.randn(*shape).astype(dtype) * prop
|
||||
output = softsign(Tensor(x))
|
||||
expect_output = x / (1.0 + np.abs(x))
|
||||
diff = output.asnumpy() - expect_output
|
||||
error = np.ones(shape=expect_output.shape) * tol
|
||||
assert np.all(np.abs(diff) < error)
|
||||
|
||||
|
||||
@pytest.mark.level0
|
||||
@pytest.mark.platform_x86_cpu
|
||||
@pytest.mark.env_onecard
|
||||
|
|
Loading…
Reference in New Issue