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 24 namespace gemmlowp { 25 namespace meta { 26 27 struct QuantizedStaticPreprocessed { 28 public: 29 int multiplicative_offset; 30 int rounding_offset; 31 int shift; 32 int count; 33 }; 34 35 template <typename InType, typename OutType, int m, int n, int k> 36 class MulKernel<InType, OutType, QuantizedStaticPreprocessed, RowMajor, m, n, 37 k> { 38 public: 39 typedef FusedKernelParams<QuantizedStaticPreprocessed, RowMajor> FusedKernel; 40 Multiply(const InType * lhs,const InType *,const FusedKernel & params,OutType * result)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 Debug(const FusedKernel & params)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 78 struct QuantizedStaticPreprocessedAsInt32 { 79 public: 80 int count; 81 }; 82 83 template <typename InType, typename OutType, int m, int n, int k> 84 class MulKernel<InType, OutType, QuantizedStaticPreprocessedAsInt32, RowMajor, 85 m, n, k> { 86 public: 87 typedef FusedKernelParams<QuantizedStaticPreprocessedAsInt32, RowMajor> 88 FusedKernel; 89 Multiply(const InType * lhs,const InType *,const FusedKernel & params,OutType * result)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 Debug(const FusedKernel & params)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 122 struct QuantizedStaticPreprocessedAsFloat { 123 public: 124 int count; 125 float scale; 126 }; 127 128 template <typename InType, typename OutType, int m, int n, int k> 129 class MulKernel<InType, OutType, QuantizedStaticPreprocessedAsFloat, RowMajor, 130 m, n, k> { 131 public: 132 typedef FusedKernelParams<QuantizedStaticPreprocessedAsFloat, RowMajor> 133 FusedKernel; 134 Multiply(const InType * lhs,const InType *,const FusedKernel & params,OutType * result)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 Debug(const FusedKernel & params)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