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> ExecuteDispatch1D(const P & params)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 { ExecuteDispatch1D42 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