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