Add a cpu kernel, Inv.

This commit is contained in:
liqiliang 2022-04-09 18:31:39 +08:00
parent e78bd0926b
commit c84e885c58
4 changed files with 55 additions and 36 deletions

View File

@ -46,6 +46,7 @@ constexpr auto kFloor = "Floor";
constexpr auto kRint = "Rint";
constexpr auto kRound = "Round";
constexpr auto kReciprocal = "Reciprocal";
constexpr auto kInv = "Inv";
constexpr auto kGeLU = "GeLU";
constexpr auto kLogicalNot = "LogicalNot";
constexpr auto kAsin = "Asin";
@ -171,6 +172,11 @@ void Reciprocal(ArithmeticSelfCpuKernelFunc *content, const T *in, T *out, size_
ParallelLaunchAutoSearch(task, size, content, &content->parallel_search_info_);
}
template <typename T>
void Inv(ArithmeticSelfCpuKernelFunc *content, const T *in, T *out, size_t size) {
Reciprocal<T>(content, in, out, size);
}
template <typename T>
void Gelu(ArithmeticSelfCpuKernelFunc *content, const T *in, T *out, size_t size) {
auto task = [&in, &out](size_t start, size_t end) {
@ -483,6 +489,7 @@ void ArithmeticSelfCpuKernelFunc::LaunchKernel(const std::vector<AddressPtr> &in
{prim::kPrimCosh->name(), Cosh<T>},
{prim::kPrimAsinh->name(), Asinh<T>},
{prim::kPrimReciprocal->name(), Reciprocal<T>},
{prim::kPrimInv->name(), Inv<T>},
{prim::kPrimRint->name(), Rint<T>},
{prim::kPrimRound->name(), Round<T>},
{prim::kPrimAbs->name(), Abs<T>},
@ -575,7 +582,12 @@ static std::map<std::string, std::vector<std::pair<KernelAttr, ArithFuncCreator>
{KernelAttr().AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), CreateArithSelfFunc},
{KernelAttr().AddInputAttr(kNumberTypeFloat64).AddOutputAttr(kNumberTypeFloat64), CreateArithSelfFunc}}},
{kReciprocal,
{{KernelAttr().AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), CreateArithSelfFunc},
{{KernelAttr().AddInputAttr(kNumberTypeInt32).AddOutputAttr(kNumberTypeInt32), CreateArithSelfFunc},
{KernelAttr().AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), CreateArithSelfFunc},
{KernelAttr().AddInputAttr(kNumberTypeFloat64).AddOutputAttr(kNumberTypeFloat64), CreateArithSelfFunc}}},
{kInv,
{{KernelAttr().AddInputAttr(kNumberTypeInt32).AddOutputAttr(kNumberTypeInt32), CreateArithSelfFunc},
{KernelAttr().AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), CreateArithSelfFunc},
{KernelAttr().AddInputAttr(kNumberTypeFloat64).AddOutputAttr(kNumberTypeFloat64), CreateArithSelfFunc}}},
{kGeLU, {{KernelAttr().AddInputAttr(kNumberTypeFloat32).AddOutputAttr(kNumberTypeFloat32), CreateArithSelfFunc}}},
{kLogicalNot, {{KernelAttr().AddInputAttr(kNumberTypeBool).AddOutputAttr(kNumberTypeBool), CreateArithSelfFunc}}},
@ -700,6 +712,8 @@ MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, Round,
[]() { return std::make_shared<ArithmeticSelfCpuKernelMod>(kRound); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, Reciprocal,
[]() { return std::make_shared<ArithmeticSelfCpuKernelMod>(kReciprocal); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, Inv,
[]() { return std::make_shared<ArithmeticSelfCpuKernelMod>(kInv); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, GeLU,
[]() { return std::make_shared<ArithmeticSelfCpuKernelMod>(kGeLU); });
MS_KERNEL_FACTORY_REG_BY_CREATOR(NativeCpuKernelMod, LogicalNot,

View File

@ -64,6 +64,7 @@ constexpr auto kACos = "ACos";
constexpr auto kACosGrad = "ACosGrad";
constexpr auto kRealDiv = "RealDiv";
constexpr auto kReciprocal = "Reciprocal";
constexpr auto kInv = "Inv";
constexpr auto kLog = "Log";
constexpr auto kLogicalXor = "LogicalXor";
constexpr auto kSelect = "Select";
@ -703,6 +704,7 @@ GVAR_DEF(PrimitivePtr, kPrimTruncateMod, std::make_shared<Primitive>("TruncateMo
GVAR_DEF(PrimitivePtr, kPrimSqrtGrad, std::make_shared<Primitive>("SqrtGrad"));
GVAR_DEF(PrimitivePtr, kPrimReciprocal, std::make_shared<Primitive>(kReciprocal));
GVAR_DEF(PrimitivePtr, kPrimReciprocalGrad, std::make_shared<Primitive>("ReciprocalGrad"));
GVAR_DEF(PrimitivePtr, kPrimInv, std::make_shared<Primitive>(kInv));
GVAR_DEF(PrimitivePtr, kPrimExpandDims, std::make_shared<Primitive>("ExpandDims"));
GVAR_DEF(PrimitivePtr, kPrimAbs, std::make_shared<Primitive>(kAbs));
GVAR_DEF(PrimitivePtr, kPrimAbsGrad, std::make_shared<Primitive>("AbsGrad"));
@ -742,7 +744,6 @@ GVAR_DEF(PrimitivePtr, kPrimSquareSumAll, std::make_shared<Primitive>("SquareSum
GVAR_DEF(PrimitivePtr, kPrimComplex, std::make_shared<Primitive>("Complex"));
GVAR_DEF(PrimitivePtr, kPrimXdivy, std::make_shared<Primitive>("Xdivy"));
GVAR_DEF(PrimitivePtr, kPrimXlogy, std::make_shared<Primitive>("Xlogy"));
GVAR_DEF(PrimitivePtr, kPrimInv, std::make_shared<Primitive>("Inv"));
GVAR_DEF(PrimitivePtr, kPrimBitwiseOr, std::make_shared<Primitive>("BitwiseOr"));
GVAR_DEF(PrimitivePtr, kPrimBitwiseAnd, std::make_shared<Primitive>("BitwiseAnd"));
GVAR_DEF(PrimitivePtr, kPrimBitwiseXor, std::make_shared<Primitive>("BitwiseXor"));

View File

@ -188,9 +188,7 @@ class Add(_MathBinaryOp):
out_{i} = x_{i} + y_{i}
.. note::
- Inputs of `x` and `y` comply with the
`implicit type conversion rules <https://www.mindspore.cn/docs/note/en/master/operator_list_implicit.html>`_
to make the data types consistent.
- Inputs of `x` and `y` comply with the implicit type conversion rules to make the data types consistent.
- The inputs must be two tensors or one tensor and one scalar.
- When the inputs are two tensors,
dtypes of them cannot be bool at the same time, and the shapes of them can be broadcast.
@ -1895,9 +1893,7 @@ class Sub(_MathBinaryOp):
out_{i} = x_{i} - y_{i}
.. note::
- Inputs of `x` and `y` comply with the
`implicit type conversion rules <https://www.mindspore.cn/docs/note/en/master/operator_list_implicit.html>`_
to make the data types consistent.
- Inputs of `x` and `y` comply with the implicit type conversion rules to make the data types consistent.
- The inputs must be two tensors or one tensor and one scalar.
- When the inputs are two tensors,
dtypes of them cannot be bool at the same time, and the shapes of them can be broadcast.
@ -1949,9 +1945,7 @@ class Mul(_MathBinaryOp):
out_{i} = x_{i} * y_{i}
.. note::
- Inputs of `x` and `y` comply with the
`implicit type conversion rules <https://www.mindspore.cn/docs/note/en/master/operator_list_implicit.html>`_
to make the data types consistent.
- Inputs of `x` and `y` comply with the implicit type conversion rules to make the data types consistent.
- The inputs must be two tensors or one tensor and one scalar.
- When the inputs are two tensors,
dtypes of them cannot be bool at the same time, and the shapes of them can be broadcast.
@ -2207,7 +2201,7 @@ class Reciprocal(PrimitiveWithInfer):
TypeError: If `x` is not a Tensor.
Supported Platforms:
``Ascend`` ``GPU``
``Ascend`` ``GPU`` ``CPU``
Examples:
>>> x = Tensor(np.array([1.0, 2.0, 4.0]), mindspore.float32)
@ -2251,9 +2245,7 @@ class Pow(Primitive):
out_{i} = x_{i} ^{ y_{i}}
.. note::
- Inputs of `x` and `y` comply with the
`implicit type conversion rules <https://www.mindspore.cn/docs/note/en/master/operator_list_implicit.html>`_
to make the data types consistent.
- Inputs of `x` and `y` comply with the implicit type conversion rules to make the data types consistent.
- The inputs must be two tensors or one tensor and one scalar.
- When the inputs are two tensors,
dtypes of them cannot be bool at the same time, and the shapes of them can be broadcast.
@ -2879,9 +2871,7 @@ class Div(_MathBinaryOp):
out_{i} = \frac{x_i}{y_i}
.. note::
- Inputs of `x` and `y` comply with the
`implicit type conversion rules <https://www.mindspore.cn/docs/note/en/master/operator_list_implicit.html>`_
to make the data types consistent.
- Inputs of `x` and `y` comply with the implicit type conversion rules to make the data types consistent.
- The inputs must be two tensors or one tensor and one scalar.
- When the inputs are two tensors,
dtypes of them cannot be bool at the same time, and the shapes of them can be broadcast.
@ -4092,9 +4082,7 @@ class LessEqual(_LogicBinaryOp):
\end{cases}
.. note::
- Inputs of `x` and `y` comply with the
`implicit type conversion rules <https://www.mindspore.cn/docs/note/en/master/operator_list_implicit.html>`_
to make the data types consistent.
- Inputs of `x` and `y` comply with the implicit type conversion rules to make the data types consistent.
- The inputs must be two tensors or one tensor and one scalar.
- When the inputs are two tensors,
dtypes of them cannot be both bool , and the shapes of them can be broadcast.
@ -5434,7 +5422,7 @@ class Inv(Primitive):
TypeError: If dtype of `x` is not one of float16, float32, int32.
Supported Platforms:
``Ascend``
``Ascend`` ``CPU``
Examples:
>>> inv = ops.Inv()

View File

@ -199,28 +199,44 @@ def test_round():
@pytest.mark.level0
@pytest.mark.platform_x86_cpu
@pytest.mark.env_onecard
def test_reciprocal():
@pytest.mark.parametrize('shape', [(2,), (4, 5), (3, 4, 5, 6)])
@pytest.mark.parametrize('dtype, tol',
[(np.int32, 1.0e-7), (np.float16, 1.0e-5), (np.float32, 1.0e-5), (np.float64, 1.0e-7)])
def test_reciprocal(shape, dtype, tol):
"""
Feature: ALL To ALL
Description: test cases for reciprocal
Expectation: the result match to numpy
"""
net = ReciprocalNet()
prop = 100 if np.random.random() > 0.5 else -100
x = np.random.randn(3, 4, 5, 6).astype(np.float16) * prop
x = np.random.randn(*shape).astype(dtype) * prop
output = net(Tensor(x))
expect_output = (1. / x).astype(np.float16)
expect_output = (1. / x).astype(dtype)
diff = output.asnumpy() - expect_output
error = np.ones(shape=expect_output.shape) * 1.0e-5
error = np.ones(shape=expect_output.shape) * tol
assert np.all(np.abs(diff) < error)
x = np.random.randn(3, 4, 5, 6).astype(np.float32) * prop
output = net(Tensor(x))
expect_output = (1. / x).astype(np.float32)
diff = output.asnumpy() - expect_output
error = np.ones(shape=expect_output.shape) * 1.0e-5
assert np.all(np.abs(diff) < error)
x = np.random.randn(3, 4, 5, 6).astype(np.float64) * prop
output = net(Tensor(x))
expect_output = (1. / x).astype(np.float64)
@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.int32, 1.0e-7), (np.float16, 1.0e-5), (np.float32, 1.0e-5)])
def test_inv(shape, dtype, tol):
"""
Feature: ALL To ALL
Description: test cases for inv
Expectation: the result match to numpy
"""
inv = P.Inv()
prop = 100 if np.random.random() > 0.5 else -100
x = np.random.randn(*shape).astype(dtype) * prop
output = inv(Tensor(x))
expect_output = (1. / x).astype(dtype)
diff = output.asnumpy() - expect_output
error = np.ones(shape=expect_output.shape) * 1.0e-7
error = np.ones(shape=expect_output.shape) * tol
assert np.all(np.abs(diff) < error)