// 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_TRANSFORM_KERNELS_H_
#define GEMMLOWP_META_TRANSFORM_KERNELS_H_
#include "base.h"
namespace gemmlowp {
namespace meta {
struct Quantize {
float range_min;
float range_offset;
float range_scale;
int count;
};
struct Dequantize {
float range_min;
float range_offset;
float range_scale;
int count;
};
struct Requantize {
float input_range_min;
float input_range_offset;
float input_range_scale;
float output_range_min;
float output_range_offset;
float one_over_output_range_scale;
int count;
};
template <typename Type>
struct MinMax {
Type min;
Type max;
int count;
};
template <typename BiasType>
struct BiasAdd {
float input_range_min;
float input_range_offset;
float input_range_scale;
float bias_range_min;
float bias_range_offset;
float bias_range_scale;
float output_range_min;
float output_range_offset;
float one_over_output_range_scale;
int count;
int rows;
const BiasType* bias;
};
template <typename InType, typename OutType, int kernel_size, int leftovers>
class Transform1DKernel<InType, OutType, Quantize, kernel_size, leftovers> {
public:
static void Transform(const InType* in, const Quantize& params,
OutType* output) {
#ifdef DEBUG
#ifdef DEBUG_METAGEMM_VERBOSE
std::cout << "Quantize::Transform(" << std::string(typeid(InType).name())
<< ", " << std::string(typeid(OutType).name()) << ") -- "
<< kernel_size << "x" << leftovers << std::endl;
#endif
#else
std::cerr << "FATAL: Quantize::Transform not implemented." << std::endl;
std::exit(1);
#endif
}
};
template <typename InType, typename OutType, int kernel_size, int leftovers>
class Transform1DKernel<InType, OutType, Dequantize, kernel_size, leftovers> {
public:
static void Transform(const InType* in, const Dequantize& params,
OutType* output) {
#ifdef DEBUG
#ifdef DEBUG_METAGEMM_VERBOSE
std::cout << "Dequantize::Transform(" << std::string(typeid(InType).name())
<< ", " << std::string(typeid(OutType).name()) << ") -- "
<< kernel_size << "x" << leftovers << std::endl;
#endif
#else
std::cerr << "FATAL: Dequantize::Transform not implemented." << std::endl;
std::exit(1);
#endif
}
};
template <typename InType, typename OutType, int kernel_size, int leftovers>
class Transform1DKernel<InType, OutType, Requantize, kernel_size, leftovers> {
public:
static void Transform(const InType* in, const Requantize& params,
OutType* output) {
#ifdef DEBUG
#ifdef DEBUG_METAGEMM_VERBOSE
std::cout << "Requantize::Transform(" << std::string(typeid(InType).name())
<< ", " << std::string(typeid(OutType).name()) << ") -- "
<< kernel_size << "x" << leftovers << std::endl;
#endif
#else
std::cerr << "FATAL: Requantize::Transform not implemented." << std::endl;
std::exit(1);
#endif
}
};
template <typename InType, typename OutType, int kernel_size, int leftovers,
typename Type>
class Transform1DKernel<InType, OutType, MinMax<Type>, kernel_size, leftovers> {
public:
static void Transform(const InType* in, const MinMax<Type>& params,
OutType* output) {
#ifdef DEBUG
#ifdef DEBUG_METAGEMM_VERBOSE
std::cout << "MinMax::Transform(" << std::string(typeid(InType).name())
<< ", " << std::string(typeid(OutType).name()) << ") -- "
<< kernel_size << "x" << leftovers << std::endl;
#endif
#else
std::cerr << "FATAL: MinMax::Transform not implemented." << std::endl;
std::exit(1);
#endif
}
};
template <typename InType, typename OutType, int kernel_size, int leftovers,
typename Type>
class Transform1DKernel<InType, OutType, BiasAdd<Type>, kernel_size,
leftovers> {
public:
static void Transform(const InType* in, const BiasAdd<Type>& params,
OutType* output) {
#ifdef DEBUG
#ifdef DEBUG_METAGEMM_VERBOSE
std::cout << "BiasAdd::Transform(" << std::string(typeid(InType).name())
<< ", " << std::string(typeid(OutType).name()) << ") -- "
<< kernel_size << "x" << leftovers << std::endl;
#endif
#else
std::cerr << "FATAL: BiasAdd::Transform not implemented." << std::endl;
std::exit(1);
#endif
}
};
template <typename InType, typename OutType>
class Transform1DUtil<InType, OutType, Quantize> {
public:
static int EstimateComputeCost(const Quantize& params) {
return params.count * 8;
}
static const InType* OffsetInput(const Quantize& params, const InType* input,
int offset) {
return input + offset;
}
static OutType* OffsetOutput(const Quantize& params, OutType* output,
int offset) {
return output + offset;
}
};
template <typename InType, typename OutType>
class Transform1DUtil<InType, OutType, Requantize> {
public:
static int EstimateComputeCost(const Requantize& params) {
return params.count * 12;
}
static const InType* OffsetInput(const Requantize& params,
const InType* input, int offset) {
return input + offset;
}
static OutType* OffsetOutput(const Requantize& params, OutType* output,
int offset) {
return output + offset;
}
};
template <typename InType, typename OutType>
class Transform1DUtil<InType, OutType, Dequantize> {
public:
static int EstimateComputeCost(const Dequantize& params) {
return params.count * 12;
}
static const InType* OffsetInput(const Dequantize& params,
const InType* input, int offset) {
return input + offset;
}
static OutType* OffsetOutput(const Dequantize& params, OutType* output,
int offset) {
return output + offset;
}
};
template <typename InType, typename OutType, typename MinMaxType>
class Transform1DUtil<InType, OutType, MinMax<MinMaxType>> {
public:
static int EstimateComputeCost(const MinMax<MinMaxType>& params) {
return params.count * 4;
}
static const InType* OffsetInput(const MinMax<MinMaxType>& params,
const InType* input, int offset) {
return input + offset;
}
static OutType* OffsetOutput(const MinMax<MinMaxType>& params,
OutType* output, int offset) {
return output + offset;
}
};
} // namespace meta
} // namespace gemmlowp
#ifdef GEMMLOWP_NEON_32
#include "transform_kernels_arm_32.h"
#elif defined(GEMMLOWP_NEON_64)
#include "transform_kernels_arm_64.h"
#endif
#endif // GEMMLOWP_META_TRANSFORM_KERNELS_H_