1 | // Copyright 2016 The Gemmlowp Authors. All Rights Reserved. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #ifndef GEMMLOWP_META_SINGLE_THREAD_TRANSFORM_H_ |
16 | #define GEMMLOWP_META_SINGLE_THREAD_TRANSFORM_H_ |
17 | |
18 | #include <iostream> |
19 | #include "base.h" |
20 | |
21 | namespace gemmlowp { |
22 | namespace meta { |
23 | |
24 | template <typename Params, int kernel_size> |
25 | void Transform1D(const Params& params); |
26 | |
27 | namespace internal { |
28 | |
29 | class Transform1DExecutor { |
30 | public: |
31 | template <typename P, int kernel_size, int leftovers> |
32 | static void ExecuteDispatch1D(const P& params) { |
33 | Transform1DKernel<typename P::InType, typename P::OutType, |
34 | typename P::Kernel, kernel_size, |
35 | leftovers>::Transform(params.input, params.kernel, |
36 | params.output); |
37 | } |
38 | }; |
39 | |
40 | template <typename E, typename P, int kernel_size, int variable_leftovers> |
41 | struct Dispatch1D { |
42 | static void Execute(const P& params, int leftovers) { |
43 | #ifdef DEBUG |
44 | #ifdef DEBUG_METAGEMM_VERBOSE |
45 | std::cout << "Dispatch(1): " << kernel_size << ":" << variable_leftovers |
46 | << std::endl |
47 | << std::flush; |
48 | #endif |
49 | #endif |
50 | if (leftovers == variable_leftovers) { |
51 | E::template ExecuteDispatch1D<P, kernel_size, variable_leftovers>(params); |
52 | } else { |
53 | Dispatch1D<E, P, kernel_size, variable_leftovers - 1>::Execute(params, |
54 | leftovers); |
55 | } |
56 | } |
57 | }; |
58 | |
59 | template <typename E, typename P, int kernel_size> |
60 | struct Dispatch1D<E, P, kernel_size, 0> { |
61 | static void Execute(const P& params, int leftovers) { |
62 | #ifdef DEBUG |
63 | #ifdef DEBUG_METAGEMM_VERBOSE |
64 | std::cout << "Dispatch(1): " << kernel_size << ": 0" << std::endl |
65 | << std::flush; |
66 | #endif |
67 | #endif |
68 | if (leftovers == 0) { |
69 | E::template ExecuteDispatch1D<P, kernel_size, 0>(params); |
70 | } else { |
71 | std::cerr << "FATAL: dispatch1D failed: ran out of cases." << std::endl |
72 | << std::flush; |
73 | std::exit(1); |
74 | } |
75 | } |
76 | }; |
77 | |
78 | } // namespace internal |
79 | |
80 | template <typename Params, int kernel_size> |
81 | inline void Transform1D(const Params& params) { |
82 | internal::Dispatch1D<internal::Transform1DExecutor, Params, kernel_size, |
83 | kernel_size - 1>::Execute(params, params.kernel.count % |
84 | kernel_size); |
85 | } |
86 | |
87 | } // namespace meta |
88 | } // namespace gemmlowp |
89 | |
90 | #endif // GEMMLOWP_META_SINGLE_THREAD_TRANSFORM_H_ |
91 | |