summaryrefslogtreecommitdiff
path: root/compute/cker/include/cker/operation/Logistic.h
diff options
context:
space:
mode:
Diffstat (limited to 'compute/cker/include/cker/operation/Logistic.h')
-rw-r--r--compute/cker/include/cker/operation/Logistic.h29
1 files changed, 28 insertions, 1 deletions
diff --git a/compute/cker/include/cker/operation/Logistic.h b/compute/cker/include/cker/operation/Logistic.h
index 3d3e59e55..e9907729e 100644
--- a/compute/cker/include/cker/operation/Logistic.h
+++ b/compute/cker/include/cker/operation/Logistic.h
@@ -29,12 +29,39 @@ namespace nnfw
namespace cker
{
+/**
+ * @brief Internal scalar_logistic_op operation struct
+ *
+ * @note Recent Eigen3 scalar_logistic_op return invalid value on ARM32 if
+ * input value is float type 88 (expected: 1, actual: 0)
+ * As a workaround, we use old version scalar_logistic_op internal struct
+ * TODO Remove this workaround
+ */
+template <typename T> struct scalar_logistic_op
+{
+ EIGEN_EMPTY_STRUCT_CTOR(scalar_logistic_op)
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T operator()(const T &x) const
+ {
+ const T one = T(1);
+ return one / (one + Eigen::numext::exp(-x));
+ }
+
+ template <typename Packet>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet &x) const
+ {
+ const Packet one = Eigen::internal::pset1<Packet>(T(1));
+ return pdiv(one, padd(one, pexp(pnegate(x))));
+ }
+};
+
inline void Logistic(const Shape &input_shape, const float *input_data, const Shape &output_shape,
float *output_data)
{
auto input_map = MapAsVector(input_data, input_shape);
auto output_map = MapAsVector(output_data, output_shape);
- output_map.array() = input_map.array().unaryExpr(Eigen::internal::scalar_logistic_op<float>());
+
+ // Use old version scalar_logistic_op
+ output_map.array() = input_map.array().unaryExpr(nnfw::cker::scalar_logistic_op<float>());
}
} // namespace cker