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