blob: 1e000947de97fd567434a542fc7294c627ebe1ac [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/*!
* \file np_elemwise_unary_op_basic.cc
* \brief CPU Implementation of numpy elementwise unary function.
*/
#include <mxnet/base.h>
#include "operator/tensor/elemwise_unary_op.h"
#include "operator/tensor/elemwise_binary_op.h"
namespace mxnet {
namespace op {
MXNET_OPERATOR_REGISTER_UNARY(_npx_relu)
.describe(R"code(Computes rectified linear activation.
.. math::
max(features, 0)
)code" ADD_FILELINE)
.set_attr<FCompute>("FCompute<cpu>", UnaryOp::Compute<cpu, mshadow_op::relu>)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseOut{"_backward_relu"});
MXNET_OPERATOR_REGISTER_UNARY(_npx_sigmoid)
.describe(R"code(Computes sigmoid of x element-wise.
.. math::
y = 1 / (1 + exp(-x))
)code" ADD_FILELINE)
.set_attr<FCompute>("FCompute<cpu>", UnaryOp::Compute<cpu, mshadow_op::sigmoid>)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseOut{"_backward_sigmoid"});
NNVM_REGISTER_OP(_npi_copy)
.describe(R"code(Return an array copy of the given object.)code" ADD_FILELINE)
.set_num_inputs(1)
.set_num_outputs(1)
.set_attr<mxnet::FInferShape>("FInferShape", ElemwiseShape<1, 1>)
.set_attr<nnvm::FInferType>("FInferType", ElemwiseType<1, 1>)
.set_attr<nnvm::FInplaceOption>("FInplaceOption",
[](const NodeAttrs& attrs) {
return std::vector<std::pair<int, int> >{{0, 0}};
})
.set_attr<FCompute>("FCompute<cpu>", UnaryOp::IdentityCompute<cpu>)
.set_attr<nnvm::FInplaceIdentity>("FInplaceIdentity",
[](const NodeAttrs& attrs) {
return std::vector<bool>{true};
})
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseNone{"_copy"})
.set_attr<nnvm::FListInputNames>("FListInputNames",
[](const NodeAttrs& attrs) {
return std::vector<std::string>{"a"};
})
.add_argument("a", "NDArray-or-Symbol", "The input");
#define MXNET_OPERATOR_REGISTER_NUMPY_UNARY(__name$, __input_name$, __kernel$) \
NNVM_REGISTER_OP(__name$) \
.set_num_inputs(1) \
.set_num_outputs(1) \
.set_attr<mxnet::FInferShape>("FInferShape", ElemwiseShape<1, 1>) \
.set_attr<nnvm::FInferType>("FInferType", ElemwiseType<1, 1>) \
.set_attr<nnvm::FInplaceOption>("FInplaceOption", \
[](const NodeAttrs& attrs) { \
return std::vector<std::pair<int, int> >{{0, 0}}; \
}) \
.set_attr<nnvm::FListInputNames>( \
"FListInputNames", \
[](const NodeAttrs& attrs) { return std::vector<std::string>{__input_name$}; }) \
.set_attr<FCompute>("FCompute<cpu>", UnaryOp::Compute<cpu, __kernel$>) \
.add_argument(__input_name$, "NDArray-or-Symbol", "The input array.")
inline bool MixedUnaryOpType(const nnvm::NodeAttrs& attrs,
std::vector<int>* in_attrs,
std::vector<int>* out_attrs) {
CHECK_EQ(in_attrs->size(), 1U);
CHECK_EQ(out_attrs->size(), 1U);
int a_type = in_attrs->at(0);
if (mxnet::common::is_float(a_type)) {
TYPE_ASSIGN_CHECK(*out_attrs, 0, in_attrs->at(0));
} else if (a_type == mshadow::kInt32 || a_type == mshadow::kInt64) {
TYPE_ASSIGN_CHECK(*out_attrs, 0, mshadow::kFloat32);
} else {
TYPE_ASSIGN_CHECK(*out_attrs, 0, mshadow::kFloat16);
}
return out_attrs->at(0) != -1;
}
#define MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(__name$, __input_name$, __kernel$) \
NNVM_REGISTER_OP(__name$) \
.set_num_inputs(1) \
.set_num_outputs(1) \
.set_attr<mxnet::FInferShape>("FInferShape", ElemwiseShape<1, 1>) \
.set_attr<nnvm::FInferType>("FInferType", MixedUnaryOpType) \
.set_attr<nnvm::FInplaceOption>("FInplaceOption", \
[](const NodeAttrs& attrs) { \
return std::vector<std::pair<int, int> >{{0, 0}}; \
}) \
.set_attr<nnvm::FListInputNames>( \
"FListInputNames", \
[](const NodeAttrs& attrs) { return std::vector<std::string>{__input_name$}; }) \
.set_attr<FCompute>("FCompute<cpu>", UnaryOp::ComputeMixedType<cpu, __kernel$>) \
.add_argument(__input_name$, "NDArray-or-Symbol", "The input array.")
#define MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_BWD_IN(name) \
NNVM_REGISTER_OP(name) \
.set_num_inputs(2) \
.set_num_outputs(1) \
.set_attr<nnvm::FListInputNames>("FListInputNames", \
[](const NodeAttrs& attrs) { \
return std::vector<std::string>{"lhs", "rhs"}; \
}) \
.set_attr<mxnet::FInferShape>("FInferShape", ElemwiseShape<2, 1>) \
.set_attr<nnvm::FInplaceOption>("FInplaceOption", \
[](const NodeAttrs& attrs) { \
return std::vector<std::pair<int, int> >{{0, 0}, {1, 0}}; \
}) \
.add_argument("lhs", "NDArray-or-Symbol", "first input") \
.add_argument("rhs", "NDArray-or-Symbol", "second input")
/*! \brief Binary launch */
#define MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_BWD_INOUT(name) \
NNVM_REGISTER_OP(name) \
.set_num_inputs(3) \
.set_num_outputs(1) \
.set_attr<nnvm::FListInputNames>("FListInputNames", \
[](const NodeAttrs& attrs) { \
return std::vector<std::string>{"lhs", "rhs"}; \
}) \
.set_attr<mxnet::FInferShape>("FInferShape", ElemwiseShape<3, 1>) \
.set_attr<nnvm::FInplaceOption>("FInplaceOption", \
[](const NodeAttrs& attrs) { \
return std::vector<std::pair<int, int> >{{0, 0}, {1, 0}}; \
}) \
.add_argument("lhs", "NDArray-or-Symbol", "first input") \
.add_argument("rhs", "NDArray-or-Symbol", "second input")
#define MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_IN_CPU(__name$, __kernel$) \
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_BWD_IN(__name$).set_attr<FCompute>( \
"FCompute<cpu>", ElemwiseBinaryOp::MixedUnaryBackwardUseInCompute<cpu, __kernel$>)
#define MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(__name$, __kernel$) \
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_BWD_IN(__name$).set_attr<FCompute>( \
"FCompute<cpu>", ElemwiseBinaryOp::MixedUnaryBackwardUseInCompute<cpu, __kernel$>)
#define MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEINOUT_BWD_CPU(__name$, __kernel$) \
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_BWD_INOUT(__name$).set_attr<FCompute>( \
"FCompute<cpu>", ElemwiseBinaryOp::MixedUnaryBackwardUseInOutCompute<cpu, __kernel$>)
bool NumpyUnaryBoolOpType(const nnvm::NodeAttrs& attrs,
std::vector<int>* in_attrs,
std::vector<int>* out_attrs) {
CHECK_EQ(in_attrs->size(), 1U);
CHECK_EQ(out_attrs->size(), 1U);
if (in_attrs->at(0) == -1)
return false;
if (out_attrs->at(0) == -1) {
out_attrs->at(0) = mshadow::kBool;
} else if (out_attrs->at(0) != mshadow::kBool) {
LOG(FATAL) << "TypeError: the `out` parameter should be a boolean array";
}
return true;
}
#define MXNET_OPERATOR_REGISTER_NUMPY_UNARY_BOOL(__name$, __input_name$, __kernel$) \
NNVM_REGISTER_OP(__name$) \
.set_num_inputs(1) \
.set_num_outputs(1) \
.set_attr<mxnet::FInferShape>("FInferShape", ElemwiseShape<1, 1>) \
.set_attr<nnvm::FInferType>("FInferType", NumpyUnaryBoolOpType) \
.set_attr<nnvm::FInplaceOption>("FInplaceOption", \
[](const NodeAttrs& attrs) { \
return std::vector<std::pair<int, int> >{{0, 0}}; \
}) \
.set_attr<nnvm::FListInputNames>( \
"FListInputNames", \
[](const NodeAttrs& attrs) { return std::vector<std::string>{__input_name$}; }) \
.set_attr<FCompute>("FCompute<cpu>", UnaryOp::ComputeLogic<cpu, __kernel$>) \
.add_argument(__input_name$, "NDArray-or-Symbol", "The input array.")
// negative
MXNET_OPERATOR_REGISTER_NUMPY_UNARY(_npi_negative, "x", mshadow_op::negation)
.describe(R"code(Numerical negative, element-wise.
Example::
negative([1., -1.]) = [-1., 1.]
)code")
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseNone{"negative"});
// reciprocal
MXNET_OPERATOR_REGISTER_NUMPY_UNARY(_npi_reciprocal, "x", mshadow_op::reciprocal)
.describe(R"code(Return the reciprocal of the argument, element-wise.
Example::
reciprocal([-2, 1, 3, 1.6, 0.2]) = [-0.5, 1.0, 0.33333334, 0.625, 5.0]
)code")
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_reciprocal"});
// abs
MXNET_OPERATOR_REGISTER_NUMPY_UNARY(_npi_absolute, "x", mshadow_op::abs)
.add_alias("_npi_abs")
.describe(R"code(Returns element-wise absolute value of the input.
Example::
absolute([-2, 0, 3]) = [2, 0, 3]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_abs"});
// sign
MXNET_OPERATOR_REGISTER_NUMPY_UNARY(_npi_sign, "x", mshadow_op::sign)
.describe(R"code(Returns an element-wise indication of the sign of a number.
The sign function returns -1 if x < 0, 0 if x==0, 1 if x > 0.
Example::
sign([-2, 0, 3]) = [-1, 0, 1]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// rint
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_rint, "x", mshadow_op::rint)
.describe(R"code(Round elements of the array to the nearest integer.
Example::
rint([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) = [-2., -2., -0., 0., 2., 2., 2.]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// ceil
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_ceil, "x", mshadow_op::ceil)
.describe(R"code(Return the ceiling of the input, element-wise.
The ceil of the scalar x is the smallest integer i, such that i >= x.
Example::
ceil([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) = [-1., -1., -0., 1., 2., 2., 2.]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// floor
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_floor, "x", mshadow_op::floor)
.describe(R"code(Return the floor of the input, element-wise.
The floor of the scalar x is the largest integer i, such that i <= x.
Example::
floor([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) = [-2., -2., -1., 0., 1., 1., 2.]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// bitwise_not
NNVM_REGISTER_OP(_npi_bitwise_not)
.set_num_inputs(1)
.set_num_outputs(1)
.set_attr<mxnet::FInferShape>("FInferShape", ElemwiseShape<1, 1>)
.set_attr<nnvm::FInferType>("FInferType", ElemwiseType<1, 1>)
.set_attr<nnvm::FListInputNames>("FListInputNames",
[](const NodeAttrs& attrs) {
return std::vector<std::string>{"x"};
})
.set_attr<FCompute>("FCompute<cpu>", UnaryOp::ComputeInt<cpu, mshadow_op::bitwise_not>)
.add_argument("x", "NDArray-or-Symbol", "The input array.")
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// trunc
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_trunc, "x", mshadow_op::trunc)
.describe(R"code(Return the truncated value of the input, element-wise.
The truncated value of the scalar x is the nearest integer i which is closer to
zero than x is. In short, the fractional part of the signed number x is discarded.
Example::
trunc([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) = [-1., -1., -0., 0., 1., 1., 2.]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// fix
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_fix, "x", mshadow_op::fix)
.describe(R"code(Round to nearest integer towards zero.
Round an array of floats element-wise to nearest integer towards zero.
The rounded values are returned as floats.
Example::
fix([-2.1, -1.9, 1.9, 2.1]) = [-2., -1., 1., 2.]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// square
MXNET_OPERATOR_REGISTER_NUMPY_UNARY(_npi_square, "x", mshadow_op::square)
.describe(R"code(Return the element-wise square of the input.
Example::
square([2, 3, 4]) = [4, 9, 16]
)code" ADD_FILELINE)
#if MXNET_USE_ONEDNN == 1
.set_attr<FComputeEx>("FComputeEx<cpu>", EltwiseComputeExCPU<mshadow_op::square, false>)
.set_attr<FInferStorageType>("FInferStorageType", EltwiseStorageType)
#endif // MXNET_USE_ONEDNN
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_square"});
// sqrt
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_sqrt, "x", mshadow_op::square_root)
.describe(R"code(Return the non-negative square-root of an array, element-wise.
Example::
sqrt([4, 9, 16]) = [2, 3, 4]
)code" ADD_FILELINE)
#if MXNET_USE_ONEDNN == 1
.set_attr<FComputeEx>("FComputeEx<cpu>", EltwiseComputeExCPU<mshadow_op::square_root, true>)
.set_attr<FInferStorageType>("FInferStorageType", EltwiseStorageType)
#endif // MXNET_USE_ONEDNN
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseInOut{"_backward_npi_sqrt"});
// cbrt
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_cbrt, "x", mshadow_op::cube_root)
.describe(R"code(Return the cube-root of an array, element-wise.
Example::
cbrt([1, 8, -125]) = [1, 2, -5]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseInOut{"_backward_npi_cbrt"});
// exp
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_exp, "x", mshadow_op::exp)
.describe(R"code(Calculate the exponential of all elements in the input array.
Example::
exp([0, 1, 2]) = [1., 2.71828175, 7.38905621]
)code" ADD_FILELINE)
#if MXNET_USE_ONEDNN == 1
.set_attr<FComputeEx>("FComputeEx<cpu>", EltwiseComputeExCPU<mshadow_op::exp, true>)
.set_attr<FInferStorageType>("FInferStorageType", EltwiseStorageType)
#endif // MXNET_USE_ONEDNN
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseInOut{"_backward_npi_exp"});
// log
NNVM_REGISTER_OP(_npi_log)
.describe(R"code(Returns element-wise Natural logarithmic value of the input.
The natural logarithm is logarithm in base *e*, so that ``log(exp(x)) = x``
)code" ADD_FILELINE)
.set_num_inputs(1)
.set_num_outputs(1)
.set_attr<mxnet::FInferShape>("FInferShape", ElemwiseShape<1, 1>)
.set_attr<nnvm::FInferType>("FInferType", MixedUnaryOpType)
.set_attr<nnvm::FInplaceOption>("FInplaceOption",
[](const NodeAttrs& attrs) {
return std::vector<std::pair<int, int> >{{0, 0}};
})
.set_attr<nnvm::FListInputNames>("FListInputNames",
[](const NodeAttrs& attrs) {
return std::vector<std::string>{"x"};
})
.set_attr<FCompute>("FCompute<cpu>", UnaryOp::ComputeMixedType<cpu, mshadow_op::log>)
.add_argument("x", "NDArray-or-Symbol", "The input array.")
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_log"});
// log10
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_log10, "x", mshadow_op::log10)
.describe(R"code(Returns element-wise Base-10 logarithmic value of the input.
``10**log10(x) = x``
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_log10"});
// log2
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_log2, "x", mshadow_op::log2)
.describe(R"code(Returns element-wise Base-2 logarithmic value of the input.
``2**log2(x) = x``
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_log2"});
// log1p
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_log1p, "x", mshadow_op::log1p)
.describe(R"code(Return the natural logarithm of one plus the input array, element-wise.
Calculates ``log(1 + x)``.
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_log1p"});
// expm1
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_expm1, "x", mshadow_op::expm1)
.describe(R"code(Calculate ``exp(x) - 1`` for all elements in the array.)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_expm1"});
// logical_not
MXNET_OPERATOR_REGISTER_NUMPY_UNARY_BOOL(_npi_logical_not, "x", mshadow_op::np_logical_not)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// isnan
MXNET_OPERATOR_REGISTER_NUMPY_UNARY_BOOL(_npi_isnan, "x", mshadow_op::isnan)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// isinf
MXNET_OPERATOR_REGISTER_NUMPY_UNARY_BOOL(_npi_isinf, "x", mshadow_op::isinf)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// isposinf
MXNET_OPERATOR_REGISTER_NUMPY_UNARY_BOOL(_npi_isposinf, "x", mshadow_op::isposinf)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// isneginf
MXNET_OPERATOR_REGISTER_NUMPY_UNARY_BOOL(_npi_isneginf, "x", mshadow_op::isneginf)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// isfinite
MXNET_OPERATOR_REGISTER_NUMPY_UNARY_BOOL(_npi_isfinite, "x", mshadow_op::isfinite)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
// sin
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_sin, "x", mshadow_op::sin)
.describe(R"code(Trigonometric sine, element-wise.
.. math::
sin([0, \pi/4, \pi/2]) = [0, 0.707, 1]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_sin"});
// cos
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_cos, "x", mshadow_op::cos)
.describe(R"code(Computes the element-wise cosine of the input array.
.. math::
cos([0, \pi/4, \pi/2]) = [1, 0.707, 0]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_cos"});
// tan
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_tan, "x", mshadow_op::tan)
.describe(R"code(Computes the element-wise tangent of the input array.
.. math::
tan([0, \pi/4, \pi/2]) = [0, 1, -inf]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseInOut{"_backward_npi_tan"});
// arcsin
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_arcsin, "x", mshadow_op::arcsin)
.describe(R"code(Returns element-wise inverse sine of the input array.
.. math::
arcsin([-1, -.707, 0, .707, 1]) = [-\pi/2, -\pi/4, 0, \pi/4, \pi/2]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_arcsin"});
// arccos
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_arccos, "x", mshadow_op::arccos)
.describe(R"code(Returns element-wise inverse cosine of the input array.
The input should be in range `[-1, 1]`.
The output is in the closed interval :math:`[0, \pi]`
.. math::
arccos([-1, -.707, 0, .707, 1]) = [\pi, 3\pi/4, \pi/2, \pi/4, 0]
The storage type of ``arccos`` output is always dense
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_arccos"});
// arctan
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_arctan, "x", mshadow_op::arctan)
.describe(R"code(Returns element-wise inverse tangent of the input array.
.. math::
arctan([-1, 0, 1]) = [-\pi/4, 0, \pi/4]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_arctan"});
// degrees
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_degrees, "x", mshadow_op::degrees)
.describe(R"code(Converts each element of the input array from radians to degrees.
.. math::
degrees([0, \pi/2, \pi, 3\pi/2, 2\pi]) = [0, 90, 180, 270, 360]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_degrees"});
// radians
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_radians, "x", mshadow_op::radians)
.describe(R"code(Converts each element of the input array from degrees to radians.
.. math::
radians([0, 90, 180, 270, 360]) = [0, \pi/2, \pi, 3\pi/2, 2\pi]
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_radians"});
// sinh
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_sinh, "x", mshadow_op::sinh)
.describe(R"code(Returns the hyperbolic sine of the input array, computed element-wise.
.. math::
sinh(x) = 0.5\times(exp(x) - exp(-x))
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_sinh"});
// cosh
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_cosh, "x", mshadow_op::cosh)
.describe(R"code(Returns the hyperbolic cosine of the input array, computed element-wise.
.. math::
cosh(x) = 0.5\times(exp(x) + exp(-x))
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_cosh"});
// tanh
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_tanh, "x", mshadow_op::tanh)
.describe(R"code(Returns the hyperbolic tangent of the input array, computed element-wise.
.. math::
tanh(x) = sinh(x) / cosh(x)
)code" ADD_FILELINE)
#if MXNET_USE_ONEDNN == 1
.set_attr<FComputeEx>("FComputeEx<cpu>", EltwiseComputeExCPU<mshadow_op::tanh, true>)
.set_attr<FInferStorageType>("FInferStorageType", EltwiseStorageType)
#endif // MXNET_USE_ONEDNN
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseInOut{"_backward_npi_tanh"});
// arcsinh
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_arcsinh, "x", mshadow_op::arcsinh)
.describe(R"code(Returns the element-wise inverse hyperbolic sine of the input array, \
computed element-wise.
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_arcsinh"});
// arccosh
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_arccosh, "x", mshadow_op::arccosh)
.describe(R"code(Returns the element-wise inverse hyperbolic cosine of the input array, \
computed element-wise.
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_arccosh"});
// arctanh
MXNET_OPERATOR_REGISTER_NUMPY_MIXED_TYPE_UNARY(_npi_arctanh, "x", mshadow_op::arctanh)
.describe(R"code(Returns the element-wise inverse hyperbolic tangent of the input array, \
computed element-wise.
)code" ADD_FILELINE)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_npi_arctanh"});
inline bool AroundOpType(const nnvm::NodeAttrs& attrs,
std::vector<int>* in_attrs,
std::vector<int>* out_attrs) {
CHECK_EQ(in_attrs->size(), 1U);
CHECK_EQ(out_attrs->size(), 1U);
TYPE_ASSIGN_CHECK(*out_attrs, 0, in_attrs->at(0));
TYPE_ASSIGN_CHECK(*in_attrs, 0, out_attrs->at(0));
CHECK(in_attrs->at(0) != mshadow::kFloat16) << "Do not support `float16` as input.\n";
return out_attrs->at(0) != -1;
}
DMLC_REGISTER_PARAMETER(AroundParam);
NNVM_REGISTER_OP(_npi_around)
.set_attr_parser(ParamParser<AroundParam>)
.set_num_inputs(1)
.set_num_outputs(1)
.set_attr<nnvm::FListInputNames>("FListInputNames",
[](const NodeAttrs& attrs) {
return std::vector<std::string>{"x"};
})
.set_attr<mxnet::FInferShape>("FInferShape", ElemwiseShape<1, 1>)
.set_attr<nnvm::FInferType>("FInferType", AroundOpType)
.set_attr<FCompute>("FCompute<cpu>", AroundOpForward<cpu>)
.set_attr<nnvm::FInplaceOption>("FInplaceOption",
[](const NodeAttrs& attrs) {
return std::vector<std::pair<int, int> >{{0, 0}};
})
.add_argument("x", "NDArray-or-Symbol", "Input ndarray")
.add_arguments(AroundParam::__FIELDS__())
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes);
DMLC_REGISTER_PARAMETER(NumpyNanToNumParam);
NNVM_REGISTER_OP(_npi_nan_to_num)
.describe("" ADD_FILELINE)
.set_attr_parser(ParamParser<NumpyNanToNumParam>)
.set_num_inputs(1)
.set_num_outputs(1)
.set_attr<nnvm::FListInputNames>("FListInputNames",
[](const NodeAttrs& attrs) {
return std::vector<std::string>{"data"};
})
.set_attr<mxnet::FInferShape>("FInferShape", ElemwiseShape<1, 1>)
.set_attr<nnvm::FInferType>("FInferType", ElemwiseType<1, 1>)
.set_attr<FCompute>("FCompute<cpu>", NumpyNanToNumOpForward<cpu>)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_npi_backward_nan_to_num"})
.set_attr<nnvm::FInplaceOption>("FInplaceOption",
[](const NodeAttrs& attrs) {
return std::vector<std::pair<int, int> >{{0, 0}};
})
.add_argument("data", "NDArray-or-Symbol", "Input ndarray")
.add_arguments(NumpyNanToNumParam::__FIELDS__());
NNVM_REGISTER_OP(_npi_backward_nan_to_num)
.set_attr_parser(ParamParser<NumpyNanToNumParam>)
.set_num_inputs(2)
.set_num_outputs(1)
.set_attr<nnvm::TIsBackward>("TIsBackward", true)
.set_attr<FCompute>("FCompute<cpu>", NumpyNanToNumOpBackward<cpu>);
NNVM_REGISTER_OP(_backward_npi_exp)
.set_num_inputs(3)
.set_num_outputs(1)
.set_attr<nnvm::FListInputNames>("FListInputNames",
[](const NodeAttrs& attrs) {
return std::vector<std::string>{"lhs", "mid", "rhs"};
})
.set_attr<mxnet::FInferShape>("FInferShape", ElemwiseShape<3, 1>)
.set_attr<nnvm::FInplaceOption>("FInplaceOption",
[](const NodeAttrs& attrs) {
return std::vector<std::pair<int, int> >{{0, 0}, {1, 0}};
})
.add_argument("lhs", "NDArray-or-Symbol", "first input")
.add_argument("rhs", "NDArray-or-Symbol", "second input")
.set_attr<FCompute>(
"FCompute<cpu>",
ElemwiseBinaryOp::MixedUnaryBackwardUseInOutCompute<cpu, op::mshadow_op::mul>)
.set_attr<FResourceRequest>("FResourceRequest", /* For Sparse CSR */
[](const NodeAttrs& attrs) {
return std::vector<ResourceRequest>{ResourceRequest::kTempSpace};
})
.set_attr<THasDeterministicOutput>("THasDeterministicOutput", true);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_log,
unary_bwd<mshadow_op::log_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_log10,
unary_bwd<mshadow_op::log10_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_log2,
unary_bwd<mshadow_op::log2_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_log1p,
unary_bwd<mshadow_op::log1p_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_expm1,
unary_bwd<mshadow_op::exp>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEINOUT_BWD_CPU(_backward_npi_sqrt,
unary_bwd<mshadow_op::square_root_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEINOUT_BWD_CPU(_backward_npi_cbrt,
unary_bwd<mshadow_op::cube_root_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_sin,
unary_bwd<mshadow_op::sin_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_IN_CPU(_backward_npi_cos, unary_bwd<mshadow_op::cos_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEINOUT_BWD_CPU(_backward_npi_tan,
unary_bwd<mshadow_op::tan_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_arcsin,
unary_bwd<mshadow_op::arcsin_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_arccos,
unary_bwd<mshadow_op::arccos_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_arctan,
unary_bwd<mshadow_op::arctan_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_degrees,
unary_bwd<mshadow_op::degrees_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_radians,
unary_bwd<mshadow_op::radians_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_sinh,
unary_bwd<mshadow_op::sinh_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_IN_CPU(_backward_npi_cosh,
unary_bwd<mshadow_op::cosh_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEINOUT_BWD_CPU(_backward_npi_tanh,
unary_bwd<mshadow_op::tanh_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_arcsinh,
unary_bwd<mshadow_op::arcsinh_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_arccosh,
unary_bwd<mshadow_op::arccosh_grad>);
MXNET_OPERATOR_REGISTER_UNARY_MIXEDTYPE_USEIN_BWD_CPU(_backward_npi_arctanh,
unary_bwd<mshadow_op::arctanh_grad>);
} // namespace op
} // namespace mxnet