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
21namespace gemmlowp {
22namespace meta {
23
24template <typename Params, int kernel_size>
25void Transform1D(const Params& params);
26
27namespace internal {
28
29class 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
40template <typename E, typename P, int kernel_size, int variable_leftovers>
41struct 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
59template <typename E, typename P, int kernel_size>
60struct 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
80template <typename Params, int kernel_size>
81inline 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