| // Copyright 2016 The Gemmlowp Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef GEMMLOWP_META_QUANTIZED_MUL_KERNELS_H_ |
| #define GEMMLOWP_META_QUANTIZED_MUL_KERNELS_H_ |
| |
| #include <iostream> |
| #include <typeinfo> |
| |
| #include "base.h" |
| #include "streams.h" |
| |
| namespace gemmlowp { |
| namespace meta { |
| |
| struct QuantizedStaticPreprocessed { |
| public: |
| int multiplicative_offset; |
| int rounding_offset; |
| int shift; |
| int count; |
| }; |
| |
| template <typename InType, typename OutType, int m, int n, int k> |
| class MulKernel<InType, OutType, QuantizedStaticPreprocessed, RowMajor, m, n, |
| k> { |
| public: |
| typedef FusedKernelParams<QuantizedStaticPreprocessed, RowMajor> FusedKernel; |
| |
| static void Multiply(const InType* lhs, const InType*, |
| const FusedKernel& params, OutType* result) { |
| #ifdef DEBUG |
| #ifdef DEBUG_METAGEMM_VERBOSE |
| std::cout << "MulQSPR(" << typeid(InType).name() << ", " |
| << typeid(OutType).name() << ")::Multiply() -- " << m << "x" << n |
| << "x" << k << std::endl; |
| #endif |
| #else |
| if (m != 0 && n != 0) { |
| std::cerr << "FATAL: QuantizedStaticPreprocessed_RowMajor::Multiply not " |
| << "implemented." << std::endl; |
| std::exit(1); |
| } |
| #endif |
| } |
| |
| #ifdef DEBUG |
| #ifdef DEBUG_METAGEMM_VERBOSE |
| static void Debug(const FusedKernel& params) { |
| std::cout << "MulQSPR(" << typeid(InType).name() << ", " |
| << typeid(OutType).name() << ") -- " << m << "x" << n << "x" << k |
| << std::endl; |
| std::cout << " params:" << std::endl; |
| std::cout << " kernel.multiplicative_offset: " |
| << params.kernel.multiplicative_offset << std::endl; |
| std::cout << " kernel.rounding_offset: " << params.kernel.rounding_offset |
| << std::endl; |
| std::cout << " kernel.shift: " << params.kernel.shift << std::endl; |
| std::cout << " kernel.count: " << params.kernel.count << std::endl; |
| std::cout << " output_stream.stride: " << params.output_stream.stride |
| << std::endl; |
| } |
| #endif |
| #endif |
| }; |
| |
| struct QuantizedStaticPreprocessedAsInt32 { |
| public: |
| int count; |
| }; |
| |
| template <typename InType, typename OutType, int m, int n, int k> |
| class MulKernel<InType, OutType, QuantizedStaticPreprocessedAsInt32, RowMajor, |
| m, n, k> { |
| public: |
| typedef FusedKernelParams<QuantizedStaticPreprocessedAsInt32, RowMajor> |
| FusedKernel; |
| |
| static void Multiply(const InType* lhs, const InType*, |
| const FusedKernel& params, OutType* result) { |
| #ifdef DEBUG |
| #ifdef DEBUG_METAGEMM_VERBOSE |
| std::cout << "MulQSPI32R(" << typeid(InType).name() << ", " |
| << typeid(OutType).name() << ")::Multiply() -- " << m << "x" << n |
| << "x" << k << std::endl; |
| #endif |
| #else |
| if (m != 0 && n != 0) { |
| std::cerr << "FATAL: QuantizedStaticPreprocessedAsInt32_RowMajor::" |
| << "Multiply not implemented." << std::endl; |
| std::exit(1); |
| } |
| #endif |
| } |
| |
| #ifdef DEBUG |
| #ifdef DEBUG_METAGEMM_VERBOSE |
| static void Debug(const FusedKernel& params) { |
| std::cout << "MulQSPI32R(" << typeid(InType).name() << ", " |
| << typeid(OutType).name() << ") -- " << m << "x" << n << "x" << k |
| << std::endl; |
| std::cout << " params:" << std::endl; |
| std::cout << " kernel.count: " << params.kernel.count << std::endl; |
| std::cout << " output_stream.stride: " << params.output_stream.stride |
| << std::endl; |
| } |
| #endif |
| #endif |
| }; |
| |
| struct QuantizedStaticPreprocessedAsFloat { |
| public: |
| int count; |
| float scale; |
| }; |
| |
| template <typename InType, typename OutType, int m, int n, int k> |
| class MulKernel<InType, OutType, QuantizedStaticPreprocessedAsFloat, RowMajor, |
| m, n, k> { |
| public: |
| typedef FusedKernelParams<QuantizedStaticPreprocessedAsFloat, RowMajor> |
| FusedKernel; |
| |
| static void Multiply(const InType* lhs, const InType*, |
| const FusedKernel& params, OutType* result) { |
| #ifdef DEBUG |
| #ifdef DEBUG_METAGEMM_VERBOSE |
| std::cout << "MulQSPFR(" << typeid(InType).name() << ", " |
| << typeid(OutType).name() << ")::Multiply() -- " << m << "x" << n |
| << "x" << k << std::endl; |
| #endif |
| #else |
| if (m != 0 && n != 0) { |
| std::cerr << "FATAL: QuantizedStaticPreprocessedAsFloat_RowMajor::" |
| << "Multiply not implemented." << std::endl; |
| std::exit(1); |
| } |
| #endif |
| } |
| |
| #ifdef DEBUG |
| #ifdef DEBUG_METAGEMM_VERBOSE |
| static void Debug(const FusedKernel& params) { |
| std::cout << "MulQSPFR(" << typeid(InType).name() << ", " |
| << typeid(OutType).name() << ") -- " << m << "x" << n << "x" << k |
| << std::endl; |
| std::cout << " params:" << std::endl; |
| std::cout << " kernel.count: " << params.kernel.count << std::endl; |
| std::cout << " kernel.scale: " << params.kernel.scale << std::endl; |
| std::cout << " output_stream.stride: " << params.output_stream.stride |
| << std::endl; |
| } |
| #endif |
| #endif |
| }; |
| |
| } // namespace meta |
| } // namespace gemmlowp |
| |
| #ifdef GEMMLOWP_NEON_32 |
| #include "quantized_mul_kernels_arm_32.h" |
| #elif defined(GEMMLOWP_NEON_64) |
| #include "quantized_mul_kernels_arm_64.h" |
| #endif |
| |
| #endif // GEMMLOWP_META_QUANTIZED_MUL_KERNELS_H_ |