Skip to content
Snippets Groups Projects
Commit aab3e328 authored by Axel Farrugia's avatar Axel Farrugia
Browse files

[Refactor] Split rescaling.hpp and activation.hpp into two types of files :

- kernels/ : The forward call of the corresponding kernels (Btw activation and rescaling have exactly the same implementation...)
- network/ : The utilitary functions which may be used by other kernels

Also move the `macs.hpp` file into the network folder, for coherence
parent 640bbef9
No related branches found
No related tags found
No related merge requests found
Showing
with 153 additions and 162 deletions
......@@ -7,4 +7,6 @@ class ExportLibCpp(ExportLib):
str(ROOT / "static" / "Makefile"): "",
str(ROOT / "static" / "typedefs.hpp"): "dnn/include/network",
str(ROOT / "static" / "utils.hpp"): "dnn/include/network",
str(ROOT / "static" / "rescaling_utils.hpp"): "dnn/include/network",
str(ROOT / "static" / "activation_utils.hpp"): "dnn/include/network",
}
#ifndef __AIDGE_EXPORT_CPP_KERNELS_ACTIVATION__
#define __AIDGE_EXPORT_CPP_KERNELS_ACTIVATION__
#include <type_traits>
#include "network/typedefs.hpp"
#include "network/utils.hpp"
#include "kernels/rescaling.hpp"
template<typename Output_T, typename T,
typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
__attribute__((always_inline)) inline
Output_T saturate (T value, int32_t /*sat*/)
{
return value;
}
template<typename Output_T, typename T,
typename std::enable_if<!std::is_floating_point<T>::value>::type* = nullptr>
__attribute__((always_inline)) inline
Output_T saturate (T value, uint32_t sat)
{
if (std::is_unsigned<Output_T>::value) {
return clamp(value, T(0), (T(1) << sat) - 1);
} else {
return clamp(value, -(T(1) << (sat - 1)), (T(1) << (sat - 1)) - 1);
}
}
template<typename Output_T,
typename Sum_T,
typename Rescaling_T>
__attribute__((always_inline)) inline
Output_T activation_forward_value (Sum_T weightedSum,
int output,
ActivationFunction_T func,
const Rescaling_T& __restrict rescaling)
{
switch(func) {
case Linear:
case Saturation: {
break;
}
case Rectifier: {
if(weightedSum <= 0) weightedSum = 0;
break;
}
default:
// Unsupported activation function
break;
}
// Value fixed here for now but it should be generated by
// the export module or determined by the type of Output_T
// For now only works for int8_t and uint8_t
const uint32_t NB_BITS = 8;
return saturate<Output_T>(rescaling(weightedSum, output), NB_BITS);
}
#include "network/activation_utils.hpp"
#include "network/rescaling_utils.hpp"
template<int NB_DATA,
ActivationFunction_T ACTIVATION,
......
......@@ -2,7 +2,7 @@
#define __AIDGE_EXPORT_CPP_KERNELS_BATCHNORM__
#include "network/typedefs.hpp"
#include "kernels/activation.hpp"
#include "network/activation_utils.hpp"
#include <math.h>
......
......@@ -2,10 +2,10 @@
#define __AIDGE_EXPORT_CPP_KERNELS_CONVOLUTION__
#include "network/typedefs.hpp"
#include "kernels/rescaling.hpp"
#include "network/rescaling_utils.hpp"
#include "network/utils.hpp"
#include "kernels/macs.hpp"
#include "kernels/activation.hpp"
#include "network/macs.hpp"
#include "network/activation_utils.hpp"
template<int NB_CHANNELS,
......
......@@ -2,7 +2,7 @@
#define __AIDGE_EXPORT_CPP_KERNELS_ELEMWISE__
#include "network/typedefs.hpp"
#include "kernels/activation.hpp"
#include "network/activation_utils.hpp"
// Generic function for two inputs
......
......@@ -2,10 +2,10 @@
#define __AIDGE_EXPORT_CPP_KERNELS_FULLYCONNECTED__
#include "network/typedefs.hpp"
#include "kernels/rescaling.hpp"
#include "network/rescaling_utils.hpp"
#include "network/utils.hpp"
#include "kernels/macs.hpp"
#include "kernels/activation.hpp"
#include "network/macs.hpp"
#include "network/activation_utils.hpp"
template<int NB_CHANNELS,
int CHANNELS_HEIGHT, int CHANNELS_WIDTH,
......
......@@ -2,7 +2,7 @@
#define __AIDGE_EXPORT_CPP_KERNELS_MATMUL__
#include "network/typedefs.hpp"
#include "kernels/activation.hpp"
#include "network/activation_utils.hpp"
// Generic function for matmul and activation
......
#ifndef __AIDGE_EXPORT_CPP_NETWORK_RESCALING__
#define __AIDGE_EXPORT_CPP_NETWORK_RESCALING__
#include "kernels/activation.hpp"
#include "network/rescaling_utils.hpp"
#include "network/activation_utils.hpp"
template<int NB_DATA,
ActivationFunction_T ACTIVATION,
......@@ -23,83 +23,4 @@ void rescaling_forward (
}
}
// ---------------------------------------------------
// ----------------- Saturate Utils ------------------
// ---------------------------------------------------
static int64_t toInt64(uint32_t lo, uint32_t hi) {
return (int64_t) (((uint64_t) hi) << 32ull) | ((uint64_t) lo);
}
static int64_t smlal(int32_t lhs, int32_t rhs,
uint32_t accumLo, uint32_t accumHi)
{
return ((int64_t) lhs) * ((int64_t) rhs) + toInt64(accumLo, accumHi);
}
// ---------------------------------------------------
// --------------- Scaling by Shifting ---------------
// ---------------------------------------------------
template<int SHIFT>
struct SingleShiftScaling {
template<typename Sum_T>
Sum_T operator()(Sum_T weightedSum, size_t /*output*/) const
{
return (SHIFT != 0) ? ((weightedSum >> (SHIFT - 1)) + 1) >> 1 // Rounding
: weightedSum;
}
// // Shift attribute
// static const int mShift = SHIFT;
// static const Scaling_T mScalingType = SingleShift;
// // FP Attribute
// static const int32_t mScaling = 0;
// static const int64_t mFractionalBits = 0;
};
// ---------------------------------------------------
// --------------- Fixed Point Scaling ---------------
// ---------------------------------------------------
template<int64_t SHIFT, int32_t COEF>
struct FixedPointScaling {
template<typename Sum_T>
Sum_T operator()(Sum_T weightedSum, size_t /*output*/) const
{
return smlal(weightedSum, COEF, HALF_LO, HALF_HI) >> SHIFT;
}
// Attributes
static const uint32_t HALF_LO = (SHIFT > 0)
? (1ull << (SHIFT - 1)) & 0xFFFFFFFF : 0;
static const uint32_t HALF_HI = (SHIFT > 0)
? (1ull << (SHIFT - 1)) >> 32u : 0;
// static const int32_t mScaling = SCALING;
// static const int64_t mFractionalBits = FRACTIONAL_BITS;
// static const Scaling_T mScalingType = FixedPoint;
// static const int mShift = 0;
};
// ---------------------------------------------------
// ------------------- No Scaling --------------------
// ---------------------------------------------------
struct NoScaling {
template<typename Sum_T>
Sum_T operator()(Sum_T weightedSum, unsigned int /*output*/) const
{
return weightedSum;
}
};
#endif // __AIDGE_EXPORT_CPP_NETWORK_RESCALING__
......@@ -3,7 +3,6 @@
#include "network/typedefs.hpp"
#include "network/utils.hpp"
#include "kernels/macs.hpp"
#include <type_traits>
#include <cmath>
......
......@@ -50,7 +50,6 @@ class CppActivation(ExportNodeCpp):
# Path to the kernel(s) files to copy
self.add_kernel_to_copy(ROOT / "kernels" / "activation.hpp")
self.add_kernel_to_copy(ROOT / "kernels" / "rescaling.hpp", fwd_include=False)
# Include aidge outputs within the fwd file
if self.attributes["aidge_cmp"]:
......
......@@ -25,9 +25,7 @@ class CppBatchNorm(ExportNodeCpp):
# Path to the kernel(s) files to copy
self.add_kernel_to_copy(ROOT / "kernels" / "batchnorm.hpp")
self.add_kernel_to_copy(ROOT / "kernels" / "macs.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "kernels" / "activation.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "kernels" / "rescaling.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "static" / "macs.hpp", "include/network", fwd_include=False)
# Include aidge outputs within the fwd file
if self.attributes["aidge_cmp"]:
......
......@@ -50,9 +50,7 @@ class CppConv(ExportNodeCpp):
# Path to the kernel(s) files to copy
self.add_kernel_to_copy(ROOT / "kernels" / "convolution.hpp")
self.add_kernel_to_copy(ROOT / "kernels" / "macs.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "kernels" / "activation.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "kernels" / "rescaling.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "static" / "macs.hpp", "include/network", fwd_include=False)
# Include aidge outputs within the fwd file
if self.attributes["aidge_cmp"]:
......
......@@ -72,8 +72,6 @@ class CppElemWise(ExportNodeCpp):
# Path to the kernel(s) files to copy
self.add_kernel_to_copy(ROOT / "kernels" / "elemwise.hpp")
self.add_kernel_to_copy(ROOT / "kernels" / "rescaling.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "kernels" / "activation.hpp", fwd_include=False)
# Include aidge outputs within the fwd file
if self.attributes["aidge_cmp"]:
......
......@@ -48,9 +48,7 @@ class CppFc(ExportNodeCpp):
# Path to the kernel(s) files to copy
self.add_kernel_to_copy(ROOT / "kernels" / "fullyconnected.hpp")
self.add_kernel_to_copy(ROOT / "kernels" / "macs.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "kernels" / "activation.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "kernels" / "rescaling.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "static" / "macs.hpp", "include/network", fwd_include=False)
# Include aidge outputs within the fwd file
if self.attributes["aidge_cmp"]:
......
......@@ -44,7 +44,6 @@ class CppPool(ExportNodeCpp):
# Path to the kernel(s) files to copy
self.add_kernel_to_copy(ROOT / "kernels" / "pooling.hpp")
self.add_kernel_to_copy(ROOT / "kernels" / "activation.hpp", fwd_include=False)
# Include aidge outputs within the fwd file
if self.attributes["aidge_cmp"]:
......
......@@ -48,8 +48,7 @@ class CppRescaling(ExportNodeCpp):
self.include_list = []
# Path to the kernel(s) files to copy
self.add_kernel_to_copy(ROOT / "kernels" / "rescaling.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "kernels" / "activation.hpp", fwd_include=False)
self.add_kernel_to_copy(ROOT / "kernels" / "rescaling.hpp")
# # Include aidge outputs within the fwd file
# if self.attributes["aidge_cmp"]:
......
......@@ -46,7 +46,6 @@ class CppSoftmax(ExportNodeCpp):
# Path to the kernel(s) files to copy
self.add_kernel_to_copy(ROOT / "kernels" / "softmax.hpp")
self.add_kernel_to_copy(ROOT / "kernels" / "macs.hpp", fwd_include=False)
# Include aidge outputs within the fwd file
if self.attributes["aidge_cmp"]:
......
#pragma once
#include <type_traits>
#include "network/typedefs.hpp"
#include "network/utils.hpp"
#include "network/rescaling_utils.hpp"
template<typename Output_T, typename T,
typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
__attribute__((always_inline)) inline
Output_T saturate (T value, int32_t /*sat*/)
{
return value;
}
template<typename Output_T, typename T,
typename std::enable_if<!std::is_floating_point<T>::value>::type* = nullptr>
__attribute__((always_inline)) inline
Output_T saturate (T value, uint32_t sat)
{
if (std::is_unsigned<Output_T>::value) {
return clamp(value, T(0), (T(1) << sat) - 1);
} else {
return clamp(value, -(T(1) << (sat - 1)), (T(1) << (sat - 1)) - 1);
}
}
template<typename Output_T,
typename Sum_T,
typename Rescaling_T>
__attribute__((always_inline)) inline
Output_T activation_forward_value (Sum_T weightedSum,
int output,
ActivationFunction_T func,
const Rescaling_T& __restrict rescaling)
{
switch(func) {
case Linear:
case Saturation: {
break;
}
case Rectifier: {
if(weightedSum <= 0) weightedSum = 0;
break;
}
default:
// Unsupported activation function
break;
}
// Value fixed here for now but it should be generated by
// the export module or determined by the type of Output_T
// For now only works for int8_t and uint8_t
const uint32_t NB_BITS = 8;
return saturate<Output_T>(rescaling(weightedSum, output), NB_BITS);
}
#pragma once
// ---------------------------------------------------
// ----------------- Saturate Utils ------------------
// ---------------------------------------------------
static int64_t toInt64(uint32_t lo, uint32_t hi) {
return (int64_t) (((uint64_t) hi) << 32ull) | ((uint64_t) lo);
}
static int64_t smlal(int32_t lhs, int32_t rhs,
uint32_t accumLo, uint32_t accumHi)
{
return ((int64_t) lhs) * ((int64_t) rhs) + toInt64(accumLo, accumHi);
}
// ---------------------------------------------------
// --------------- Scaling by Shifting ---------------
// ---------------------------------------------------
template<int SHIFT>
struct SingleShiftScaling {
template<typename Sum_T>
Sum_T operator()(Sum_T weightedSum, size_t /*output*/) const
{
return (SHIFT != 0) ? ((weightedSum >> (SHIFT - 1)) + 1) >> 1 // Rounding
: weightedSum;
}
// // Shift attribute
// static const int mShift = SHIFT;
// static const Scaling_T mScalingType = SingleShift;
// // FP Attribute
// static const int32_t mScaling = 0;
// static const int64_t mFractionalBits = 0;
};
// ---------------------------------------------------
// --------------- Fixed Point Scaling ---------------
// ---------------------------------------------------
template<int64_t SHIFT, int32_t COEF>
struct FixedPointScaling {
template<typename Sum_T>
Sum_T operator()(Sum_T weightedSum, size_t /*output*/) const
{
return smlal(weightedSum, COEF, HALF_LO, HALF_HI) >> SHIFT;
}
// Attributes
static const uint32_t HALF_LO = (SHIFT > 0)
? (1ull << (SHIFT - 1)) & 0xFFFFFFFF : 0;
static const uint32_t HALF_HI = (SHIFT > 0)
? (1ull << (SHIFT - 1)) >> 32u : 0;
// static const int32_t mScaling = SCALING;
// static const int64_t mFractionalBits = FRACTIONAL_BITS;
// static const Scaling_T mScalingType = FixedPoint;
// static const int mShift = 0;
};
// ---------------------------------------------------
// ------------------- No Scaling --------------------
// ---------------------------------------------------
struct NoScaling {
template<typename Sum_T>
Sum_T operator()(Sum_T weightedSum, unsigned int /*output*/) const
{
return weightedSum;
}
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment