diff --git a/aidge_export_arm_cortexm/_Aidge_Arm/kernels/Utils/typedefs.h b/aidge_export_arm_cortexm/_Aidge_Arm/kernels/Utils/typedefs.h deleted file mode 100644 index e9d09749a21bb0e2965c7632e16b2b10c395544c..0000000000000000000000000000000000000000 --- a/aidge_export_arm_cortexm/_Aidge_Arm/kernels/Utils/typedefs.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - (C) Copyright 2015 CEA LIST. All Rights Reserved. - Contributor(s): N2D2 Team - - This software is governed by the CeCILL-C license under French law and - abiding by the rules of distribution of free software. You can use, - modify and/ or redistribute the software under the terms of the CeCILL-C - license as circulated by CEA, CNRS and INRIA at the following URL - "http://www.cecill.info". - - As a counterpart to the access to the source code and rights to copy, - modify and redistribute granted by the license, users are provided only - with a limited warranty and the software's author, the holder of the - economic rights, and the successive licensors have only limited - liability. - - The fact that you are presently reading this means that you have had - knowledge of the CeCILL-C license and that you accept its terms. -*/ - -#ifndef __N2D2_TYPEDEFS_H__ -#define __N2D2_TYPEDEFS_H__ - -#include <stdint.h> - -typedef enum { - HWC, - CHW -} Format_T; - -typedef enum { - Logistic, - LogisticWithLoss, - FastSigmoid, - Tanh, - TanhLeCun, - Saturation, - Rectifier, - Linear, - Softplus -} ActivationFunction_T; - -typedef enum { - Max, - Average -} Pooling_T; - -typedef enum { - Sum, - Mult -} OpMode_T; - -typedef enum { - PerLayer, - PerInput, - PerChannel -} CoeffMode_T; - - -#endif // __N2D2_TYPEDEFS_H__ diff --git a/aidge_export_arm_cortexm/_Aidge_Arm/kernels/Utils/typedefs.hpp b/aidge_export_arm_cortexm/_Aidge_Arm/kernels/Utils/typedefs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cf173dc2960ed0a9e5e13dfd1898f975686d2e7e --- /dev/null +++ b/aidge_export_arm_cortexm/_Aidge_Arm/kernels/Utils/typedefs.hpp @@ -0,0 +1,570 @@ +/* + (C) Copyright 2015 CEA LIST. All Rights Reserved. + Contributor(s): N2D2 Team + + This software is governed by the CeCILL-C license under French law and + abiding by the rules of distribution of free software. You can use, + modify and/ or redistribute the software under the terms of the CeCILL-C + license as circulated by CEA, CNRS and INRIA at the following URL + "http://www.cecill.info". + + As a counterpart to the access to the source code and rights to copy, + modify and redistribute granted by the license, users are provided only + with a limited warranty and the software's author, the holder of the + economic rights, and the successive licensors have only limited + liability. + + The fact that you are presently reading this means that you have had + knowledge of the CeCILL-C license and that you accept its terms. +*/ + +#ifndef __N2D2_TYPEDEFS_H__ +#define __N2D2_TYPEDEFS_H__ + +#include <stdint.h> +#include <cmath> +#include <type_traits> +#include <limits> + +typedef enum { + HWC, + CHW +} Format_T; + +typedef enum { + Logistic, + LogisticWithLoss, + FastSigmoid, + Tanh, + TanhLeCun, + Saturation, + Rectifier, + Linear, + Softplus +} ActivationFunction_T; + +typedef enum { + Max, + Average +} Pooling_T; + +typedef enum { + Sum, + Mult +} OpMode_T; + +typedef enum { + PerLayer, + PerInput, + PerChannel +} CoeffMode_T; + + +// ---------------------------------------------------------------------------- +// -------------------- Generic custom bit-width types ------------------------ +// ---------------------------------------------------------------------------- + +template <int BITWIDTH> +struct data {}; + +template <int BITWIDTH> +struct udata{}; + +namespace std { + // Specialization of STL, allows to use std::is_unsigned<> for example. + template <int BITWIDTH> + struct is_integral<data<BITWIDTH>> + : std::is_integral<decltype(data<BITWIDTH>::value)>::type {}; + template <int BITWIDTH> + struct is_integral<udata<BITWIDTH>> + : std::is_integral<decltype(udata<BITWIDTH>::value)>::type {}; + template <int BITWIDTH> + struct is_floating_point<data<BITWIDTH>> + : std::is_floating_point<decltype(data<BITWIDTH>::value)>::type {}; + template <int BITWIDTH> + struct is_unsigned<data<BITWIDTH>> + : std::is_unsigned<decltype(data<BITWIDTH>::value)>::type {}; + template <int BITWIDTH> + struct is_unsigned<udata<BITWIDTH>> + : std::is_unsigned<decltype(udata<BITWIDTH>::value)>::type {}; + + template <int BITWIDTH> + class numeric_limits<data<BITWIDTH>> { + public: + static constexpr int is_integer = (BITWIDTH > 0); + static constexpr int is_signed = true; + static constexpr int digits = std::abs(BITWIDTH); + static constexpr decltype(data<BITWIDTH>::value) min() noexcept + { return (BITWIDTH > 0) ? -(1 << (BITWIDTH - 1)) : + std::numeric_limits<decltype(data<BITWIDTH>::value)>::min(); }; + static constexpr decltype(data<BITWIDTH>::value) lowest() noexcept + { return (BITWIDTH > 0) ? -(1 << (BITWIDTH - 1)) : + std::numeric_limits<decltype(data<BITWIDTH>::value)>::lowest(); }; + static constexpr decltype(data<BITWIDTH>::value) max() noexcept + { return (BITWIDTH > 0) ? ((1 << (BITWIDTH - 1)) - 1) : + std::numeric_limits<decltype(data<BITWIDTH>::value)>::max(); }; + }; + template <int BITWIDTH> + class numeric_limits<udata<BITWIDTH>> { + public: + static constexpr int is_integer = true; + static constexpr int is_signed = false; + static constexpr int digits = BITWIDTH; + static constexpr decltype(data<BITWIDTH>::value) min() noexcept + { return 0; }; + static constexpr decltype(data<BITWIDTH>::value) lowest() noexcept + { return 0; }; + static constexpr decltype(data<BITWIDTH>::value) max() noexcept + { return ((1 << BITWIDTH) - 1); }; + }; +} + + +// ---------------------------------------------------------------------------- +// -------------- Custom bit-width types operator overloading ----------------- +// ---------------------------------------------------------------------------- + +// data +template<int BITWIDTH, typename T> +constexpr data<BITWIDTH>& operator+=(data<BITWIDTH>& d, T rhs) + {d.value += decltype(data<BITWIDTH>::value)(rhs); return d;} + +template<int BITWIDTH, typename T> +constexpr data<BITWIDTH> operator+(data<BITWIDTH> d, T rhs) + {d += rhs; return d;} + +template<int BITWIDTH, typename T> +constexpr data<BITWIDTH>& operator-=(data<BITWIDTH>& d, T rhs) + {d.value -= decltype(data<BITWIDTH>::value)(rhs); return d;} + +template<int BITWIDTH, typename T> +constexpr data<BITWIDTH> operator-(data<BITWIDTH> d, T rhs) + {d -= rhs; return d;} + +template<int BITWIDTH, typename T> +constexpr data<BITWIDTH>& operator*=(data<BITWIDTH>& d, T rhs) + {d.value *= decltype(data<BITWIDTH>::value)(rhs); return d;} + +template<int BITWIDTH, typename T> +constexpr data<BITWIDTH> operator*(data<BITWIDTH> d, T rhs) + {d *= rhs; return d;} + +template<int BITWIDTH, typename T> +constexpr data<BITWIDTH>& operator/=(data<BITWIDTH>& d, T rhs) + {d.value /= decltype(data<BITWIDTH>::value)(rhs); return d;} + +template<int BITWIDTH, typename T> +constexpr data<BITWIDTH> operator/(data<BITWIDTH> d, T rhs) + {d /= rhs; return d;} + + +// udata +template<int BITWIDTH, typename T> +constexpr udata<BITWIDTH>& operator+=(udata<BITWIDTH>& d, T rhs) + {d.value += decltype(udata<BITWIDTH>::value)(rhs); return d;} + +template<int BITWIDTH, typename T> +constexpr udata<BITWIDTH> operator+(udata<BITWIDTH> d, T rhs) + {d += rhs; return d;} + +template<int BITWIDTH, typename T> +constexpr udata<BITWIDTH>& operator-=(udata<BITWIDTH>& d, T rhs) + {d.value -= decltype(udata<BITWIDTH>::value)(rhs); return d;} + +template<int BITWIDTH, typename T> +constexpr udata<BITWIDTH> operator-(udata<BITWIDTH> d, T rhs) + {d -= rhs; return d;} + +template<int BITWIDTH, typename T> +constexpr udata<BITWIDTH>& operator*=(udata<BITWIDTH>& d, T rhs) + {d.value *= decltype(udata<BITWIDTH>::value)(rhs); return d;} + +template<int BITWIDTH, typename T> +constexpr udata<BITWIDTH> operator*(udata<BITWIDTH> d, T rhs) + {d *= rhs; return d;} + +template<int BITWIDTH, typename T> +constexpr udata<BITWIDTH>& operator/=(udata<BITWIDTH>& d, T rhs) + {d.value /= decltype(udata<BITWIDTH>::value)(rhs); return d;} + +template<int BITWIDTH, typename T> +constexpr udata<BITWIDTH> operator/(udata<BITWIDTH> d, T rhs) + {d /= rhs; return d;} + + +// ---------------------------------------------------------------------------- +// ---------------- Custom bit-width types specializations -------------------- +// ---------------------------------------------------------------------------- + +// Data structure for double +template <> +struct data<-64> +{ + data<-64>() = default; + constexpr data<-64>(double v): value(v) {}; + constexpr operator double() const { return value; } + union { + double value; + }; +}; + +// Data structure for float +template <> +struct data<-32> +{ + data<-32>() = default; + constexpr data<-32>(float v): value(v) {}; + constexpr operator float() const { return value; } + union { + float value; + }; +}; + +// Data structure for half float +template <> +struct data<-16> +{ + data<-16>() = default; + constexpr data<-16>(float v): value(v) {}; + constexpr operator float() const { return value; } + union { + float value; + }; +}; + +// Data structure for int32 +template <> +struct data<32> +{ + data<32>() = default; + constexpr data<32>(int32_t v): value(v) {}; + constexpr operator int32_t() const { return value; } + union { + int32_t value; + }; +}; + +// Data structure for uint32 +template <> +struct udata<32> +{ + udata<32>() = default; + constexpr udata<32>(uint32_t v): value(v) {}; + constexpr operator uint32_t() const { return value; } + union { + uint32_t value; + }; +}; + +// Data structure for int16 +template <> +struct data<16> +{ + data<16>() = default; + constexpr data<16>(int16_t v): value(v) {}; + constexpr operator int16_t() const { return value; } + union { + int16_t value; + }; +}; + +// Data structure for uint16 +template <> +struct udata<16> +{ + udata<16>() = default; + constexpr udata<16>(uint16_t v): value(v) {}; + constexpr operator uint16_t() const { return value; } + union { + uint16_t value; + }; +}; + +// Data structure for int8 +template <> +struct data<8> +{ + data<8>() = default; + constexpr data<8>(int8_t v): value(v) {}; + constexpr operator int8_t() const { return value; } + union { + int8_t value; + }; +}; + +// Data structure for uint8 +template <> +struct udata<8> +{ + udata<8>() = default; + constexpr udata<8>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + uint8_t value; + }; +}; + +// Data structure for int7 +template <> +struct data<7> +{ + data<7>() = default; + constexpr data<7>(int8_t v): value(v) {}; + constexpr operator int8_t() const { return value; } + union { + int8_t value; + }; +}; + +// Data structure for uint7 +template <> +struct udata<7> +{ + udata<7>() = default; + constexpr udata<7>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + uint8_t value; + }; +}; + +// Data structure for int6 +template <> +struct data<6> +{ + data<6>() = default; + constexpr data<6>(int8_t v): value(v) {}; + constexpr operator int8_t() const { return value; } + union { + int8_t value; + }; +}; + +// Data structure for uint6 +template <> +struct udata<6> +{ + udata<6>() = default; + constexpr udata<6>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + uint8_t value; + }; +}; + +// Data structure for int5 +template <> +struct data<5> +{ + data<5>() = default; + constexpr data<5>(int8_t v): value(v) {}; + constexpr operator int8_t() const { return value; } + union { + int8_t value; + }; +}; + +// Data structure for uint5 +template <> +struct udata<5> +{ + udata<5>() = default; + constexpr udata<5>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + uint8_t value; + }; +}; + +// Data structure for 2 * int4 +template <> +struct data<4> +{ + data<4>() = default; + constexpr data<4>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + int8_t value; + uint8_t uvalue; + struct + { + int8_t op0 : 4; + int8_t op1 : 4; + } fields; + }; +}; + +// Data structure for 2 * uint4 +template <> +struct udata<4> +{ + udata<4>() = default; + constexpr udata<4>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + uint8_t value; + uint8_t uvalue; + struct + { + uint8_t op0 : 4; + uint8_t op1 : 4; + } fields; + }; +}; + +// Data structure for 2 * int3 +template <> +struct data<3> +{ + data<3>() = default; + constexpr data<3>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + int8_t value; + uint8_t uvalue; + struct + { + int8_t op0 : 4; + int8_t op1 : 4; + } fields; + }; +}; + +// Data structure for 2 * uint3 +template <> +struct udata<3> +{ + udata<3>() = default; + constexpr udata<3>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + uint8_t value; + uint8_t uvalue; + struct + { + uint8_t op0 : 4; + uint8_t op1 : 4; + } fields; + }; +}; + +// Data structure for 4 * int2 +template <> +struct data<2> +{ + data<2>() = default; + constexpr data<2>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + int8_t value; + uint8_t uvalue; + struct + { + int8_t op0 : 2; + int8_t op1 : 2; + int8_t op2 : 2; + int8_t op3 : 2; + } fields; + }; +}; + +// Data structure for 4 * uint2 +template <> +struct udata<2> +{ + udata<2>() = default; + constexpr udata<2>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + uint8_t value; + uint8_t uvalue; + struct + { + uint8_t op0 : 2; + uint8_t op1 : 2; + uint8_t op2 : 2; + uint8_t op3 : 2; + } fields; + }; +}; + +// Data structure for 8 * int1 +template <> +struct data<1> +{ + data<1>() = default; + constexpr data<1>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + int8_t value; + uint8_t uvalue; + struct + { + int8_t op0 : 1; + int8_t op1 : 1; + int8_t op2 : 1; + int8_t op3 : 1; + int8_t op4 : 1; + int8_t op5 : 1; + int8_t op6 : 1; + int8_t op7 : 1; + } fields; + }; +}; + +// Data structure for 8 * uint1 +template <> +struct udata<1> +{ + udata<1>() = default; + constexpr udata<1>(uint8_t v): value(v) {}; + constexpr operator uint8_t() const { return value; } + union { + uint8_t value; + uint8_t uvalue; + struct + { + uint8_t op0 : 1; + uint8_t op1 : 1; + uint8_t op2 : 1; + uint8_t op3 : 1; + uint8_t op4 : 1; + uint8_t op5 : 1; + uint8_t op6 : 1; + uint8_t op7 : 1; + } fields; + }; +}; + + +// ---------------------------------------------------------------------------- +// ------------------------- Structures and Unions ---------------------------- +// ---------------------------------------------------------------------------- + +/* Object for compressing the outputs after mac operations */ +typedef struct PackSupport { + uint8_t accumulator; + unsigned int cptAccumulator; +} PackSupport; + +/* Union to access the data<32>/data<8>/data<4>/data<1> types */ +union n2d2_dataword +{ + data<32> word; + data<8> bytes[4]; + data<4> half_bytes[4]; + data<1> bitfields[4]; +}; + +/* Union to access the udata<32>/udata<8>/udata<4>/udata<1> types */ +union n2d2_udataword +{ + udata<32> word; + udata<8> bytes[4]; + udata<4> half_bytes[4]; + udata<1> bitfields[4]; +}; + + + +#endif // __N2D2_TYPEDEFS_H__