Imported Upstream version 1.9.0
[platform/core/ml/nnfw.git] / compute / cker / include / cker / eigen / eigen_convolution_helpers.h
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3  * Copyright 2019 The TensorFlow Authors. All Rights Reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #ifndef __NNFW_CKER_EIGEN_EIGEN_CONVOLUTION_HELPERS_H__
19 #define __NNFW_CKER_EIGEN_EIGEN_CONVOLUTION_HELPERS_H__
20
21 namespace Eigen
22 {
23 namespace internal
24 {
25
26 // TensorEvaluatorHasPartialPacket<TensorEvaluatorType, PacketType, IndexType>
27 // provides `value` that is true if TensorEvaluatorType has `PacketType
28 // partialPacket<PacketType>(IndexType, unpacket_traits<PacketType>::mask_t)
29 // const` and if the PacketType supports masked load.
30 //
31 // Partial packets are used to:
32 //
33 // 1) Split the packet over two columns in eigen based spatial convolution and
34 // use partial loads for each individual part before combining them to get the
35 // required packet. This class is used to pick the correct implementation of
36 // loadPacketStandard function.
37 //
38 // 2) Split the packet over two rows (within the same column) in eigen based
39 // cuboid convolution and use partial loads for each individual part before
40 // combining them to get the required packet. This class is used to pick the
41 // correct implementation of loadPacketStandard function. This usage is similar
42 // to the usage in eigen based spatial convolution described above.
43 //
44 // 3) Finalize packing of columns in gemm_pack_colmajor after processing
45 //    vectorized part with full packets (see eigen_spatial_convolutions.h).
46 template <typename TensorEvaluatorType, typename PacketType, typename IndexType>
47 class TensorEvaluatorHasPartialPacket
48 {
49 public:
50   template <typename TensorEvaluatorT, typename PacketT, typename IndexT>
51   static auto functionExistsSfinae(
52       typename std::enable_if<
53           unpacket_traits<PacketT>::masked_load_available &&
54           std::is_same<
55               PacketT,
56               decltype(std::declval<const TensorEvaluatorT>().template partialPacket<PacketT>(
57                   std::declval<IndexT>(),
58                   std::declval<typename unpacket_traits<PacketT>::mask_t>()))>::value>::type *)
59       -> std::true_type;
60
61   template <typename TensorEvaluatorT, typename PacketT, typename IndexT>
62   static auto functionExistsSfinae(...) -> std::false_type;
63
64   typedef decltype(
65       functionExistsSfinae<TensorEvaluatorType, PacketType, IndexType>(nullptr)) status;
66
67   static constexpr bool value = status::value;
68 };
69
70 // Compute a mask for loading/storing coefficients in/from a packet in a
71 // [from, to) range. If the mask bit is 1, element will be loaded/stored.
72 template <typename Packet>
73 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
74     typename std::enable_if<unpacket_traits<Packet>::masked_load_available,
75                             typename unpacket_traits<Packet>::mask_t>::type
76     mask(int from, int to)
77 {
78   const Index packet_size = internal::unpacket_traits<Packet>::size;
79   eigen_assert(0 <= from && to <= (packet_size + 1) && from < to);
80
81   using Mask = typename internal::unpacket_traits<Packet>::mask_t;
82   const Mask mask_max = std::numeric_limits<Mask>::max();
83
84   return (mask_max >> (packet_size - to)) ^ (mask_max >> (packet_size - from));
85 }
86
87 } // namespace internal
88 } // namespace Eigen
89
90 #endif // __NNFW_CKER_EIGEN_EIGEN_CONVOLUTION_HELPERS_H__