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_QUANTIZED_MUL_KERNELS_H_
16#define GEMMLOWP_META_QUANTIZED_MUL_KERNELS_H_
17
18#include <iostream>
19#include <typeinfo>
20
21#include "base.h"
22#include "streams.h"
23
24namespace gemmlowp {
25namespace meta {
26
27struct QuantizedStaticPreprocessed {
28 public:
29  int multiplicative_offset;
30  int rounding_offset;
31  int shift;
32  int count;
33};
34
35template <typename InType, typename OutType, int m, int n, int k>
36class MulKernel<InType, OutType, QuantizedStaticPreprocessed, RowMajor, m, n,
37                k> {
38 public:
39  typedef FusedKernelParams<QuantizedStaticPreprocessed, RowMajor> FusedKernel;
40
41  static void Multiply(const InType* lhs, const InType*,
42                       const FusedKernel& params, OutType* result) {
43#ifdef DEBUG
44#ifdef DEBUG_METAGEMM_VERBOSE
45    std::cout << "MulQSPR(" << typeid(InType).name() << ", "
46              << typeid(OutType).name() << ")::Multiply() -- " << m << "x" << n
47              << "x" << k << std::endl;
48#endif
49#else
50    if (m != 0 && n != 0) {
51      std::cerr << "FATAL: QuantizedStaticPreprocessed_RowMajor::Multiply not "
52                << "implemented." << std::endl;
53      std::exit(1);
54    }
55#endif
56  }
57
58#ifdef DEBUG
59#ifdef DEBUG_METAGEMM_VERBOSE
60  static void Debug(const FusedKernel& params) {
61    std::cout << "MulQSPR(" << typeid(InType).name() << ", "
62              << typeid(OutType).name() << ") -- " << m << "x" << n << "x" << k
63              << std::endl;
64    std::cout << "  params:" << std::endl;
65    std::cout << "    kernel.multiplicative_offset: "
66              << params.kernel.multiplicative_offset << std::endl;
67    std::cout << "    kernel.rounding_offset: " << params.kernel.rounding_offset
68              << std::endl;
69    std::cout << "    kernel.shift: " << params.kernel.shift << std::endl;
70    std::cout << "    kernel.count: " << params.kernel.count << std::endl;
71    std::cout << "    output_stream.stride: " << params.output_stream.stride
72              << std::endl;
73  }
74#endif
75#endif
76};
77
78struct QuantizedStaticPreprocessedAsInt32 {
79 public:
80  int count;
81};
82
83template <typename InType, typename OutType, int m, int n, int k>
84class MulKernel<InType, OutType, QuantizedStaticPreprocessedAsInt32, RowMajor,
85                m, n, k> {
86 public:
87  typedef FusedKernelParams<QuantizedStaticPreprocessedAsInt32, RowMajor>
88      FusedKernel;
89
90  static void Multiply(const InType* lhs, const InType*,
91                       const FusedKernel& params, OutType* result) {
92#ifdef DEBUG
93#ifdef DEBUG_METAGEMM_VERBOSE
94    std::cout << "MulQSPI32R(" << typeid(InType).name() << ", "
95              << typeid(OutType).name() << ")::Multiply() -- " << m << "x" << n
96              << "x" << k << std::endl;
97#endif
98#else
99    if (m != 0 && n != 0) {
100      std::cerr << "FATAL: QuantizedStaticPreprocessedAsInt32_RowMajor::"
101                << "Multiply not implemented." << std::endl;
102      std::exit(1);
103    }
104#endif
105  }
106
107#ifdef DEBUG
108#ifdef DEBUG_METAGEMM_VERBOSE
109  static void Debug(const FusedKernel& params) {
110    std::cout << "MulQSPI32R(" << typeid(InType).name() << ", "
111              << typeid(OutType).name() << ") -- " << m << "x" << n << "x" << k
112              << std::endl;
113    std::cout << "  params:" << std::endl;
114    std::cout << "    kernel.count: " << params.kernel.count << std::endl;
115    std::cout << "    output_stream.stride: " << params.output_stream.stride
116              << std::endl;
117  }
118#endif
119#endif
120};
121
122struct QuantizedStaticPreprocessedAsFloat {
123 public:
124  int count;
125  float scale;
126};
127
128template <typename InType, typename OutType, int m, int n, int k>
129class MulKernel<InType, OutType, QuantizedStaticPreprocessedAsFloat, RowMajor,
130                m, n, k> {
131 public:
132  typedef FusedKernelParams<QuantizedStaticPreprocessedAsFloat, RowMajor>
133      FusedKernel;
134
135  static void Multiply(const InType* lhs, const InType*,
136                       const FusedKernel& params, OutType* result) {
137#ifdef DEBUG
138#ifdef DEBUG_METAGEMM_VERBOSE
139    std::cout << "MulQSPFR(" << typeid(InType).name() << ", "
140              << typeid(OutType).name() << ")::Multiply() -- " << m << "x" << n
141              << "x" << k << std::endl;
142#endif
143#else
144    if (m != 0 && n != 0) {
145      std::cerr << "FATAL: QuantizedStaticPreprocessedAsFloat_RowMajor::"
146                << "Multiply not implemented." << std::endl;
147      std::exit(1);
148    }
149#endif
150  }
151
152#ifdef DEBUG
153#ifdef DEBUG_METAGEMM_VERBOSE
154  static void Debug(const FusedKernel& params) {
155    std::cout << "MulQSPFR(" << typeid(InType).name() << ", "
156              << typeid(OutType).name() << ") -- " << m << "x" << n << "x" << k
157              << std::endl;
158    std::cout << "  params:" << std::endl;
159    std::cout << "    kernel.count: " << params.kernel.count << std::endl;
160    std::cout << "    kernel.scale: " << params.kernel.scale << std::endl;
161    std::cout << "    output_stream.stride: " << params.output_stream.stride
162              << std::endl;
163  }
164#endif
165#endif
166};
167
168}  // namespace meta
169}  // namespace gemmlowp
170
171#ifdef GEMMLOWP_NEON_32
172#include "quantized_mul_kernels_arm_32.h"
173#elif defined(GEMMLOWP_NEON_64)
174#include "quantized_mul_kernels_arm_64.h"
175#endif
176
177#endif  // GEMMLOWP_META_QUANTIZED_MUL_KERNELS_H_
178