diff --git a/include/aidge/operator/ArgMax.hpp b/include/aidge/operator/ArgMax.hpp index bc97e1f5bdd4dcc80857db55b66e9b6bedb1fa62..5057310d30b118ea6e9707e200ec90f020af62c2 100644 --- a/include/aidge/operator/ArgMax.hpp +++ b/include/aidge/operator/ArgMax.hpp @@ -25,29 +25,35 @@ #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" -namespace Aidge { +#define LIST_ARGMAX_ATTR(X) \ + X(Axis, "axis", std::int32_t), \ + X(KeepDims, "keep_dims", bool), \ + X(SelectLastIndex, "select_last_index", bool) \ +namespace Aidge { +/** + * @enum ArgMaxAttr + * @brief Attributes for the ArgMax operation. + * + * - Axis: Specifies the dimension along which the ArgMax operation is performed. + * - KeepDims: Indicates whether reduced dimensions should be kept or removed. + * - SelectLastIndex: Determines whether to select the first or last index in case of ties. + */ enum class ArgMaxAttr { - /** - * @brief Specifies the dimension along which the ArgMax operation is performed. - */ - Axis, - /** - * Indicates whether reduced dimensions should be kept or removed. - */ - KeepDims, - /** - * Determines whether to select the first or last index in case of ties. - */ - SelectLastIndex + GENERATE_LIST_ATTR_ENUM(LIST_ARGMAX_ATTR) }; } // namespace Aidge -/** - * @brief Provides string representations for the ArgMaxAttr enumeration. - */ + namespace { - template <> - const char *const EnumStrings<Aidge::ArgMaxAttr>::data[] = {"axis", "keep_dims", "select_last_index"}; +template <> +struct EnumStrings<Aidge::ArgMaxAttr> { + static const char* const data[]; +}; +/// @brief Provides string representations for the ArgMaxAttr enumeration. +constexpr const char* const EnumStrings<Aidge::ArgMaxAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_ARGMAX_ATTR) +}; + } namespace Aidge { /** @@ -85,9 +91,8 @@ public: private: using Attributes_ = StaticAttributes<ArgMaxAttr, - std::int32_t, - bool, - bool>; + GENERATE_LIST_ATTR_TYPE(LIST_ARGMAX_ATTR) + >; template <ArgMaxAttr e> using attr = typename Attributes_::template attr<e>; /// Pointer to the attribute storage. @@ -190,7 +195,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::ArgMaxAttr>::data; } }; @@ -214,6 +219,6 @@ std::shared_ptr<Node> ArgMax(std::int32_t axis = 0, } // namespace Aidge - +#undef LIST_ARGMAX_ATTR #endif /* AIDGE_CORE_OPERATOR_ARGMAX_H_ */ diff --git a/include/aidge/operator/AvgPooling.hpp b/include/aidge/operator/AvgPooling.hpp index 3c7d943a3ef888c410679e6ae4fe22c65d66d144..505a0639851245e4f66a7ccf4456d5a30dd55da3 100644 --- a/include/aidge/operator/AvgPooling.hpp +++ b/include/aidge/operator/AvgPooling.hpp @@ -23,42 +23,45 @@ #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" +#define LIST_AVGPOOLING_ATTR(X) \ + X(KernelDims, "kernel_dims", sizeArr_t<DIM>), \ + X(StrideDims, "stride_dims", sizeArr_t<DIM>), \ + X(Dilations, "dilations", sizeArr_t<DIM>), \ + X(CeilMode, "ceil_mode", bool) + namespace Aidge { + /** - * @brief Attributes specific to the AvgPooling operation. + * @enum Attr + * @brief Attributes defining the configuration of a MaxPooling Operator. + * + * - **KernelDims**: Kernel dimensions specifying the size of the pooling window for each spatial dimension. + * Must be an array of positive integers. Common examples include [2,2] or [3,3]. + * - **StrideDims**: Stride dimensions for sliding the pooling window across the input. + * The stride specifies how much the window moves after each operation. + * Must be an array of positive integers. For example, [1,1] or [2,2]. + * - **Dilations**: Dilation along each spatial axis. Default value is 1 for all axes. + * Must be an array of positive integers. For example, [1,1]. + * - **CeilMode**: Flag indicating whether to use ceil or floor when calculating output size. + * - `true`: Use `ceil` for output size calculation. + * - `false`: Use `floor` for output size calculation. */ enum class AvgPoolingAttr { - /** - * @brief Kernel dimensions for the pooling operation. - * Specifies the size of the pooling window along each spatial dimension. - */ - KernelDims, - /** - * @brief Stride dimensions for sliding the pooling window. - * Specifies the step size of the sliding window along each spatial dimension. - */ - StrideDims, - /** - * @brief Dilation along each spatial axis. Default value is 1. - */ - Dilations, - /** - * @brief Flag indicating whether to use ceil or floor when calculating output size. - * - `true`: Use `ceil` for output size calculation. - * - `false`: Use `floor` for output size calculation. - */ - CeilMode + GENERATE_LIST_ATTR_ENUM(LIST_AVGPOOLING_ATTR) }; } // namespace Aidge + namespace { - /** - * @brief String representation of the AvgPooling attributes. - */ - template <> - const char *const EnumStrings<Aidge::AvgPoolingAttr>::data[] = { - "kernel_dims", "stride_dims", "dilations", "ceil_mode" - }; +template <> +struct EnumStrings<Aidge::AvgPoolingAttr> { + static const char* const data[]; +}; +/// @brief String representation of the AvgPooling attributes. +constexpr const char* const EnumStrings<Aidge::AvgPoolingAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_AVGPOOLING_ATTR) +}; } + namespace Aidge { /** * @brief Class representing an Average Pooling operation. @@ -104,10 +107,8 @@ private: * @brief Static attributes representing kernel and stride dimensions. */ using Attributes_ = StaticAttributes<AvgPoolingAttr, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - bool>; + GENERATE_LIST_ATTR_TYPE(LIST_AVGPOOLING_ATTR) + >; template <AvgPoolingAttr e> using attr = typename Attributes_::template attr<e>; @@ -238,7 +239,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::AvgPoolingAttr>::data; } }; @@ -290,4 +291,6 @@ extern template class Aidge::AvgPooling_Op<2>; extern template class Aidge::AvgPooling_Op<3>; extern template class Aidge::AvgPooling_Op<4>; +#undef LIST_AVGPOOLING_ATTR + #endif /* AIDGE_CORE_OPERATOR_AVGPOOLING_H_ */ diff --git a/include/aidge/operator/BatchNorm.hpp b/include/aidge/operator/BatchNorm.hpp index 3521c9b16dcbbf73b0c3c4aea9d93047dc0a2f61..81a679502c3ba74747fc7d7612293d4af46acc4f 100644 --- a/include/aidge/operator/BatchNorm.hpp +++ b/include/aidge/operator/BatchNorm.hpp @@ -22,39 +22,39 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" -namespace Aidge { +#define LIST_BATCHNORM_ATTR(X) \ + X(Epsilon, "epsilon", float), \ + X(Momentum, "momentum", float), \ + X(TrainingMode, "training_mode", bool) +namespace Aidge { +/** + * @enum BatchNormAttr + * @brief Attributes for the Batch Normalization operation. + * + * - Epsilon: A small value added to the denominator to ensure numerical stability and avoid division by zero. + * - Momentum: Controls the weighting of past running averages in batch normalization statistics. + * - `0.0`: Full reliance on current batch statistics. + * - `1.0`: Complete reliance on the previous moving average. + * - TrainingMode: Determines whether the operator is in training mode. + * - `true`: Uses the current batch statistics for normalization. + * - `false`: Uses moving average statistics accumulated during training. + */ enum class BatchNormAttr { - /** - * @brief Epsilon value to avoid division by zero during normalization. - * - * A small value added to the denominator during normalization to ensure numerical stability. - * Commonly used in batch normalization to avoid very small variance values. - */ - Epsilon, - - /** - * @brief Momentum factor for the moving average of batch statistics. - * - * Controls the weighting of past running averages in the batch normalization statistics. - * - `0.0`: Full reliance on current batch statistics. - * - `1.0`: Complete reliance on the previous moving average. - */ - Momentum, - - /** - * @brief Flag indicating whether the operator is in training mode. - * - * - `true`: Uses the current batch statistics for normalization. - * - `false`: Uses moving average statistics accumulated during training. - */ - TrainingMode + GENERATE_LIST_ATTR_ENUM(LIST_BATCHNORM_ATTR) }; } // namespace Aidge + namespace { - template <> - const char *const EnumStrings<Aidge::BatchNormAttr>::data[] = { "epsilon", "momentum", "training_mode" }; +template <> +struct EnumStrings<Aidge::BatchNormAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::BatchNormAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_BATCHNORM_ATTR) +}; } + namespace Aidge { /** * @class BatchNorm_Op @@ -83,8 +83,9 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<BatchNormAttr, float, float, bool>; - + using Attributes_ = StaticAttributes<BatchNormAttr, + GENERATE_LIST_ATTR_TYPE(LIST_BATCHNORM_ATTR) + >; template <BatchNormAttr e> using attr = typename Attributes_::template attr<e>; @@ -162,7 +163,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::BatchNormAttr>::data; } }; @@ -183,4 +184,6 @@ extern template std::shared_ptr<Aidge::Node> Aidge::BatchNorm<2>(const DimSize_t extern template std::shared_ptr<Aidge::Node> Aidge::BatchNorm<3>(const DimSize_t, const float, const float, const bool, const std::string&); extern template std::shared_ptr<Aidge::Node> Aidge::BatchNorm<4>(const DimSize_t, const float, const float, const bool, const std::string&); +#undef LIST_BATCHNORM_ATTR + #endif /* AIDGE_CORE_OPERATOR_BATCHNORM_H_ */ diff --git a/include/aidge/operator/BitShift.hpp b/include/aidge/operator/BitShift.hpp index 3e9f8c3f22728afc4fae7abf5f60adc13c89ac76..c54d6a99fc2f945a02396af446d356004e94efc1 100644 --- a/include/aidge/operator/BitShift.hpp +++ b/include/aidge/operator/BitShift.hpp @@ -23,23 +23,25 @@ #include "aidge/utils/Types.h" #include "aidge/utils/StaticAttributes.hpp" -namespace Aidge { - +#define LIST_BITSHIFT_ATTR(X) X(BitShiftdirection, "bit_shift_direction", BitShiftDirection) +namespace Aidge { enum class BitShiftAttr { - /** - * - */ - BitShiftdirection + GENERATE_LIST_ATTR_ENUM(LIST_BITSHIFT_ATTR) }; -} +} // namespace Aidge + namespace { - /** - * @brief Specialization of `EnumStrings` for `BitShiftAttr`. - */ - template <> - const char* const EnumStrings<Aidge::BitShiftAttr>::data[] = {"bit_shift_direction"}; +/// @brief Specialization of `EnumStrings` for `BitShiftAttr`. +template <> +struct EnumStrings<Aidge::BitShiftAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::BitShiftAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_BITSHIFT_ATTR) +}; } + namespace Aidge { /** * @class BitShift_Op @@ -71,7 +73,9 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<BitShiftAttr, BitShiftDirection>; + using Attributes_ = StaticAttributes<BitShiftAttr, + GENERATE_LIST_ATTR_TYPE(LIST_BITSHIFT_ATTR) + >; template <BitShiftAttr e> using attr = typename Attributes_::template attr<e>; @@ -160,7 +164,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::BitShiftAttr>::data; } }; @@ -177,6 +181,6 @@ inline std::shared_ptr<Node> BitShift(const BitShift_Op::BitShiftDirection direc } // namespace Aidge - +#undef LIST_BITSHIFT_ATTR #endif /* AIDGE_CORE_OPERATOR_BITSHIFT_H_ */ diff --git a/include/aidge/operator/Cast.hpp b/include/aidge/operator/Cast.hpp index b2ffbb553ce44f66f371a65f35340193bf04dab4..f003e30c30ce8bfa7a33d65b75bb83fc8ec17d93 100644 --- a/include/aidge/operator/Cast.hpp +++ b/include/aidge/operator/Cast.hpp @@ -30,20 +30,28 @@ public: void forward() override; }; +#define LIST_CAST_ATTR(X) \ + X(TargetType, "target_type", DataType) + /** * @enum CastAttr * @brief Enum class defining the attributes for the Cast operator. + * + * - TargetType: Specifies the target data type for the cast operation. */ enum class CastAttr { - /** - * @brief Target data type for the cast operation. - */ - TargetType + GENERATE_LIST_ATTR_ENUM(LIST_CAST_ATTR) }; } // namespace Aidge + namespace { - template <> - const char* const EnumStrings<Aidge::CastAttr>::data[] = { "target_type" }; +template <> +struct EnumStrings<Aidge::CastAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::CastAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_CAST_ATTR) +}; } namespace Aidge { /** @@ -67,7 +75,9 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<CastAttr, DataType>; + using Attributes_ = StaticAttributes<CastAttr, + GENERATE_LIST_ATTR_TYPE(LIST_CAST_ATTR) + >; template <CastAttr e> using attr = typename Attributes_::template attr<e>; @@ -147,7 +157,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::CastAttr>::data; } }; @@ -162,4 +172,6 @@ std::shared_ptr<Node> Cast(const DataType targetType, const std::string& name = } // namespace Aidge +#undef LIST_CAST_ATTR + #endif /* AIDGE_CORE_OPERATOR_CAST_H_ */ diff --git a/include/aidge/operator/Clip.hpp b/include/aidge/operator/Clip.hpp index 51ecb6eb36591c2e22ea47ba529b87d125c92a65..4d5d2a93c3434c53b48d718b0b908edc3f402dcb 100644 --- a/include/aidge/operator/Clip.hpp +++ b/include/aidge/operator/Clip.hpp @@ -23,23 +23,32 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" -namespace Aidge { +#define LIST_CLIP_ATTR(X) \ + X(Min, "min", float), \ + X(Max, "max", float) + +namespace Aidge { /** * @enum ClipAttr * @brief Enum class defining the attributes for the Clip operator. + * + * - Min: Minimum value for clipping. + * - Max: Maximum value for clipping. */ enum class ClipAttr { - Min, /**< Minimum value for clipping. */ - Max /**< Maximum value for clipping. */ + GENERATE_LIST_ATTR_ENUM(LIST_CLIP_ATTR) }; -} +} // namespace Aidge + namespace { - /** - * @brief Specialization of EnumStrings for ClipAttr. - */ - template <> - const char* const EnumStrings<Aidge::ClipAttr>::data[] = { "min", "max" }; +template <> +struct EnumStrings<Aidge::ClipAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ClipAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_CLIP_ATTR) +}; } namespace Aidge { @@ -69,7 +78,9 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<ClipAttr, float, float>; + using Attributes_ = StaticAttributes<ClipAttr, + GENERATE_LIST_ATTR_TYPE(LIST_CLIP_ATTR) + >; template <ClipAttr e> using attr = typename Attributes_::template attr<e>; @@ -162,7 +173,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::ClipAttr>::data; } }; @@ -182,4 +193,6 @@ std::shared_ptr<Aidge::Node> Clip( } // namespace Aidge +#undef LIST_CLIP_ATTR + #endif /* AIDGE_CORE_OPERATOR_CLIP_H_ */ diff --git a/include/aidge/operator/Concat.hpp b/include/aidge/operator/Concat.hpp index 1f8a357a830ef3bf3d945ea488425128ea99d3ed..3e5efb5f9bbdecb248d6fd9ab647469955aa0214 100644 --- a/include/aidge/operator/Concat.hpp +++ b/include/aidge/operator/Concat.hpp @@ -49,25 +49,34 @@ public: */ void forward() override; }; +} // namespace Aidge + +#define LIST_CONCAT_ATTR(X) \ + X(Axis, "axis", std::int32_t) + +namespace Aidge { +/** + * @enum ConcatAttr + * @brief Attributes for the Concat operation. + * + * - Axis: index of dimension along which the input tensors are concatenated. + */ enum class ConcatAttr { - /** - * @brief Axis along which to concat the input tensor. - * - * The specified axis determines the direction of concatenating. - */ - Axis + GENERATE_LIST_ATTR_ENUM(LIST_CONCAT_ATTR) }; -} // namespace Aidge +} // namespace Aidge + namespace { - /** - * @brief Specialization of EnumStrings for ConcatAttr. - */ - template <> - const char* const EnumStrings<Aidge::ConcatAttr>::data[] = { - "axis" - }; +template <> +struct EnumStrings<Aidge::ConcatAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ConcatAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_CONCAT_ATTR) +}; } + namespace Aidge { /** * @class Concat_Op @@ -99,7 +108,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<ConcatAttr, std::int32_t>; + using Attributes_ = StaticAttributes<ConcatAttr, GENERATE_LIST_ATTR_TYPE(LIST_CONCAT_ATTR)>; template <ConcatAttr e> using attr = typename Attributes_::template attr<e>; @@ -184,7 +193,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::ConcatAttr>::data; } }; @@ -200,4 +209,6 @@ std::shared_ptr<Node> Concat(const IOIndex_t nbIn, const std::int32_t axis = 0, } // namespace Aidge +#undef LIST_CONCAT_ATTR + #endif /* AIDGE_CORE_OPERATOR_CONCAT_H_ */ diff --git a/include/aidge/operator/ConstantOfShape.hpp b/include/aidge/operator/ConstantOfShape.hpp index e78fba12ec89be456da0aca25c9bb15e170bdede..886df95a8f2478f84eae1f5548d558b2e5c4649b 100644 --- a/include/aidge/operator/ConstantOfShape.hpp +++ b/include/aidge/operator/ConstantOfShape.hpp @@ -12,41 +12,45 @@ #ifndef AIDGE_CORE_OPERATOR_CONSTANT_OF_SHAPE_H_ #define AIDGE_CORE_OPERATOR_CONSTANT_OF_SHAPE_H_ -#include <cstdint> -#include <cstdlib> -#include <functional> -#include <limits> #include <memory> +#include <functional> +#include <set> #include <string> -#include <vector> -#include "aidge/data/Data.hpp" -#include "aidge/graph/Node.hpp" -#include "aidge/operator/Operator.hpp" +#include "aidge/backend/OperatorImpl.hpp" #include "aidge/data/Tensor.hpp" +#include "aidge/graph/Node.hpp" #include "aidge/operator/OperatorTensor.hpp" -#include "aidge/utils/ErrorHandling.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/utils/StaticAttributes.hpp" -#include "aidge/utils/Types.h" -namespace Aidge { +#define LIST_CONSTANTOFSHAPE_ATTR(X) \ + X(Value, "value", Tensor) + +namespace Aidge { +/** + * @enum ConstantOfShapeAttr + * @brief Attributes for the ConstantOfShape operation. + * + * - Value: A scalar tensor that holds a fixed datatype value to fill the output tensor. + */ enum class ConstantOfShapeAttr { - /** - * @brief value to fill the output tensor with. - * Its a scalar tensor holding a value with a fixed datatype - */ - Value, + GENERATE_LIST_ATTR_ENUM(LIST_CONSTANTOFSHAPE_ATTR) }; -} // namespace Aidge -namespace { - template <> - const char *const EnumStrings<Aidge::ConstantOfShapeAttr>::data[] = {"value"}; - } //namespace +} // namespace Aidge - namespace Aidge { +namespace { +template <> +struct EnumStrings<Aidge::ConstantOfShapeAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ConstantOfShapeAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_CONSTANTOFSHAPE_ATTR) +}; +} +namespace Aidge { /** * @brief This operator's purpose is to generate a tensor of shape given via * input and filled with a given value set via attribute. @@ -62,7 +66,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<ConstantOfShapeAttr, Tensor>; + using Attributes_ = StaticAttributes<ConstantOfShapeAttr, GENERATE_LIST_ATTR_TYPE(LIST_CONSTANTOFSHAPE_ATTR)>; template <ConstantOfShapeAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -119,18 +123,20 @@ public: return mAttributes->template getAttr<ConstantOfShapeAttr::Value>(); } - static const std::vector<std::string> getInputsName() { return {"input"}; } - static const std::vector<std::string> getOutputsName() { - return {"constant_of_shape"}; - } + static const std::vector<std::string> getInputsName() noexcept { + return {"input"}; + } + static const std::vector<std::string> getOutputsName() noexcept { + return {"constant_of_shape"}; + } - /** - * @brief Retrieves the names of the attributes for the operator. - * @return A vector containing the attributes name. - */ - static const char* const* attributesName(){ - return EnumStrings<Aidge::ConstantOfShapeAttr>::data; - } + /** + * @brief Retrieves the names of the attributes for the operator. + * @return A vector containing the attributes name. + */ + static constexpr const char* const* attributesName() noexcept { + return EnumStrings<Aidge::ConstantOfShapeAttr>::data; + } }; // helper with C-style array instead of std::array for kernel_dims to allow @@ -142,5 +148,6 @@ inline std::shared_ptr<Node> ConstantOfShape(const Tensor value = Tensor(0.f), } } // namespace Aidge -#endif // AIDGE_CORE_OPERATOR_CONSTANT_OF_SHAPE_H_ +#undef LIST_CONSTANTOFSHAPE_ATTR +#endif // AIDGE_CORE_OPERATOR_CONSTANT_OF_SHAPE_H_ diff --git a/include/aidge/operator/Conv.hpp b/include/aidge/operator/Conv.hpp index f9c9109282cb90dadfa9b26d6f830faf9fdecd7c..283d0136e50e7c051061acb5274e98368b3d26a2 100644 --- a/include/aidge/operator/Conv.hpp +++ b/include/aidge/operator/Conv.hpp @@ -13,43 +13,37 @@ #define AIDGE_CORE_OPERATOR_CONV_H_ #include <array> -#include <cmath> // std::floor #include <cstddef> // std::size_t #include <string> #include <utility> // std::pair #include <vector> -#include "aidge/data/Tensor.hpp" #include "aidge/graph/Node.hpp" #include "aidge/operator/OperatorTensor.hpp" -#include "aidge/operator/Producer.hpp" #include "aidge/utils/ArrayHelpers.hpp" -#include "aidge/utils/ErrorHandling.hpp" #include "aidge/utils/Registrar.hpp" // SET_IMPL_MACRO #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" -namespace Aidge { +#define LIST_CONV_ATTR(X) \ + X(KernelDims, "kernel_dims", sizeArr_t<DIM>), \ + X(StrideDims, "stride_dims", sizeArr_t<DIM>), \ + X(DilationDims, "dilation_dims", sizeArr_t<DIM>) + +namespace Aidge { /** - * @enum ConvAttr + * @enum Attr * @brief Attributes used for the Convolution operation. + * + * - StrideDims: The stride dimensions. + * - DilationDims: The dilation dimensions. + * - KernelDims: The kernel dimensions. */ enum class ConvAttr { - StrideDims, // The stride dimensions - DilationDims, // The dilation dimensions - KernelDims // The kernel dimensions + GENERATE_LIST_ATTR_ENUM(LIST_CONV_ATTR) }; -} // namespace Aidge -namespace { - template <> - const char *const EnumStrings<Aidge::ConvAttr>::data[] = { - "stride_dims", - "dilation_dims", - "kernel_dims" - }; -} -namespace Aidge { + /** * @class Conv_Op * @brief Convolution operator for performing a multi-dimensional convolution. @@ -85,15 +79,13 @@ class Conv_Op : public OperatorTensor, public: static const std::string Type; -private: - using Attributes_ = StaticAttributes<ConvAttr, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>>; + // Use the external enum so that Aidge::Conv_Op<DIM>::Attr is valid. + using Attr = ConvAttr; - template <ConvAttr e> +private: + using Attributes_ = StaticAttributes<Attr, GENERATE_LIST_ATTR_TYPE(LIST_CONV_ATTR)>; + template <Attr e> using attr = typename Attributes_::template attr<e>; - const std::shared_ptr<Attributes_> mAttributes; public: @@ -110,9 +102,9 @@ public: const std::array<DimSize_t, DIM> &dilationDims = create_array<DimSize_t,DIM>(1)) : OperatorTensor(Type, {InputCategory::Data, InputCategory::Param, InputCategory::OptionalParam}, 1), mAttributes(std::make_shared<Attributes_>( - attr<ConvAttr::StrideDims>(strideDims), - attr<ConvAttr::DilationDims>(dilationDims), - attr<ConvAttr::KernelDims>(kernelDims))) + attr<Attr::StrideDims>(strideDims), + attr<Attr::DilationDims>(dilationDims), + attr<Attr::KernelDims>(kernelDims))) {} /** @@ -168,30 +160,14 @@ public: * @return The number of input channels. * @throws std::runtime_error If the operator has no associated weight tensor. */ - DimSize_t inChannels() const { - if (!getInput(1)) { - AIDGE_THROW_OR_ABORT(std::runtime_error, "Convolution operator has no weight Tensor associated so no specific number of input channel imposed."); - } - - // check format - if(getInput(1)->dataFormat()==Aidge::DataFormat::NHWC) - return getInput(1)->template dims<DIM+2>()[DIM+1]; - // default format is NCHW - return getInput(1)->template dims<DIM+2>()[1]; - } + DimSize_t inChannels() const; /** * @brief Get the number of output channels. * @return The number of output channels. * @throws std::runtime_error If the operator has no associated weight tensor. */ - DimSize_t outChannels() const { - if (!getInput(1)) { - AIDGE_THROW_OR_ABORT(std::runtime_error, "Convolution operator has no weight Tensor associated so no specific number of output channel imposed."); - } - // first weight dimension for both NCHW (Cout,Cin,H,W) and NHWC (Cout,H,W,Cin) data format - return getInput(1)->template dims<DIM+2>()[0]; - } + DimSize_t outChannels() const; /** * @brief Get the attributes of the operator. @@ -203,19 +179,19 @@ public: * @brief Get the stride dimensions. * @return The stride dimensions as a reference. */ - inline std::array<DimSize_t, DIM>& strideDims() const { return mAttributes->template getAttr<ConvAttr::StrideDims>(); } + inline std::array<DimSize_t, DIM>& strideDims() const { return mAttributes->template getAttr<Attr::StrideDims>(); } /** * @brief Get the dilation dimensions. * @return The dilation dimensions as a reference. */ - inline std::array<DimSize_t, DIM>& dilationDims() const { return mAttributes->template getAttr<ConvAttr::DilationDims>(); } + inline std::array<DimSize_t, DIM>& dilationDims() const { return mAttributes->template getAttr<Attr::DilationDims>(); } /** * @brief Get the kernel dimensions. * @return The kernel dimensions as a reference. */ - inline std::array<DimSize_t, DIM>& kernelDims() const { return mAttributes->template getAttr<ConvAttr::KernelDims>(); } + inline std::array<DimSize_t, DIM>& kernelDims() const { return mAttributes->template getAttr<Attr::KernelDims>(); } static const std::vector<std::string> getInputsName(){ return {"data_input", "weight", "bias"}; @@ -229,9 +205,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ - return EnumStrings<Aidge::ConvAttr>::data; - } + static constexpr const char* const* attributesName(); }; /** @@ -266,22 +240,35 @@ std::shared_ptr<Node> Conv(DimSize_t inChannels, * based on the kernel dimensions provided. */ template <DimSize_t DIM> -inline std::shared_ptr<Node> Conv( +std::shared_ptr<Node> Conv( DimSize_t inChannels, DimSize_t outChannels, DimSize_t const (&kernelDims)[DIM], const std::string& name = "", const std::array<DimSize_t, DIM> &strideDims = create_array<DimSize_t,DIM>(1), const std::array<DimSize_t, DIM> &dilationDims = create_array<DimSize_t,DIM>(1), - bool noBias = false) { - static_assert(DIM<=MaxDim,"Too many kernel dimensions required by Conv, not supported"); - return Conv(inChannels, outChannels, to_array(kernelDims), name, strideDims, dilationDims, noBias); -} + bool noBias = false); } // namespace Aidge +namespace { +template <> +struct EnumStrings<Aidge::ConvAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ConvAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_CONV_ATTR) +}; +} + +template <Aidge::DimIdx_t DIM> +constexpr const char* const* Aidge::Conv_Op<DIM>::attributesName() { + return EnumStrings<Aidge::Conv_Op<DIM>::Attr>::data; +} + extern template class Aidge::Conv_Op<1>; extern template class Aidge::Conv_Op<2>; +#undef LIST_CONV_ATTR #endif /* AIDGE_CORE_OPERATOR_CONV_H_ */ diff --git a/include/aidge/operator/ConvDepthWise.hpp b/include/aidge/operator/ConvDepthWise.hpp index b307d67a61cabd416bb96db8558fb6960cd65cc4..341b6f76647059e94613feb0b87dfb3a0187d875 100644 --- a/include/aidge/operator/ConvDepthWise.hpp +++ b/include/aidge/operator/ConvDepthWise.hpp @@ -28,21 +28,35 @@ #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" +#define LIST_CONVDEPTHWISE_ATTR(X) \ + X(KernelDims, "kernel_dims", sizeArr_t<DIM>), \ + X(StrideDims, "stride_dims", sizeArr_t<DIM>), \ + X(DilationDims, "dilation_dims", sizeArr_t<DIM>) + namespace Aidge { +/** + * @enum ConvDepthWiseAttr + * @brief Attributes used for the Convolution operation. + * + * - StrideDims: The stride dimensions. + * - DilationDims: The dilation dimensions. + * - KernelDims: The kernel dimensions. + */ enum class ConvDepthWiseAttr { - StrideDims, // The stride dimensions for the convolution. - DilationDims, // The dilation dimensions for the convolution. - KernelDims // The kernel dimensions for the convolution. + GENERATE_LIST_ATTR_ENUM(LIST_CONVDEPTHWISE_ATTR) }; -} // namespace Aidge +} // namespace Aidge + namespace { - template <> - const char *const EnumStrings<Aidge::ConvDepthWiseAttr>::data[] = { - "stride_dims", - "dilation_dims", - "kernel_dims" - }; +template <> +struct EnumStrings<Aidge::ConvDepthWiseAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ConvDepthWiseAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_CONVDEPTHWISE_ATTR) +}; } + namespace Aidge { /** * @class ConvDepthWise_Op @@ -72,9 +86,8 @@ public: private: using Attributes_ = StaticAttributes<ConvDepthWiseAttr, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>>; + GENERATE_LIST_ATTR_TYPE(LIST_CONVDEPTHWISE_ATTR) + >; template <ConvDepthWiseAttr e> using attr = typename Attributes_::template attr<e>; @@ -203,7 +216,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::ConvDepthWiseAttr>::data; } }; @@ -254,4 +267,6 @@ inline std::shared_ptr<Node> ConvDepthWise( extern template class Aidge::ConvDepthWise_Op<1>; extern template class Aidge::ConvDepthWise_Op<2>; +#undef LIST_CONVDEPTHWISE_ATTR + #endif /* AIDGE_CORE_OPERATOR_CONVDEPTHWISE_H_ */ diff --git a/include/aidge/operator/DepthToSpace.hpp b/include/aidge/operator/DepthToSpace.hpp index c99f7bbb7d882300b7f2f4278dda832189064ad5..7bf6ffdf3ad63986049558374afff642a71fc549 100644 --- a/include/aidge/operator/DepthToSpace.hpp +++ b/include/aidge/operator/DepthToSpace.hpp @@ -42,20 +42,35 @@ public: */ void forward() override; }; +} // namespace Aidge + +#define LIST_DEPTHTOSPACE_ATTR(X) \ + X(BlockSize, "block_size", std::uint32_t), \ + X(Mode, "mode", Aidge::DepthToSpace_Op::Mode) +namespace Aidge { /** * @enum DepthToSpaceAttr * @brief Attributes for the DepthToSpace operation. + * + * - BlockSize: The block size for rearranging depth to spatial dimensions. + * - Mode: The mode for depth-to-space transformation. */ enum class DepthToSpaceAttr { - BlockSize, /**< The block size for rearranging depth to spatial dimensions. */ - Mode /**< The mode for depth-to-space transformation. */ + GENERATE_LIST_ATTR_ENUM(LIST_DEPTHTOSPACE_ATTR) }; -} // namespace Aidge +} // namespace Aidge + namespace { - template <> - const char *const EnumStrings<Aidge::DepthToSpaceAttr>::data[] = { "block_size", "mode" }; +template <> +struct EnumStrings<Aidge::DepthToSpaceAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::DepthToSpaceAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_DEPTHTOSPACE_ATTR) +}; } + namespace Aidge{ /** * @class DepthToSpace_Op @@ -92,7 +107,7 @@ public: enum class Mode { DCR, CRD }; private: - using Attributes_ = StaticAttributes<DepthToSpaceAttr, std::uint32_t, Mode>; + using Attributes_ = StaticAttributes<DepthToSpaceAttr, GENERATE_LIST_ATTR_TYPE(LIST_DEPTHTOSPACE_ATTR)>; template <DepthToSpaceAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -174,7 +189,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::DepthToSpaceAttr>::data; } }; @@ -192,5 +207,6 @@ std::shared_ptr<Node> DepthToSpace(const std::uint32_t blockSize, } // namespace Aidge +#undef LIST_DEPTHTOSPACE_ATTR #endif //AIDGE_CORE_OPERATOR_DEPTHTOSPACE_H_ diff --git a/include/aidge/operator/Flatten.hpp b/include/aidge/operator/Flatten.hpp index b61fc6912dd0e9f61dd2506370c591aae8c3a107..0ccc54eb770421dd726658dfbd4e44ee78f28cfb 100644 --- a/include/aidge/operator/Flatten.hpp +++ b/include/aidge/operator/Flatten.hpp @@ -43,22 +43,33 @@ public: */ void forward() override; }; +} // namespace Aidge + +#define LIST_FLATTEN_ATTR(X) \ + X(Axis, "axis", std::int64_t) +namespace Aidge { /** * @enum FlattenAttr * @brief Defines attributes for the Flatten operator. + * + * - Axis: dimension index at which to flatten the input tensor. */ enum class FlattenAttr { - /** - * @brief The axis at which to flatten the input tensor. - */ - Axis + GENERATE_LIST_ATTR_ENUM(LIST_FLATTEN_ATTR) }; -} // namespace Aidge +} // namespace Aidge + namespace { - template <> - const char *const EnumStrings<Aidge::FlattenAttr>::data[] = { "axis" }; +template <> +struct EnumStrings<Aidge::FlattenAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::FlattenAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_FLATTEN_ATTR) +}; } + namespace Aidge { /** * @brief Description the Flatten operation to reshape a tensor into a 2D matrix. @@ -85,7 +96,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<FlattenAttr, std::int64_t>; + using Attributes_ = StaticAttributes<FlattenAttr, GENERATE_LIST_ATTR_TYPE(LIST_FLATTEN_ATTR)>; template <FlattenAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -165,7 +176,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::FlattenAttr>::data; } }; @@ -184,5 +195,6 @@ std::shared_ptr<Node> Flatten(std::int64_t axis = 1, const std::string &name = ""); } // namespace Aidge +#undef LIST_FLATTEN_ATTR #endif /* AIDGE_CORE_OPERATOR_FLATTEN_H_ */ diff --git a/include/aidge/operator/Fold.hpp b/include/aidge/operator/Fold.hpp index 2f9974e8ed3b1723734a2483616feceace5bec33..9b71057fb20327c7c37d3ac9aa49d021e7c244cc 100644 --- a/include/aidge/operator/Fold.hpp +++ b/include/aidge/operator/Fold.hpp @@ -29,51 +29,37 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" -namespace Aidge { +#define LIST_FOLD_ATTR(X) \ + X(OutputDims, "output_dims", sizeArr_t<DIM>), \ + X(StrideDims, "stride_dims", sizeArr_t<DIM>), \ + X(DilationDims, "dilation_dims", sizeArr_t<DIM>), \ + X(KernelDims, "kernel_dims", sizeArr_t<DIM>) +namespace Aidge { /** * @enum FoldAttr * @brief Enumeration for the attributes of the Fold operation. + * + * - OutputDims: Specifies the shape of the output tensor after applying the fold operation. + * - StrideDims: Step sizes in each dimension during the fold operation. + * - DilationDims: Spacing between elements in the kernel during the fold. + * - KernelDims: Size of the kernel or filter applied during the fold. */ enum class FoldAttr { - /** - * @brief Output dimensions of the fold operation. - * - * Specifies the shape of the output tensor after applying the fold operation. - */ - OutputDims, - - /** - * @brief Stride dimensions used during the fold operation. - * - * Strides are the step sizes in each dimension during the fold operation. - */ - StrideDims, - - /** - * @brief Dilation dimensions for the fold operation. - * - * Dilation is the spacing between elements in the kernel during the fold. - */ - DilationDims, - - /** - * @brief Kernel dimensions used for the fold operation. - * - * Specifies the size of the kernel or filter applied during the fold. - */ - KernelDims + GENERATE_LIST_ATTR_ENUM(LIST_FOLD_ATTR) }; -} // namespace Aidge +} // namespace Aidge + namespace { - template <> - const char* const EnumStrings<Aidge::FoldAttr>::data[] = { - "output_dims", - "stride_dims", - "dilation_dims", - "kernel_dims" - }; +template <> +struct EnumStrings<Aidge::FoldAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::FoldAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_FOLD_ATTR) +}; } + namespace Aidge { /** * @class Fold_Op @@ -112,11 +98,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<FoldAttr, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>>; + using Attributes_ = StaticAttributes<FoldAttr, GENERATE_LIST_ATTR_TYPE(LIST_FOLD_ATTR)>; template <FoldAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -225,7 +207,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::FoldAttr>::data; } }; @@ -265,4 +247,6 @@ extern template class Aidge::Fold_Op<2>; } // namespace Aidge +#undef LIST_FOLD_ATTR + #endif /* AIDGE_CORE_OPERATOR_FOLD_H_ */ diff --git a/include/aidge/operator/Gather.hpp b/include/aidge/operator/Gather.hpp index 86fc7bc7855473c6f73e3bcc36d46ef9b4956446..60bec8d1c571eb7c5be2d99527d233fa2ac53e82 100644 --- a/include/aidge/operator/Gather.hpp +++ b/include/aidge/operator/Gather.hpp @@ -43,29 +43,15 @@ public: */ void forward() override; }; +} // namespace Aidge -enum class GatherAttr { - /** - * @brief Axis along which to gather elements. - */ - Axis, - /** - * @brief Indices specifying which elements to gather. - */ - Indices, +#define LIST_GATHER_ATTR(X) \ + X(Axis, "axis", std::int8_t), \ + X(Indices, "indices", std::vector<int64_t>), \ + X(GatheredShape, "gathered_shape", std::vector<DimSize_t>) - /** - * @brief Shape of the resulting gathered tensor. - */ - GatheredShape -}; -} // namespace Aidge -namespace { - template <> - const char *const EnumStrings<Aidge::GatherAttr>::data[] = {"axis", "indices", "gathered_shape"}; -} namespace Aidge { /** * @brief Description for the Gather operation on an input tensor. @@ -86,13 +72,21 @@ class Gather_Op : public OperatorTensor, public: static const std::string Type; - using Attributes_ = StaticAttributes<GatherAttr, - std::int8_t, - std::vector<int64_t>, - std::vector<DimSize_t>>; + /** + * @enum Attr + * @brief Attributes for the Gather operation. + * + * - Axis: The axis along which to gather elements. + * - Indices: Specifies which elements to gather. + * - GatheredShape: The shape of the resulting gathered tensor. + */ + enum class Attr { + GENERATE_LIST_ATTR_ENUM(LIST_GATHER_ATTR) + }; private: - template <GatherAttr e> + using Attributes_ = StaticAttributes<Attr, GENERATE_LIST_ATTR_TYPE(LIST_GATHER_ATTR)>; + template <Attr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -161,19 +155,19 @@ public: * @brief Get the axis along which elements are gathered. * @return The axis attribute. */ - inline std::int8_t& axis() const { return mAttributes->getAttr<GatherAttr::Axis>(); } + inline std::int8_t& axis() const { return mAttributes->getAttr<Attr::Axis>(); } /** * @brief Get the indices specifying which elements to gather. * @return The indices attribute. */ - inline std::vector<int64_t>& indices() const { return mAttributes->getAttr<GatherAttr::Indices>(); } + inline std::vector<int64_t>& indices() const { return mAttributes->getAttr<Attr::Indices>(); } /** * @brief Get the shape of the gathered tensor. * @return The gathered shape attribute. */ - inline std::vector<DimSize_t>& gatheredShape() const { return mAttributes->getAttr<GatherAttr::GatheredShape>(); } + inline std::vector<DimSize_t>& gatheredShape() const { return mAttributes->getAttr<Attr::GatheredShape>(); } /** * @brief Get the input tensor names. @@ -195,9 +189,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ - return EnumStrings<Aidge::GatherAttr>::data; - } + static constexpr const char* const* attributesName(); }; /** @@ -219,5 +211,20 @@ std::shared_ptr<Node> Gather(std::int8_t axis = 0, } // namespace Aidge +namespace { +template <> +struct EnumStrings<Aidge::Gather_Op::Attr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::Gather_Op::Attr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_GATHER_ATTR) +}; +} + +constexpr const char* const* attributesName() { + return EnumStrings<Aidge::Gather_Op::Attr>::data; +} + +#undef LIST_GATHER_ATTR #endif /* AIDGE_CORE_OPERATOR_GATHER_H_ */ diff --git a/include/aidge/operator/GridSample.hpp b/include/aidge/operator/GridSample.hpp index 06642231152cefe1023688811da0dcdc0bbde859..2388cd0c17339ea50a0ea2f9047c8cdabb08a68e 100644 --- a/include/aidge/operator/GridSample.hpp +++ b/include/aidge/operator/GridSample.hpp @@ -23,21 +23,35 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/logger/EnumString.hpp" +#define LIST_GRIDSAMPLE_ATTR(X) \ + X(Mode, "mode", Mode), \ + X(PaddingMode, "padding_mode", PaddingMode), \ + X(AlignCorners, "align_corners", bool) + namespace Aidge { +/** + * @enum GridSampleAttr + * @brief Attributes for the GridSample operation. + * + * - Mode: Specifies the interpolation mode (e.g., Linear, Nearest, Cubic). + * - PaddingMode: Specifies how to handle out-of-boundary grid values. + * - AlignCorners: Determines whether grid values are normalized to align with the image corners. + */ enum class GridSampleAttr { - Mode, // Specifies the interpolation mode (e.g., Linear, Nearest, Cubic). - PaddingMode, // Specifies how to handle out-of-boundary grid values. - AlignCorners // Determines whether grid values are normalized to align with the image corners. + GENERATE_LIST_ATTR_ENUM(LIST_GRIDSAMPLE_ATTR) }; -} // namespace Aidge +} // namespace Aidge + namespace { - template <> - const char* const EnumStrings<Aidge::GridSampleAttr>::data[] = { - "mode", - "padding_mode", - "align_corners" - }; +template <> +struct EnumStrings<Aidge::GridSampleAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::GridSampleAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_GRIDSAMPLE_ATTR) +}; } + namespace Aidge { /** @@ -88,7 +102,7 @@ public: enum class PaddingMode { Zeros, Border, Reflection }; private: - using Attributes_ = StaticAttributes<GridSampleAttr, Mode, PaddingMode, bool>; + using Attributes_ = StaticAttributes<GridSampleAttr, GENERATE_LIST_ATTR_TYPE(LIST_GRIDSAMPLE_ATTR)>; template <GridSampleAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -185,7 +199,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::GridSampleAttr>::data; } }; @@ -207,4 +221,6 @@ std::shared_ptr<Node> GridSample( } // namespace Aidge +#undef LIST_GRIDSAMPLE_ATTR + #endif /* AIDGE_CORE_OPERATOR_GRIDSAMPLE_H_ */ diff --git a/include/aidge/operator/Heaviside.hpp b/include/aidge/operator/Heaviside.hpp index 806ed47f3db5f78b5636f7f14876f852ea22b341..49f9059033b2816b594802b1fcfaa4340418f883 100644 --- a/include/aidge/operator/Heaviside.hpp +++ b/include/aidge/operator/Heaviside.hpp @@ -24,23 +24,10 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" -namespace Aidge { -enum class HeavisideAttr { - /** - * @brief The value used in the output tensor when the input is 0. - */ - Value -}; -} // namespace Aidge -namespace { - /** - * @brief Define string representations for Heaviside attributes. - */ - template <> - const char *const EnumStrings<Aidge::HeavisideAttr>::data[] = {"value"}; -} -namespace Aidge { +#define LIST_HEAVISIDE_ATTR(X) \ + X(Value, "value", float) +namespace Aidge { /** * @class Heaviside_Op * @brief Implements the Heaviside step function operation. @@ -59,18 +46,26 @@ namespace Aidge { class Heaviside_Op : public OperatorTensor, public Registrable<Heaviside_Op, std::string, std::function<std::shared_ptr<OperatorImpl>(const Heaviside_Op &)>> { +public: + static const std::string Type; -private: - using Attributes_ = StaticAttributes<HeavisideAttr, float>; + /** + * @enum Attr + * @brief Attributes for the Heaviside operation. + * + * - Value: The value used in the output tensor when the input is 0. + */ + enum class Attr { + GENERATE_LIST_ATTR_ENUM(LIST_HEAVISIDE_ATTR) + }; - template <HeavisideAttr e> +private: + using Attributes_ = StaticAttributes<Attr, GENERATE_LIST_ATTR_TYPE(LIST_HEAVISIDE_ATTR)>; + template <Attr e> using attr = typename Attributes_::template attr<e>; - const std::shared_ptr<Attributes_> mAttributes; public: - static const std::string Type; - /** * @brief Constructor for the Heaviside operator. * @param[in] value The value to use in the output tensor when the input is 0. @@ -123,9 +118,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ - return EnumStrings<Aidge::HeavisideAttr>::data; - } + static constexpr const char* const* attributesName(); /** * @brief Get the attributes of the operator. @@ -139,7 +132,7 @@ public: * @return A reference to the value attribute. */ inline float &value() const { - return mAttributes->template getAttr<HeavisideAttr::Value>(); + return mAttributes->template getAttr<Attr::Value>(); } }; @@ -158,5 +151,20 @@ std::shared_ptr<Node> Heaviside(float value, const std::string &name = ""); } // namespace Aidge +namespace { +template <> +struct EnumStrings<Aidge::Heaviside_Op::Attr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::Heaviside_Op::Attr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_HEAVISIDE_ATTR) +}; +} + +constexpr const char* const* Aidge::Heaviside_Op::attributesName() { + return EnumStrings<Aidge::Heaviside_Op::Attr>::data; +} + +#undef LIST_HEAVISIDE_ATTR #endif /* AIDGE_CORE_OPERATOR_HEAVISIDE_H_ */ diff --git a/include/aidge/operator/LRN.hpp b/include/aidge/operator/LRN.hpp index 6c82b6b4670cff44e9d21aeabe8f64aa2b2e2397..b1cbc143dd592271ebb982a81eb9350b0ea04a70 100644 --- a/include/aidge/operator/LRN.hpp +++ b/include/aidge/operator/LRN.hpp @@ -23,21 +23,12 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" -namespace Aidge { -enum class LRNAttr { - Alpha, ///< Scale factor for normalization. - Beta, ///< Exponent applied to the normalization term. - Bias, ///< Constant bias added to the normalization term. - Size ///< Number of channels to normalize over. -}; -} // namespace Aidge -namespace { - /** - * @brief EnumStrings specialization for LRNAttr. - */ - template <> - const char *const EnumStrings<Aidge::LRNAttr>::data[] = {"alpha", "beta", "bias", "size", nullptr}; -} +#define LIST_LRN_ATTR(X) \ + X(Alpha, "alpha", float), \ + X(Beta, "beta", float), \ + X(Bias, "bias", float), \ + X(Size, "size", std::int32_t) + namespace Aidge { /** * @brief Description of a Local Response Normalization (LRN) operation on an input Tensor. @@ -77,9 +68,22 @@ public: */ static const std::string Type; + /** + * @enum Attr + * @brief Attributes for the Local Response Normalization (LRN) operation. + * + * - Alpha: Scale factor for normalization. + * - Beta: Exponent applied to the normalization term. + * - Bias: Constant bias added to the normalization term. + * - Size: Number of channels to normalize over. + */ + enum class Attr { + GENERATE_LIST_ATTR_ENUM(LIST_LRN_ATTR) + }; + private: - using Attributes_ = StaticAttributes<LRNAttr, float, float, float, std::int32_t>; - template <LRNAttr e> using attr = typename Attributes_::template attr<e>; + using Attributes_ = StaticAttributes<Attr, GENERATE_LIST_ATTR_TYPE(LIST_LRN_ATTR)>; + template <Attr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; public: @@ -131,25 +135,25 @@ public: * @brief Get or modify the `alpha` attribute. * @return Reference to the `alpha` attribute. */ - inline float& alpha() const noexcept { return mAttributes->getAttr<LRNAttr::Alpha>(); } + inline float& alpha() const noexcept { return mAttributes->getAttr<Attr::Alpha>(); } /** * @brief Get or modify the `beta` attribute. * @return Reference to the `beta` attribute. */ - inline float& beta() const noexcept { return mAttributes->getAttr<LRNAttr::Beta>(); } + inline float& beta() const noexcept { return mAttributes->getAttr<Attr::Beta>(); } /** * @brief Get or modify the `bias` attribute. * @return Reference to the `bias` attribute. */ - inline float& bias() const noexcept { return mAttributes->getAttr<LRNAttr::Bias>(); } + inline float& bias() const noexcept { return mAttributes->getAttr<Attr::Bias>(); } /** * @brief Get or modify the `size` attribute. * @return Reference to the `size` attribute. */ - inline std::int32_t& size() const noexcept { return mAttributes->getAttr<LRNAttr::Size>(); } + inline std::int32_t& size() const noexcept { return mAttributes->getAttr<Attr::Size>(); } /** * @brief Get the input tensor names for the LRN operator. @@ -171,9 +175,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ - return EnumStrings<Aidge::LRNAttr>::data; - } + static constexpr const char* const* attributesName(); }; /** @@ -187,4 +189,20 @@ std::shared_ptr<Node> LRN(std::int32_t size, const std::string& name = ""); } // namespace Aidge +namespace { +template <> +struct EnumStrings<Aidge::LRN_Op::Attr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::LRN_Op::Attr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_LRN_ATTR) +}; +} + +constexpr const char* const* Aidge::LRN_Op::attributesName() { + return EnumStrings<Aidge::LRN_Op::Attr>::data; +} + +#undef LIST_LRN_ATTR + #endif /* AIDGE_CORE_OPERATOR_LRN_H_ */ diff --git a/include/aidge/operator/LeakyReLU.hpp b/include/aidge/operator/LeakyReLU.hpp index acf9bae7f4955fee09699f27b7a23c06ce3d670e..867f324d3044cdc8ebd440dfebd5547f6936f47f 100644 --- a/include/aidge/operator/LeakyReLU.hpp +++ b/include/aidge/operator/LeakyReLU.hpp @@ -23,19 +23,9 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" -namespace Aidge { -enum class LeakyReLUAttr { - /** - * @brief Slope for the negative input values. - */ - NegativeSlope -}; -} // namespace Aidge -namespace { - template <> - const char* const EnumStrings<Aidge::LeakyReLUAttr>::data[] - = {"negative_slope"}; - } +#define LIST_LEAKYRELU_ATTR(X) \ + X(NegativeSlope, "negative_slope", float) + namespace Aidge{ /** * @class LeakyReLU_Op @@ -57,9 +47,19 @@ class LeakyReLU_Op : public OperatorTensor, public: static const std::string Type; + /** + * @enum LeakyReLUAttr + * @brief Attributes for the LeakyReLU operation. + * + * - NegativeSlope: Slope for the negative input values. + */ + enum class Attr { + GENERATE_LIST_ATTR_ENUM(LIST_LEAKYRELU_ATTR) + }; + private: - using Attributes_ = StaticAttributes<LeakyReLUAttr, float>; - template <LeakyReLUAttr e> using attr = typename Attributes_::template attr<e>; + using Attributes_ = StaticAttributes<Attr, GENERATE_LIST_ATTR_TYPE(LIST_LEAKYRELU_ATTR)>; + template <Attr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; public: @@ -77,7 +77,7 @@ public: : OperatorTensor(Type, {InputCategory::Data}, 1), mAttributes( std::make_shared<Attributes_>( - attr<LeakyReLUAttr::NegativeSlope>(negativeSlope))) + attr<Attr::NegativeSlope>(negativeSlope))) {} /** @@ -104,7 +104,7 @@ public: /** * @brief Get the negative slope value. */ - inline float& negativeSlope() const noexcept { return mAttributes -> getAttr<LeakyReLUAttr::NegativeSlope>(); } + inline float& negativeSlope() const noexcept { return mAttributes -> getAttr<Attr::NegativeSlope>(); } /** * @brief Get the names of the input tensors. @@ -126,9 +126,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ - return EnumStrings<Aidge::LeakyReLUAttr>::data; - } + static constexpr const char* const* attributesName(); }; /** @@ -139,6 +137,22 @@ public: * @return std::shared_ptr<Node> Node containing the Operator. */ std::shared_ptr<Node> LeakyReLU(float negativeSlope = 0.0f, const std::string& name = ""); +} // namespace Aidge + +namespace { +template <> +struct EnumStrings<Aidge::LeakyReLU_Op::Attr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::LeakyReLU_Op::Attr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_LEAKYRELU_ATTR) +}; +} + +constexpr const char* const* Aidge::LeakyReLU_Op::attributesName() { + return EnumStrings<Attr>::data; } +#undef LIST_LEAKYRELU_ATTR + #endif /* AIDGE_CORE_OPERATOR_LEAKYRELU_H_ */ diff --git a/include/aidge/operator/MaxPooling.hpp b/include/aidge/operator/MaxPooling.hpp index 94c786c312d214ea2ff189e1410cfa8841b8f403..01104262147dc461259c3de17e3b3ec3383328b4 100644 --- a/include/aidge/operator/MaxPooling.hpp +++ b/include/aidge/operator/MaxPooling.hpp @@ -28,47 +28,47 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" +// Define the X‑macro list with three parameters: name, string, and type. + +#define LIST_MAXPOOLING_ATTR(X) \ + X(KernelDims, "kernel_dims", sizeArr_t<DIM>), \ + X(StrideDims, "stride_dims", sizeArr_t<DIM>), \ + X(Dilations, "dilations", sizeArr_t<DIM>), \ + X(CeilMode, "ceil_mode", bool) + namespace Aidge { /** - * @enum MaxPoolingAttr + * @enum Attr * @brief Attributes defining the configuration of a MaxPooling Operator. + * + * - **KernelDims**: Kernel dimensions specifying the size of the pooling window for each spatial dimension. + * Must be an array of positive integers. Common examples include [2,2] or [3,3]. + * - **StrideDims**: Stride dimensions for sliding the pooling window across the input. + * The stride specifies how much the window moves after each operation. + * Must be an array of positive integers. For example, [1,1] or [2,2]. + * - **Dilations**: Dilation along each spatial axis. Default value is 1 for all axes. + * Must be an array of positive integers. For example, [1,1]. + * - **CeilMode**: Flag indicating whether to use ceil or floor when calculating output size. + * - `true`: Use `ceil` for output size calculation. + * - `false`: Use `floor` for output size calculation. */ enum class MaxPoolingAttr { - /** - * @brief Kernel dimensions specifying the size of the pooling window for each spatial dimension. - * Must be an array of positive integers. Common examples include [2,2] or [3,3]. - */ - KernelDims, - /** - * @brief Stride dimensions for sliding the pooling window across the input dimensions. - * The stride specifies how much the window moves after each operation. - * Must be an array of positive integers. For example, [1,1] or [2,2]. - */ - StrideDims, - /** - * @brief Dilation along each spatial axis. Default value is 1 for all axes. - * Must be an array of positive integers. For example, [1,1]. - */ - Dilations, - /** - * @brief Flag indicating whether to use ceil or floor when calculating output size. - * - `true`: Use `ceil` for output size calculation. - * - `false`: Use `floor` for output size calculation. - */ - CeilMode, + GENERATE_LIST_ATTR_ENUM(LIST_MAXPOOLING_ATTR) }; } // namespace Aidge -namespace { - /** - * @brief String representations of MaxPooling attributes for debugging and logging. - */ - template <> - const char *const EnumStrings<Aidge::MaxPoolingAttr>::data[] = {"kernel_dims", "stride_dims", "dilations", "ceil_mode"}; - } -namespace Aidge{ +namespace { +template <> +struct EnumStrings<Aidge::MaxPoolingAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::MaxPoolingAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_MAXPOOLING_ATTR) +}; +} +namespace Aidge { /** * @class MaxPooling_Op * @tparam DIM Dimensionality of the input tensor (e.g., 1D, 2D, 3D). @@ -108,10 +108,8 @@ public: private: using Attributes_ = StaticAttributes<MaxPoolingAttr, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - bool>; + GENERATE_LIST_ATTR_TYPE(LIST_MAXPOOLING_ATTR) + >; template <MaxPoolingAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; ///< Shared pointer to operator attributes. @@ -211,7 +209,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::MaxPoolingAttr>::data; } }; @@ -263,5 +261,6 @@ inline std::shared_ptr<Node> MaxPooling( } // namespace Aidge +#undef LIST_MAXPOOLING_ATTR #endif /* AIDGE_CORE_OPERATOR_MAXPOOLING_H_ */ diff --git a/include/aidge/operator/Memorize.hpp b/include/aidge/operator/Memorize.hpp index 59df17ec146bb33dc1e6e8c007eb275054fd727b..e1eea4a284f494553708fa56f99477162eab93ab 100644 --- a/include/aidge/operator/Memorize.hpp +++ b/include/aidge/operator/Memorize.hpp @@ -114,24 +114,13 @@ public: */ void forward() override; }; - -enum class MemorizeAttr { - ScheduleStep, // Defines the step interval for scheduling memory updates. - ForwardStep, // Tracks the current step in the forward pass. - EndStep // The final step for which memory updates will occur. -}; } // namespace Aidge -namespace { - /** - * @brief String representations of the Memorize operator's attributes. - */ - template <> - const char *const EnumStrings<Aidge::MemorizeAttr>::data[] = { - "schedule_step", - "forward_step", - "end_step" - }; -} + +#define LIST_MEMORIZE_ATTR(X) \ + X(ScheduleStep, "schedule_step", std::uint32_t), \ + X(ForwardStep, "forward_step", std::uint32_t), \ + X(EndStep, "end_step", std::uint32_t) + namespace Aidge { /** * @class Memorize_Op @@ -155,9 +144,21 @@ class Memorize_Op : public OperatorTensor, public: static const std::string Type; + /** + * @enum Attr + * @brief Attributes for the Memorize operation. + * + * - ScheduleStep: Defines the step interval for scheduling memory updates. + * - ForwardStep: Tracks the current step in the forward pass. + * - EndStep: The final step for which memory updates will occur. + */ + enum class Attr { + GENERATE_LIST_ATTR_ENUM(LIST_MEMORIZE_ATTR) + }; + private: - using Attributes_ = StaticAttributes<MemorizeAttr, std::uint32_t, std::uint32_t, std::uint32_t>; - template <MemorizeAttr e> + using Attributes_ = StaticAttributes<Attr, GENERATE_LIST_ATTR_TYPE(LIST_MEMORIZE_ATTR)>; + template <Attr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -223,19 +224,19 @@ public: * @brief Get or set the scheduling step for the operator. * @return A reference to the scheduling step. */ - inline std::uint32_t& scheduleStep() const { return mAttributes->template getAttr<MemorizeAttr::ScheduleStep>(); } + inline std::uint32_t& scheduleStep() const { return mAttributes->template getAttr<Attr::ScheduleStep>(); } /** * @brief Get or set the forward step counter for the operator. * @return A reference to the forward step counter. */ - inline std::uint32_t& forwardStep() const { return mAttributes->template getAttr<MemorizeAttr::ForwardStep>(); } + inline std::uint32_t& forwardStep() const { return mAttributes->template getAttr<Attr::ForwardStep>(); } /** * @brief Get or set the end step defining the memory duration. * @return A reference to the end step value. */ - inline std::uint32_t& endStep() const { return mAttributes->template getAttr<MemorizeAttr::EndStep>(); } + inline std::uint32_t& endStep() const { return mAttributes->template getAttr<Attr::EndStep>(); } /** * @brief Retrieve the names of the operator's input tensors. @@ -257,9 +258,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ - return EnumStrings<Aidge::MemorizeAttr>::data; - } + static constexpr const char* const* attributesName(); }; /** @@ -271,5 +270,20 @@ public: std::shared_ptr<Node> Memorize(const std::uint32_t endStep, const std::string& name = ""); } // namespace Aidge +namespace { +template <> +struct EnumStrings<Aidge::Memorize_Op::Attr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::Memorize_Op::Attr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_MEMORIZE_ATTR) +}; +} + +constexpr const char* const* Aidge::Memorize_Op::attributesName() { + return EnumStrings<Aidge::Memorize_Op::Attr>::data; +} + +#undef LIST_MEMORIZE_ATTR #endif /* AIDGE_CORE_OPERATOR_MEMORIZE_H_ */ diff --git a/include/aidge/operator/Operator.hpp b/include/aidge/operator/Operator.hpp index dd59af175231acb274126d7f396cdd502046b004..81a54620a6f325eba04e9055e12d73d6a5d64163 100644 --- a/include/aidge/operator/Operator.hpp +++ b/include/aidge/operator/Operator.hpp @@ -31,6 +31,16 @@ #ifdef PYBIND namespace py = pybind11; #endif + + +#define SELECT_ENUM_FOR_ATTR(name, str, type) name +#define SELECT_STR_FOR_ATTR(name, str, type) str +#define SELECT_TYPE_FOR_ATTR(name, str, type) type + +#define GENERATE_LIST_ATTR_ENUM(LIST_ATTRS) LIST_ATTRS(SELECT_ENUM_FOR_ATTR) +#define GENERATE_LIST_ATTR_STR(LIST_ATTRS) LIST_ATTRS(SELECT_STR_FOR_ATTR) +#define GENERATE_LIST_ATTR_TYPE(LIST_ATTRS) LIST_ATTRS(SELECT_TYPE_FOR_ATTR) + namespace Aidge { /** diff --git a/include/aidge/operator/Pad.hpp b/include/aidge/operator/Pad.hpp index 0880b2c97ed7e2e6e9e4515c82c37aa4e0e91233..491a8a3697de5c685d6c9130423dd290e4b6cf71 100644 --- a/include/aidge/operator/Pad.hpp +++ b/include/aidge/operator/Pad.hpp @@ -24,17 +24,25 @@ #include "aidge/utils/ArrayHelpers.hpp" #include "aidge/utils/Types.h" -namespace Aidge { +#define LIST_PAD_ATTR(X) \ + X(BeginEndBorders, "begin_end_borders", Aidge::sizeArr_t<2 * DIM>), \ + X(BorderType, "border_type", PadBorderType), \ + X(BorderValue, "border_value", double) + +namespace Aidge { /** * @enum PadAttr * @brief Attributes for the Pad operator. + * + * - BeginEndBorders: Specifies the padding sizes for the beginning and end of each dimension. + * - BorderType: Type of border handling during padding. + * - BorderValue: Value to be used for constant padding. */ enum class PadAttr { - BeginEndBorders, ///< Specifies the padding sizes for the beginning and end of each dimension. - BorderType, ///< Type of border handling during padding. - BorderValue ///< Value to be used for constant padding. + GENERATE_LIST_ATTR_ENUM(LIST_PAD_ATTR) }; + /** * @enum PadBorderType * @brief Types of border handling available for padding. @@ -46,19 +54,16 @@ enum class PadBorderType { Wrap, ///< Values wrap around the tensor dimensions. Zero ///< All out-of-bound values are set to 0. }; - } // namespace Aidge namespace { - /** - * @brief EnumStrings specialization for PadAttr. - */ - template <> - const char* const EnumStrings<Aidge::PadAttr>::data[] = { - "begin_end_borders", - "border_type", - "border_value" - }; +template <> +struct EnumStrings<Aidge::PadAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::PadAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_PAD_ATTR) +}; /** * @brief EnumStrings specialization for PadBorderType. @@ -131,11 +136,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<PadAttr, - std::array<DimSize_t, 2 * DIM>, // Padding for start and end of each dimension. - PadBorderType, // Border handling type. - double // Border value for constant padding. - >; + using Attributes_ = StaticAttributes<PadAttr, GENERATE_LIST_ATTR_TYPE(LIST_PAD_ATTR)>; template <PadAttr e> using attr = typename Attributes_::template attr<e>; @@ -247,7 +248,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::PadAttr>::data; } }; @@ -284,6 +285,6 @@ inline std::shared_ptr<Node> Pad( extern template class Aidge::Pad_Op<1>; extern template class Aidge::Pad_Op<2>; - +#undef LIST_PAD_ATTR #endif /* AIDGE_CORE_OPERATOR_PAD_H_ */ diff --git a/include/aidge/operator/Pop.hpp b/include/aidge/operator/Pop.hpp index d9d52f9bcd07a671d68e3db53c378c9ee6659c8e..9790f05e9375435f7adf2dfbf3fe0460487416fc 100644 --- a/include/aidge/operator/Pop.hpp +++ b/include/aidge/operator/Pop.hpp @@ -92,25 +92,35 @@ public: */ void backward() override; }; +} //namespace Aidge +#define LIST_POP_ATTR(X) \ + X(ForwardStep, "forward_step", std::uint32_t), \ + X(BackwardStep, "backward_step", std::uint32_t) + +namespace Aidge { /** * @enum PopAttr * @brief Attributes specific to the `Pop` operator. + * + * - ForwardStep: Tracks the current step in the forward pass. + * - BackwardStep: Tracks the current step in the backward pass. */ enum class PopAttr { - ForwardStep, // Tracks the current step in the forward pass - BackwardStep // Tracks the current step in the backward pass + GENERATE_LIST_ATTR_ENUM(LIST_POP_ATTR) }; -} // namespace Aidge +} // namespace Aidge + namespace { - /** - * @brief String representations of the `Pop` operator's attributes. - */ - template <> - const char *const EnumStrings<Aidge::PopAttr>::data[] = { - "forward_step", "backward_step" - }; +template <> +struct EnumStrings<Aidge::PopAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::PopAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_POP_ATTR) +}; } + namespace Aidge { /** * @class Pop_Op @@ -131,7 +141,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<PopAttr, std::uint32_t, std::uint32_t>; + using Attributes_ = StaticAttributes<PopAttr, GENERATE_LIST_ATTR_TYPE(LIST_POP_ATTR)>; template <PopAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -226,7 +236,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::PopAttr>::data; } }; @@ -239,5 +249,6 @@ public: std::shared_ptr<Node> Pop(const std::string& name = ""); } // namespace Aidge +#undef LIST_POP_ATTR #endif /* AIDGE_CORE_OPERATOR_POP_H_ */ diff --git a/include/aidge/operator/Producer.hpp b/include/aidge/operator/Producer.hpp index 3690579d34373b64eec20042b7f9615266c15aee..ae88c0c714ec5a1ce3a5b39e290d2566e49d9f4b 100644 --- a/include/aidge/operator/Producer.hpp +++ b/include/aidge/operator/Producer.hpp @@ -28,21 +28,29 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Registrar.hpp" -namespace Aidge { +#define LIST_PRODUCER_ATTR(X) X(Constant, "constant", bool) + +namespace Aidge { /** - * @enum ProdAttr + * @enum ProducerAttr * @brief Attributes specific to the `Producer_Op` class. */ -enum class ProdAttr { Constant }; +enum class ProducerAttr { + GENERATE_LIST_ATTR_ENUM(LIST_PRODUCER_ATTR) +}; } // namespace Aidge + namespace { - /** - * @brief Enum string representation for `ProdAttr`. - */ - template <> - const char* const EnumStrings<Aidge::ProdAttr>::data[] = {"constant"}; +template <> +struct EnumStrings<Aidge::ProducerAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ProducerAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_PRODUCER_ATTR) +}; } + namespace Aidge { /** * @class Producer_Op @@ -76,8 +84,10 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<ProdAttr, bool>; - template <ProdAttr e> using attr = typename Attributes_::template attr<e>; + using Attributes_ = StaticAttributes<ProducerAttr, + GENERATE_LIST_ATTR_TYPE(LIST_PRODUCER_ATTR) + >; + template <ProducerAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; public: @@ -160,7 +170,7 @@ public: * * @return A reference to the constant attribute. */ - inline bool& constant() const { return mAttributes->template getAttr<ProdAttr::Constant>(); } + inline bool& constant() const { return mAttributes->template getAttr<ProducerAttr::Constant>(); } /** * @brief Performs the forward operation for the operator. @@ -280,4 +290,6 @@ std::shared_ptr<Node> addProducer(std::shared_ptr<Node>& otherNode, const IOInde } // namespace Aidge +#undef LIST_PRODUCER_ATTR + #endif /* AIDGE_CORE_OPERATOR_PRODUCER_H_ */ diff --git a/include/aidge/operator/ReduceMean.hpp b/include/aidge/operator/ReduceMean.hpp index 3ee4a1bec40f7f6aa409308708bc3338174c652b..cdb139f96f4bb33b9a22479a2f996d71abf85f0e 100644 --- a/include/aidge/operator/ReduceMean.hpp +++ b/include/aidge/operator/ReduceMean.hpp @@ -25,41 +25,11 @@ #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" -namespace Aidge { -enum class ReduceMeanAttr { - /** - * @brief Axes over which the mean operation is performed. - * - * Axes are specified as a vector of integers, each representing a dimension - * of the input tensor to be reduced. - */ - Axes, - - /** - * @brief Flag indicating whether to keep reduced dimensions. - * - * - `true`: Retain reduced dimensions with size 1. - * - `false`: Completely remove reduced dimensions. - */ - KeepDims, - - /** - * @brief Flag indicating behavior when axes are empty. - * - * - `true`: No operation is performed if axes are empty. - * - `false`: Reduction is performed over all axes if none are specified. - */ - NoopWithEmptyAxes -}; -} // namespace Aidge -namespace { - template <> - const char *const EnumStrings<Aidge::ReduceMeanAttr>::data[] = { - "axes", - "keep_dims", - "noop_with_empty_axes" - }; -} +#define LIST_REDUCEMEAN_ATTR(X) \ + X(Axes, "axes", std::vector<std::int32_t>), \ + X(KeepDims, "keep_dims", bool), \ + X(NoopWithEmptyAxes, "noop_with_empty_axes", bool) + namespace Aidge { /** * @class ReduceMean_Op @@ -94,13 +64,26 @@ class ReduceMean_Op : public OperatorTensor, public: static const std::string Type; + /** + * @enum Attr + * @brief Defines attributes for the ReduceMean operation. + * + * - **Axes**: Specifies the dimensions along which the mean is computed. + * - **KeepDims**: Determines whether the reduced dimensions are preserved. + * - `true`: Retains reduced dimensions with a size of 1. + * - `false`: Removes reduced dimensions from the output. + * - **NoopWithEmptyAxes**: Defines behavior when no axes are provided. + * - `true`: The operation is skipped if no axes are specified. + * - `false`: The reduction is applied across all dimensions. + */ + enum class Attr { + GENERATE_LIST_ATTR_ENUM(LIST_REDUCEMEAN_ATTR) + }; + private: - using Attributes_ = StaticAttributes<ReduceMeanAttr, - std::vector<std::int32_t>, - bool, - bool>; + using Attributes_ = StaticAttributes<Attr, GENERATE_LIST_ATTR_TYPE(LIST_REDUCEMEAN_ATTR)>; - template <ReduceMeanAttr e> + template <Attr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -154,17 +137,17 @@ public: /** * @brief Get the axes over which the mean is computed. */ - inline std::vector<std::int32_t>& axes() const noexcept { return mAttributes -> getAttr<ReduceMeanAttr::Axes>(); } + inline std::vector<std::int32_t>& axes() const noexcept { return mAttributes -> getAttr<Attr::Axes>(); } /** * @brief Get whether reduced dimensions are retained. */ - inline bool& keepDims() const noexcept { return mAttributes -> getAttr<ReduceMeanAttr::KeepDims>(); } + inline bool& keepDims() const noexcept { return mAttributes -> getAttr<Attr::KeepDims>(); } /** * @brief Get the behavior when axes are empty. */ - inline bool& noopWithEmptyAxes() const noexcept { return mAttributes -> getAttr<ReduceMeanAttr::NoopWithEmptyAxes>(); } + inline bool& noopWithEmptyAxes() const noexcept { return mAttributes -> getAttr<Attr::NoopWithEmptyAxes>(); } static const std::vector<std::string> getInputsName() { return {"data_input"}; @@ -178,9 +161,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ - return EnumStrings<Aidge::ReduceMeanAttr>::data; - } + static constexpr const char* const* attributesName(); virtual ~ReduceMean_Op() noexcept; }; @@ -203,5 +184,20 @@ std::shared_ptr<Node> ReduceMean(const std::vector<std::int32_t> &axes, } // namespace Aidge +namespace { +template <> +struct EnumStrings<Aidge::ReduceMean_Op::Attr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ReduceMean_Op::Attr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_REDUCEMEAN_ATTR) +}; +} + +constexpr const char* const* Aidge::ReduceMean_Op::attributesName(){ + return EnumStrings<Aidge::ReduceMean_Op::Attr>::data; +} + +#undef LIST_REDUCEMEAN_ATTR #endif /* AIDGE_CORE_OPERATOR_REDUCEMEAN_H_ */ diff --git a/include/aidge/operator/ReduceSum.hpp b/include/aidge/operator/ReduceSum.hpp index adb58f895cf3fbfa67b84c518a7f6cedf09d1a19..73f59c25d43e8c78cfd9feb42eefcfd94f8680a1 100644 --- a/include/aidge/operator/ReduceSum.hpp +++ b/include/aidge/operator/ReduceSum.hpp @@ -19,44 +19,16 @@ #include "aidge/graph/Node.hpp" #include "aidge/operator/OperatorTensor.hpp" -#include "aidge/operator/Producer.hpp" #include "aidge/utils/ErrorHandling.hpp" #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" -namespace Aidge { -enum class ReduceSumAttr { -/** - * @brief Axes over which the mean operation is performed. - * - * Axes are specified as a vector of integers, each representing a dimension - * of the input tensor to be reduced. - */ - Axes, - - /** - * @brief Flag indicating whether to keep reduced dimensions. - * - * - `true`: Retain reduced dimensions with size 1. - * - `false`: Completely remove reduced dimensions. - */ - KeepDims, - - /** - * @brief Flag indicating behavior when axes are empty. - * - * - `true`: No operation is performed if axes are empty. - * - `false`: Reduction is performed over all axes if none are specified. - */ - NoopWithEmptyAxes -}; +#define LIST_REDUCESUM_ATTR(X) \ + X(Axes, "axes", std::vector<std::int32_t>), \ + X(KeepDims, "keep_dims", bool), \ + X(NoopWithEmptyAxes, "noop_with_empty_axes", bool) -} // namespace Aidge -namespace { - template <> - const char *const EnumStrings<Aidge::ReduceSumAttr>::data[] = {"axes", "keep_dims", "noop_with_empty_axes"}; -} namespace Aidge { /** * @class ReduceSum_Op @@ -91,12 +63,25 @@ class ReduceSum_Op : public OperatorTensor, public: static const std::string Type; + /** + * @enum Attr + * @brief Defines attributes for the ReduceSum operation. + * + * - **Axes**: Specifies the dimensions along which the sum is computed. + * - **KeepDims**: Determines whether the reduced dimensions are preserved. + * - `true`: Retains reduced dimensions with a size of 1. + * - `false`: Removes reduced dimensions from the output. + * - **NoopWithEmptyAxes**: Defines behavior when no axes are provided. + * - `true`: The operation is skipped if no axes are specified. + * - `false`: The reduction is applied across all dimensions. + */ + enum class Attr { + GENERATE_LIST_ATTR_ENUM(LIST_REDUCESUM_ATTR) + }; + private: - using Attributes_ = StaticAttributes<ReduceSumAttr, - std::vector<std::int32_t>, - bool, - bool>; - template <ReduceSumAttr e> + using Attributes_ = StaticAttributes<Attr, GENERATE_LIST_ATTR_TYPE(LIST_REDUCESUM_ATTR)>; + template <Attr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -114,9 +99,9 @@ public: ReduceSum_Op(const std::vector<std::int32_t>& axes, bool keep_dims, bool noop_with_empty_axes) : OperatorTensor(Type, {InputCategory::Data}, 1), mAttributes(std::make_shared<Attributes_>( - attr<ReduceSumAttr::Axes>(axes), - attr<ReduceSumAttr::KeepDims>(keep_dims), - attr<ReduceSumAttr::NoopWithEmptyAxes>(noop_with_empty_axes))) + attr<Attr::Axes>(axes), + attr<Attr::KeepDims>(keep_dims), + attr<Attr::NoopWithEmptyAxes>(noop_with_empty_axes))) {} /** @@ -157,17 +142,17 @@ public: /** * @brief Get the axes over which the mean is computed. */ - inline std::vector<std::int32_t>& axes() const noexcept { return mAttributes -> getAttr<ReduceSumAttr::Axes>(); } + inline std::vector<std::int32_t>& axes() const noexcept { return mAttributes -> getAttr<Attr::Axes>(); } /** * @brief Get whether reduced dimensions are retained. */ - inline bool& keepDims() const noexcept { return mAttributes -> getAttr<ReduceSumAttr::KeepDims>(); } + inline bool& keepDims() const noexcept { return mAttributes -> getAttr<Attr::KeepDims>(); } /** * @brief Get the behavior when axes are empty. */ - inline bool& noopWithEmptyAxes() const noexcept { return mAttributes -> getAttr<ReduceSumAttr::NoopWithEmptyAxes>(); } + inline bool& noopWithEmptyAxes() const noexcept { return mAttributes -> getAttr<Attr::NoopWithEmptyAxes>(); } static const std::vector<std::string> getInputsName() { @@ -181,9 +166,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ - return EnumStrings<Aidge::ReduceSumAttr>::data; - } + static constexpr const char* const* attributesName(); }; /** @@ -208,4 +191,20 @@ inline std::shared_ptr<Node> ReduceSum(const std::vector<std::int32_t> &axes={}, } } // namespace Aidge +namespace { +template <> +struct EnumStrings<Aidge::ReduceSum_Op::Attr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ReduceSum_Op::Attr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_REDUCESUM_ATTR) +}; +} + +constexpr const char* const* Aidge::ReduceSum_Op::attributesName() { + return EnumStrings<Aidge::ReduceSum_Op::Attr>::data; +} + +#undef LIST_REDUCESUM_ATTR + #endif /* AIDGE_CORE_OPERATOR_REDUCESUM_H_ */ diff --git a/include/aidge/operator/Reshape.hpp b/include/aidge/operator/Reshape.hpp index e69c42d4d98974e7bb00acbf17581cd56ada1331..f02dae45e8285e7187ca7f739c163e69bee7c81c 100644 --- a/include/aidge/operator/Reshape.hpp +++ b/include/aidge/operator/Reshape.hpp @@ -43,32 +43,37 @@ public: void forward() override; void backward() override; }; +} // namespace Aidge + + +#define LIST_RESHAPE_ATTR(X) \ + X(Shape, "shape", std::vector<std::int64_t>), \ + X(AllowZero, "allow_zero", bool) + +namespace Aidge { /** * @enum ReshapeAttr * @brief Enumeration of attributes specific to the Reshape operator. + * + * - **Shape**: The target shape for the output tensor. + * - **AllowZero**: When true, zeros in the target shape retain the corresponding dimension size from the input tensor. */ enum class ReshapeAttr { - /** - * @brief The target shape for the output tensor. - */ - Shape, - - /** - * @brief Whether zeros in the shape attribute are allowed. - * - * When true, zeros in the target shape retain the corresponding dimension size from the input tensor. - */ - AllowZero + GENERATE_LIST_ATTR_ENUM(LIST_RESHAPE_ATTR) }; -} // namespace Aidge +} // namespace Aidge + namespace { - /** - * @brief EnumStrings specialization for ReshapeAttr. - */ - template <> - const char *const EnumStrings<Aidge::ReshapeAttr>::data[] = {"shape", "allow_zero"}; +template <> +struct EnumStrings<Aidge::ReshapeAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ReshapeAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_RESHAPE_ATTR) +}; } + namespace Aidge { /** * @brief Description of Reshape operator that adjusts the shape of the input tensor. @@ -94,7 +99,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<ReshapeAttr, std::vector<std::int64_t>, bool>; + using Attributes_ = StaticAttributes<ReshapeAttr, GENERATE_LIST_ATTR_TYPE(LIST_RESHAPE_ATTR)>; template <ReshapeAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -189,7 +194,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::ReshapeAttr>::data; } }; @@ -208,5 +213,6 @@ std::shared_ptr<Node> Reshape(const std::vector<std::int64_t>& shape = {}, } // namespace Aidge +#undef LIST_RESHAPE_ATTR #endif /* AIDGE_CORE_OPERATOR_RESHAPE_H_ */ diff --git a/include/aidge/operator/Resize.hpp b/include/aidge/operator/Resize.hpp index 37d42fcc861db42c991a6e7f4296d725d002aad5..32ddbe48804e359a9a868a149e66c43342b76d56 100644 --- a/include/aidge/operator/Resize.hpp +++ b/include/aidge/operator/Resize.hpp @@ -25,30 +25,38 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" -namespace Aidge { -/* @brief attributes for the aidge operator */ +#define LIST_RESIZE_ATTR(X) \ + X(CoordinateTransformationMode, "coordinate_transformation_mode", Interpolation::CoordinateTransformation), \ + X(CubicCoeffA, "cubic_coeff_a", float), \ + X(InterpolationMode, "interpolation_mode", Interpolation::Mode), \ + X(PaddingMode, "padding_mode", PadBorderType) + +namespace Aidge { +/** + * @enum ResizeAttr + * @brief Attributes for the Resize operation. + * + * - CoordinateTransformationMode: Defines how source coordinates map to target coordinates. + * - CubicCoeffA: Coefficient used in cubic interpolation. + * - InterpolationMode: Defines the interpolation method used. + * - PaddingMode: Specifies how padding is handled. + */ enum class ResizeAttr { - // antialias, - // axes, - CoordinateTransformationMode, - CubicCoeffA, - // excludeOutside, - // extrapolation_value, - // keep_aspect_ratio_policy, - InterpolationMode, - PaddingMode + GENERATE_LIST_ATTR_ENUM(LIST_RESIZE_ATTR) }; } // namespace Aidge + namespace { - template <> - const char *const EnumStrings<Aidge::ResizeAttr>::data[] = { - "coordinate_transformation_mode", - "cubic_coeff_a", - "interpolation_mode", - "padding_mode" - }; +template <> +struct EnumStrings<Aidge::ResizeAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ResizeAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_RESIZE_ATTR) +}; } + namespace Aidge { /** * @brief Resize operator, will up/downscale a given tensor given the input. @@ -98,18 +106,15 @@ class Resize_Op std::string, std::function<std::shared_ptr<OperatorImpl>(const Resize_Op &)>> { - private: +private: using Attributes_ = StaticAttributes<ResizeAttr, - Interpolation::CoordinateTransformation, - float, - Interpolation::Mode, - PadBorderType>; + GENERATE_LIST_ATTR_TYPE(LIST_RESIZE_ATTR)>; template <ResizeAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; - public: +public: static const std::string Type; /** * @brief creates a resize operator @@ -206,7 +211,7 @@ class Resize_Op * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::ResizeAttr>::data; } }; @@ -240,4 +245,6 @@ Resize(std::vector<float> scale = std::vector<float>(), } // namespace Aidge +#undef LIST_RESIZE_ATTR + #endif /* AIDGE_CORE_OPERATOR_RESIZE_H_ */ diff --git a/include/aidge/operator/Scaling.hpp b/include/aidge/operator/Scaling.hpp index fb342d34580092febaf3d1e63ea78247c3e8f77a..c5264fe551bf6ab0d18010b37bb66782170cee74 100644 --- a/include/aidge/operator/Scaling.hpp +++ b/include/aidge/operator/Scaling.hpp @@ -26,37 +26,35 @@ // Caution: This operator is now deprecated and should no longer be used. // It has been replaced by the MetaOperator "Quantizer" (located directly in aidge_quantization). +#define LIST_SCALING_ATTR(X) \ + X(ScalingFactor, "scaling_factor", float), \ + X(QuantizedNbBits, "quantized_nb_bits", std::size_t), \ + X(IsOutputUnsigned, "is_output_unsigned", bool) + namespace Aidge { +/** + * @enum ScalingAttr + * @brief Attributes for the Scaling operation. + * + * - ScalingFactor: Floating-point scaling factor applied to the input tensor. + * - QuantizedNbBits: Specifies the bit-width used for quantization. + * - IsOutputUnsigned: Indicates whether the quantized output values are unsigned. + */ enum class ScalingAttr { - /** - * @brief Scaling factor applied to the input tensor. - * - * This floating-point value is used to scale the input tensor. - */ - ScalingFactor, - - /** - * @brief Number of quantization bits. - * - * Specifies the bit-width used for quantization. - * For example, a value of `8` represents 8-bit quantization. - */ - QuantizedNbBits, - - /** - * @brief Indicates whether the output is unsigned. - * - * - `true`: The quantized output values are unsigned integers. - * - `false`: The quantized output values are signed integers. - */ - IsOutputUnsigned + GENERATE_LIST_ATTR_ENUM(LIST_SCALING_ATTR) }; } // namespace Aidge + namespace { - template <> - const char* const EnumStrings<Aidge::ScalingAttr>::data[] - = {"scaling_factor", "quantized_nb_bits", "is_output_unsigned"}; +template <> +struct EnumStrings<Aidge::ScalingAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ScalingAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_SCALING_ATTR) +}; } + namespace Aidge { /** * @brief Description of a scaling operation to scale and quantize input tensors. @@ -82,7 +80,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<ScalingAttr, float, std::size_t, bool>; + using Attributes_ = StaticAttributes<ScalingAttr, GENERATE_LIST_ATTR_TYPE(LIST_SCALING_ATTR)>; template <ScalingAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -145,7 +143,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::ScalingAttr>::data; } }; @@ -165,5 +163,6 @@ std::shared_ptr<Node> Scaling(float scalingFactor = 1.0f, const std::string& name = ""); } // namespace Aidge +#undef LIST_SCALING_ATTR #endif /* AIDGE_CORE_OPERATOR_SCALING_H_ */ diff --git a/include/aidge/operator/Shape.hpp b/include/aidge/operator/Shape.hpp index 2a553fb827fc8a8d4b03fa06ebcd8825ae2ed64f..290d95eefd7972dad3d0ed05a01eb7105f5f9a62 100644 --- a/include/aidge/operator/Shape.hpp +++ b/include/aidge/operator/Shape.hpp @@ -47,29 +47,36 @@ public: */ void forward() override; }; +} + +#define LIST_SHAPE_ATTR(X) \ + X(Start, "start", std::int64_t), \ + X(End, "end", std::int64_t) +namespace Aidge { /** * @enum ShapeAttr * @brief Enumeration of attributes specific to the Shape operator. + * + * - Start: Start index of the slice of dimensions to return. + * - End: End index of the slice of dimensions to return (exclusive). */ enum class ShapeAttr { - /** - * @brief Start index of the slice of dimensions to return. - */ - Start, - /** - * End index of the slice of dimensions to return (exclusive). - */ - End + GENERATE_LIST_ATTR_ENUM(LIST_SHAPE_ATTR) }; } // namespace Aidge + namespace { - /** - * @brief EnumStrings specialization for ShapeAttr. - */ - template <> - const char *const EnumStrings<Aidge::ShapeAttr>::data[] = {"start", "end"}; +/// @brief EnumStrings specialization for ShapeAttr. +template <> +struct EnumStrings<Aidge::ShapeAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::ShapeAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_SHAPE_ATTR) +}; } + namespace Aidge { /** * @brief Description of the operation of extracting the shape of a tensor. @@ -92,7 +99,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<ShapeAttr, std::int64_t, std::int64_t>; + using Attributes_ = StaticAttributes<ShapeAttr, GENERATE_LIST_ATTR_TYPE(LIST_SHAPE_ATTR)>; template <ShapeAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -176,7 +183,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::ShapeAttr>::data; } }; @@ -193,6 +200,6 @@ std::shared_ptr<Node> Shape(const std::int64_t start = 0, const std::int64_t end } // namespace Aidge - +#undef LIST_SHAPE_ATTR #endif /* AIDGE_CORE_OPERATOR_SHAPE_H_ */ diff --git a/include/aidge/operator/Slice.hpp b/include/aidge/operator/Slice.hpp index fa21b3d197551e54a95fe29dbb8e3f83d30865af..b425fe75208b37105ce6baadd4f2ff63f94f2f3c 100644 --- a/include/aidge/operator/Slice.hpp +++ b/include/aidge/operator/Slice.hpp @@ -44,51 +44,43 @@ public: */ void forward() override; }; +} // namespace Aidge + +#define LIST_SLICE_ATTR(X) \ + X(Starts, "starts", std::vector<std::int64_t>), \ + X(Ends, "ends", std::vector<std::int64_t>), \ + X(Axes, "axes", std::vector<std::int8_t>), \ + X(Steps, "steps", std::vector<std::int64_t>) +namespace Aidge { /** * @enum SliceAttr * @brief Attributes for the Slice operation. + * + * - Starts: Starting indices for the slice along each axis. + * - If index is < 0, the input tensor's rank is added. + * - If index is still < 0, it is forced to 0. + * - If index > dim, it is forced to dim. + * - Ends: Ending indices for the slice along each axis (exclusive). + * - Follows the same adjustment rules as Starts. + * - Axes: Axes along which the slice operation is performed. + * - Steps: Steps to move between each slice along each axis. */ enum class SliceAttr { - /** - * @brief Starting indices for the slice along each axis. - * - * Specifies the start position for slicing for each axis. - * @details if index is < 0 then the input tansor's rank is added. - * After, if index is < 0 then it is forced to 0, - * if index > dim then index is forced to dim. - */ - Starts, - - /** - * @brief Ending indices for the slice along each axis. - * - * Specifies the end position (exclusive) for slicing for each axis. - * @details if index is < 0 then the input tansor's rank is added. - * After, if index is < 0 then it is forced to 0, - * if index > dim then index is forced to dim. - */ - Ends, - - /** - * @brief Axes along which the slice operation is performed. - * - * Specifies which dimensions of the input tensor are affected by the slice. - */ - Axes, - - /** - * @brief Steps to move between each slice along each axis. - * - * Specifies the step size for slicing along each axis. - */ - Steps + GENERATE_LIST_ATTR_ENUM(LIST_SLICE_ATTR) }; } // namespace Aidge + namespace { - template <> - const char *const EnumStrings<Aidge::SliceAttr>::data[] = { "starts", "ends", "axes", "steps" }; +template <> +struct EnumStrings<Aidge::SliceAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::SliceAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_SLICE_ATTR) +}; } + namespace Aidge{ /** * @class Slice_Op @@ -125,19 +117,10 @@ class Slice_Op : public OperatorTensor, public: static const std::string Type; - /** - * @brief Defines static attributes for the Slice operator. - */ - using Attributes_ = StaticAttributes<SliceAttr, - std::vector<std::int64_t>, // Starts - std::vector<std::int64_t>, // Ends - std::vector<std::int8_t>, // Axes - std::vector<std::int64_t>>; // Steps - private: + using Attributes_ = StaticAttributes<SliceAttr, GENERATE_LIST_ATTR_TYPE(LIST_SLICE_ATTR)>; template <SliceAttr e> using attr = typename Attributes_::template attr<e>; - const std::shared_ptr<Attributes_> mAttributes; public: @@ -213,7 +196,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::SliceAttr>::data; } }; @@ -236,4 +219,6 @@ std::shared_ptr<Node> Slice(const std::vector<std::int64_t>& starts = {}, } // namespace Aidge +#undef LIST_SLICE_ATTR + #endif /* AIDGE_CORE_OPERATOR_SLICE_H_ */ diff --git a/include/aidge/operator/Softmax.hpp b/include/aidge/operator/Softmax.hpp index 86e1a57e70c4b7070b9af279980b2d5344a2f6f0..b0c6a2edae7ab9bec4a5f45746f2bc9258b6eb29 100644 --- a/include/aidge/operator/Softmax.hpp +++ b/include/aidge/operator/Softmax.hpp @@ -23,24 +23,36 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" +#define LIST_SOFTMAX_ATTR(X) \ + X(Axis, "axis", std::int32_t) + namespace Aidge { +/** + * @enum SoftmaxAttr + * @brief Attributes for the Softmax operation. + * + * - Axis: Axis along which the softmax operation is applied. + * - Determines the dimension in the input tensor over which the softmax + * operation will compute normalized exponential values. + */ enum class SoftmaxAttr { - /** - * @brief Axis along which the softmax operation is applied. - * - * Determines the dimension in the input tensor over which the softmax - * operation will compute normalized exponential values. - */ - Axis + GENERATE_LIST_ATTR_ENUM(LIST_SOFTMAX_ATTR) }; } // namespace Aidge + namespace { - /** - * @brief EnumStrings specialization for SoftmaxAttr. - */ - template <> - const char* const EnumStrings<Aidge::SoftmaxAttr>::data[] = {"axis"}; +/** + * @brief EnumStrings specialization for SoftmaxAttr. + */ +template <> +struct EnumStrings<Aidge::SoftmaxAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::SoftmaxAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_SOFTMAX_ATTR) +}; } + namespace Aidge { /** * @brief Description of a Softmax operation on input Tensor along a specified axis. @@ -68,7 +80,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<SoftmaxAttr, std::int32_t>; + using Attributes_ = StaticAttributes<SoftmaxAttr, GENERATE_LIST_ATTR_TYPE(LIST_SOFTMAX_ATTR)>; template <SoftmaxAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -143,7 +155,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::SoftmaxAttr>::data; } }; @@ -159,4 +171,6 @@ std::shared_ptr<Node> Softmax(std::int32_t axis, const std::string& name = ""); } // namespace Aidge +#undef LIST_SOFTMAX_ATTR + #endif /* AIDGE_CORE_OPERATOR_SOFTMAX_H_ */ diff --git a/include/aidge/operator/Split.hpp b/include/aidge/operator/Split.hpp index 8b6acb06023f5f71cbb71b42281f21bda19caaed..038879f05dfc57f6451d0c490ec52e8283a1b93f 100644 --- a/include/aidge/operator/Split.hpp +++ b/include/aidge/operator/Split.hpp @@ -44,36 +44,41 @@ public: */ void forward() override; }; +} // naemspace Aidge +#define LIST_SPLIT_ATTR(X) \ + X(Axis, "axis", std::int8_t), \ + X(Split, "split", std::vector<DimSize_t>) + +namespace Aidge { /** * @enum SplitAttr * @brief Enumeration of Split operator attributes. + * + * - Axis: Axis along which to split the input tensor. + * - The specified axis determines the direction of splitting. + * - Split: Sizes of each output tensor after splitting. + * - If specified, the sum of the split sizes must match the size of the input + * tensor along the specified axis. */ enum class SplitAttr { - /** - * @brief Axis along which to split the input tensor. - * - * The specified axis determines the direction of splitting. - */ - Axis, - - /** - * @brief Sizes of each output tensor after splitting. - * - * If specified, the sum of the split sizes must match the size of the input - * tensor along the specified axis. - */ - Split + GENERATE_LIST_ATTR_ENUM(LIST_SPLIT_ATTR) }; } // namespace Aidge namespace { - /** - * @brief EnumStrings specialization for SplitAttr. - */ - template <> - const char* const EnumStrings<Aidge::SplitAttr>::data[] = {"axis", "split"}; - } +/** + * @brief EnumStrings specialization for SplitAttr. + */ +template <> +struct EnumStrings<Aidge::SplitAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::SplitAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_SPLIT_ATTR) +}; +} + namespace Aidge { /** @@ -109,7 +114,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<SplitAttr, std::int8_t, std::vector<DimSize_t>>; + using Attributes_ = StaticAttributes<SplitAttr,GENERATE_LIST_ATTR_TYPE(LIST_SPLIT_ATTR)>; template <SplitAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -188,7 +193,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::SplitAttr>::data; } }; @@ -209,5 +214,6 @@ std::shared_ptr<Node> Split(DimSize_t nbOutput, } // namespace Aidge +#undef LIST_SPLIT_ATTR #endif /* AIDGE_CORE_OPERATOR_SPLIT_H_ */ diff --git a/include/aidge/operator/Squeeze.hpp b/include/aidge/operator/Squeeze.hpp index 69fa9d493a321199ea2fddd61c7b769a668c6f42..987f1e6af1452d9513cd855e63a8f8504721e25a 100644 --- a/include/aidge/operator/Squeeze.hpp +++ b/include/aidge/operator/Squeeze.hpp @@ -40,19 +40,34 @@ public: : OperatorImpl(op, backend) {} void forward() override; }; +} // namespace Aidge + +#define LIST_SQUEEZE_ATTR(X) \ + X(Axes, "axes", std::vector<std::int8_t>) +namespace Aidge { +/** + * @enum SqueezeAttr + * @brief Enumeration of Squeeze operator attributes. + * + * - Axes: axes to squeeze, if left empty all 1 sized + * dimensions will be removed. + */ enum class SqueezeAttr { - /** - * @brief axes to squeeze, if left empty all 1 sized - * dimensions will be removed. - */ - Axes + GENERATE_LIST_ATTR_ENUM(LIST_SQUEEZE_ATTR) }; } // namespace Aidge + namespace { - template <> - const char *const EnumStrings<Aidge::SqueezeAttr>::data[] = {"axes"}; +template <> +struct EnumStrings<Aidge::SqueezeAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::SqueezeAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_SQUEEZE_ATTR) +}; } + namespace Aidge { /** * @brief This operator has as purpose to remove dummy dimensions around given @@ -152,7 +167,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::SqueezeAttr>::data; } }; @@ -165,4 +180,6 @@ inline std::shared_ptr<Node> Squeeze(const std::vector<int8_t> axes = {}, } } // namespace Aidge +#undef LIST_SQUEEZE_ATTR + #endif // AIDGE_CORE_OPERATOR_SQUEEZE_H_ diff --git a/include/aidge/operator/Stack.hpp b/include/aidge/operator/Stack.hpp index d22b2f2dde9d9254ca7dd0f81f1a9f7bd35d9f6b..84341375649e6d8d4948283971e86042cc003fd4 100644 --- a/include/aidge/operator/Stack.hpp +++ b/include/aidge/operator/Stack.hpp @@ -96,19 +96,34 @@ public: void backward() override; }; +#define LIST_STACK_ATTR(X) \ + X(ForwardStep, "forward_step", std::uint32_t), \ + X(BackwardStep, "backward_step", std::uint32_t), \ + X(MaxElements, "max_elements", std::uint32_t) + +/** + * @enum StackAttr + * @brief Attributes for the Stack operation. + * + * - ForwardStep: Tracks the current step in the forward pass. + * - BackwardStep: Tracks the current step in the backward pass. + * - MaxElements: Maximum number of elements that can be stacked. + */ enum class StackAttr { - ForwardStep, // Tracks the current step in the forward pass. - BackwardStep, // Tracks the current step in the forward pass. - MaxElements // Maximum number of elements that can be stacked. + GENERATE_LIST_ATTR_ENUM(LIST_STACK_ATTR) }; } // namespace Aidge + namespace { - /** - * @brief String representations of the Stack operator's attributes. - */ - template <> - const char *const EnumStrings<Aidge::StackAttr>::data[] = {"forward_step", "backward_step", "max_elements"}; +template <> +struct EnumStrings<Aidge::StackAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::StackAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_STACK_ATTR) +}; } + namespace Aidge { /** * @class StackOp @@ -129,7 +144,9 @@ namespace Aidge { class StackOp : public OperatorTensor, public Registrable<StackOp, std::string, std::function<std::unique_ptr<OperatorImpl>(const StackOp&)>> { private: - using Attributes_ = StaticAttributes<StackAttr, std::uint32_t, std::uint32_t, std::uint32_t>; + using Attributes_ = StaticAttributes<StackAttr, + GENERATE_LIST_ATTR_TYPE(LIST_STACK_ATTR) + >; template <StackAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -245,7 +262,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::StackAttr>::data; } }; @@ -259,4 +276,6 @@ public: std::shared_ptr<Node> Stack(std::uint32_t maxElements = 0, const std::string& name = ""); } // namespace Aidge +#undef LIST_STACK_ATTR + #endif /* AIDGE_CORE_OPERATOR_STACK_H_ */ diff --git a/include/aidge/operator/Transpose.hpp b/include/aidge/operator/Transpose.hpp index 2619c5ea5d41407100b66f909d6f64176027f74c..25d8d92f67901dbeb7cf0610a0f818cdbf60b0bd 100644 --- a/include/aidge/operator/Transpose.hpp +++ b/include/aidge/operator/Transpose.hpp @@ -46,28 +46,11 @@ public: */ void forward() override; }; - -/** - * @enum TransposeAttr - * @brief Enumeration of attributes specific to the Transpose operator. - */ -enum class TransposeAttr { - /** - * @brief Order of the output dimensions relative to the input dimensions. - * - * If this attribute is empty, the dimensions of the input tensor will - * be reversed. - */ - OutputDimsOrder -}; } // namespace Aidge -namespace { - /** - * @brief EnumStrings specialization for TransposeAttr. - */ - template <> - const char *const EnumStrings<Aidge::TransposeAttr>::data[] = {"output_dims_order"}; - } + +#define LIST_TRANSPOSE_ATTR(X) \ + X(OutputDimsOrder, "output_dims_order", std::vector<DimSize_t>) + namespace Aidge { /** * @brief Describes the operation of transposing the axes of a given tensor. @@ -84,17 +67,30 @@ namespace Aidge { * @see Registrable */ class Transpose_Op : public OperatorTensor, - public Registrable<Transpose_Op, std::string, std::function<std::shared_ptr<OperatorImpl>(const Transpose_Op&)>> { - + public Registrable<Transpose_Op, + std::string, + std::function<std::shared_ptr<OperatorImpl>(const Transpose_Op&)>> { public: /** * @brief Static type string for the Transpose operator. */ static const std::string Type; + /** + * @enum Attr + * @brief Enumeration of attributes specific to the Transpose operator. + * + * - OutputDimsOrder: Order of the output dimensions relative to the input dimensions. + * If this attribute is empty, the dimensions of the input tensor will + * be reversed. + */ + enum class Attr { + GENERATE_LIST_ATTR_ENUM(LIST_TRANSPOSE_ATTR) + }; + private: - using Attributes_ = StaticAttributes<TransposeAttr, std::vector<DimSize_t>>; - template <TransposeAttr e> using attr = typename Attributes_::template attr<e>; + using Attributes_ = StaticAttributes<Attr, GENERATE_LIST_ATTR_TYPE(LIST_TRANSPOSE_ATTR)>; + template <Attr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; public: @@ -156,7 +152,7 @@ public: * If left empty, axes will be reversed. */ inline std::vector<DimSize_t>& outputDimsOrder() const noexcept { - return mAttributes->getAttr<TransposeAttr::OutputDimsOrder>(); + return mAttributes->getAttr<Attr::OutputDimsOrder>(); } /** @@ -179,9 +175,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ - return EnumStrings<Aidge::TransposeAttr>::data; - } + static constexpr const char* const* attributesName(); }; /** @@ -196,5 +190,20 @@ std::shared_ptr<Node> Transpose(const std::vector<DimSize_t> &outputDimsOrder = } // namespace Aidge +namespace { +template <> +struct EnumStrings<Aidge::Transpose_Op::Attr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::Transpose_Op::Attr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_TRANSPOSE_ATTR) +}; +} + +constexpr const char* const* Aidge::Transpose_Op::attributesName() { + return EnumStrings<Aidge::Transpose_Op::Attr>::data; +} + +#undef LIST_TRANSPOSE_ATTR #endif /* AIDGE_CORE_OPERATOR_TRANSPOSE_H_ */ diff --git a/include/aidge/operator/Unfold.hpp b/include/aidge/operator/Unfold.hpp index d220807d6cd4ea2c57c152c9e8351bc48211d06e..fe85f9d5e999ab2e6b6a0ae65f3d8ef43cdea0b3 100644 --- a/include/aidge/operator/Unfold.hpp +++ b/include/aidge/operator/Unfold.hpp @@ -22,9 +22,7 @@ #include "aidge/data/Tensor.hpp" #include "aidge/graph/Node.hpp" #include "aidge/operator/OperatorTensor.hpp" -#include "aidge/operator/Producer.hpp" #include "aidge/utils/ArrayHelpers.hpp" -#include "aidge/utils/ErrorHandling.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" @@ -50,39 +48,37 @@ public: */ void forward() override; }; +} //namespace Aidge +#define LIST_UNFOLD_ATTR(X) \ + X(StrideDims, "stride_dims", sizeArr_t<DIM>), \ + X(DilationDims, "dilation_dims", sizeArr_t<DIM>), \ + X(KernelDims, "kernel_dims", sizeArr_t<DIM>) + +namespace Aidge { /** * @enum UnfoldAttr - * @brief Enumeration of attributes specific to the Unfold operator. + * @brief Enumeration for the attributes of the Unfold operation. + * + * - StrideDims: Step sizes in each dimension during the unfold operation. + * - DilationDims: Spacing between elements in the kernel during the unfold. + * - KernelDims: Size of the kernel or filter applied during the unfold. */ enum class UnfoldAttr { - /** - * @brief Stride dimensions for the unfolding operation. - */ - StrideDims, - - /** - * @brief Dilation dimensions for the unfolding operation. - */ - DilationDims, - - /** - * @brief Kernel dimensions for the unfolding operation. - */ - KernelDims + GENERATE_LIST_ATTR_ENUM(LIST_UNFOLD_ATTR) }; -} // namespace Aidge +} // namespace Aidge + namespace { - /** - * @brief EnumStrings specialization for UnfoldAttr. - */ - template <> - const char* const EnumStrings<Aidge::UnfoldAttr>::data[] = { - "stride_dims", - "dilation_dims", - "kernel_dims" - }; +template <> +struct EnumStrings<Aidge::UnfoldAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::UnfoldAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_UNFOLD_ATTR) +}; } + namespace Aidge { /** * @brief Describes the operation of unfolding a tensor into sliding blocks. @@ -109,10 +105,7 @@ public: static const std::string Type; private: - using Attributes_ = StaticAttributes<UnfoldAttr, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>>; + using Attributes_ = StaticAttributes<UnfoldAttr, GENERATE_LIST_ATTR_TYPE(LIST_UNFOLD_ATTR)>; template <UnfoldAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -216,7 +209,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::UnfoldAttr>::data; } }; @@ -249,5 +242,6 @@ inline std::shared_ptr<Node> Unfold( DimSize_t const (&kernelDims)[DIM], extern template class Aidge::Unfold_Op<2>; +#undef LIST_UNFOLD_ATTR #endif /* AIDGE_CORE_OPERATOR_UNFOLD_H_ */ diff --git a/include/aidge/operator/Unsqueeze.hpp b/include/aidge/operator/Unsqueeze.hpp index a78a986724d4b5ca06f611b82e057d13183c5015..5975ff0578ee89a50e1871b71f77846cb63c9d4d 100644 --- a/include/aidge/operator/Unsqueeze.hpp +++ b/include/aidge/operator/Unsqueeze.hpp @@ -37,21 +37,35 @@ public: : OperatorImpl(op, backend) {} void forward() override; }; +} // namespace Aidge +#define LIST_UNSQUEEZE_ATTR(X) \ + X(Axes, "axes", std::vector<std::int8_t>) + +namespace Aidge { +/** + * @enum UnsqueezeAttr + * @brief Attributes for the Unsqueeze operation. + * + * - Axes: A vector of axes to unsqueeze. + * - Values must be within the range [ -a ; a-1 ], + * where `a = input_tensor.nbDim() + dims_to_unsqueeze.size()`. + */ enum class UnsqueezeAttr { - /** - * @brief vector of axes to unsqueeze. - * values must be comprised within - * [ -a ; a-1 ] - * with a = input_tensor.nbDim() + dims_to_unsqueeze.size() - */ - Axes + GENERATE_LIST_ATTR_ENUM(LIST_UNSQUEEZE_ATTR) }; -} // namespace Aidge +} // namespace Aidge + namespace { - template <> - const char *const EnumStrings<Aidge::UnsqueezeAttr>::data[] = {"axes"}; +template <> +struct EnumStrings<Aidge::UnsqueezeAttr> { + static const char* const data[]; +}; +constexpr const char* const EnumStrings<Aidge::UnsqueezeAttr>::data[] = { + GENERATE_LIST_ATTR_STR(LIST_UNSQUEEZE_ATTR) +}; } + namespace Aidge { /** * @brief This operator has as purpose to add a dummy dimension around given @@ -72,7 +86,7 @@ public: Type; // name of the type of the operation (Here "Unsqueeze") private: - using Attributes_ = StaticAttributes<UnsqueezeAttr, std::vector<int8_t>>; + using Attributes_ = StaticAttributes<UnsqueezeAttr, GENERATE_LIST_ATTR_TYPE(LIST_UNSQUEEZE_ATTR)>; template <UnsqueezeAttr e> using attr = typename Attributes_::template attr<e>; const std::shared_ptr<Attributes_> mAttributes; @@ -150,7 +164,7 @@ public: * @brief Retrieves the names of the attributes for the operator. * @return A vector containing the attributes name. */ - static const char* const* attributesName(){ + static constexpr const char* const* attributesName(){ return EnumStrings<Aidge::UnsqueezeAttr>::data; } }; @@ -163,4 +177,6 @@ inline std::shared_ptr<Node> Unsqueeze(const std::vector<int8_t> &axes = {}, } } // namespace Aidge +#undef LIST_UNSQUEEZE_ATTR + #endif // AIDGE_CORE_OPERATOR_UNSQUEEZE_H_ diff --git a/include/aidge/utils/Types.h b/include/aidge/utils/Types.h index b601df1cb8f8fa81cd2339e7eb393f7297e63499..6cbf375578b5e42b6f3db03ff990a2c791ef49c7 100644 --- a/include/aidge/utils/Types.h +++ b/include/aidge/utils/Types.h @@ -60,6 +60,8 @@ constexpr IOIndex_t gk_IOMaxIndex = std::numeric_limits<IOIndex_t>::max() - 1; // using IOIndex_t = std::uint16_t; // constexpr IOIndex_t gk_IOMaxNb = std::numeric_limits<IOIndex_t>::max(); +// type used by StaticAttribute MACROs +template <DimSize_t DIM> using sizeArr_t = std::array<DimSize_t, DIM>; } // namespace Aidge diff --git a/src/operator/Conv.cpp b/src/operator/Conv.cpp index 2077cab52f613780e77bba80efacb41d06a7f3cf..8e23e8b3c6ce5fa3ac179bb058e7e04d5905b6b2 100644 --- a/src/operator/Conv.cpp +++ b/src/operator/Conv.cpp @@ -19,6 +19,7 @@ #include <vector> #include "aidge/data/Tensor.hpp" +#include "aidge/operator/Producer.hpp" #include "aidge/utils/ErrorHandling.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" @@ -40,7 +41,7 @@ Aidge::Conv_Op<DIM>::Conv_Op(const Aidge::Conv_Op<DIM>& op) template <Aidge::DimIdx_t DIM> bool Aidge::Conv_Op<DIM>::forwardDims(bool /*allowDataDependency*/) { - if (!inputsAssociated()) + if (!inputsAssociated()) return false; // first check weight since it defines inChannels and outChannels if(getInput(0)->dataFormat() == Aidge::DataFormat::NHWC){ @@ -65,31 +66,31 @@ bool Aidge::Conv_Op<DIM>::forwardDims(bool /*allowDataDependency*/) { const std::array<DimSize_t, DIM + 2> inputDims(getInput(0)->template dims<DIM+2>()); std::array<DimSize_t, DIM + 2> outputDims{}; - + unsigned int in_dims_index = (getInput(0)->dataFormat() == Aidge::DataFormat::NHWC) ? 1 : 2; unsigned int out_dims_index = (getOutput(0)->dataFormat() == Aidge::DataFormat::NHWC) ? 1 : 2; - for (std::size_t dim = 0; dim < mAttributes->template getAttr<ConvAttr::KernelDims>().size(); ++dim) { - const DimSize_t kernelExtent = mAttributes->template getAttr<ConvAttr::DilationDims>()[dim] * - (mAttributes->template getAttr<ConvAttr::KernelDims>()[dim] - 1) + + for (std::size_t dim = 0; dim < mAttributes->template getAttr<Attr::KernelDims>().size(); ++dim) { + const DimSize_t kernelExtent = mAttributes->template getAttr<Attr::DilationDims>()[dim] * + (mAttributes->template getAttr<Attr::KernelDims>()[dim] - 1) + 1; - + outputDims[dim + out_dims_index] = 1 + static_cast<DimSize_t>( floor(static_cast<float>(inputDims[dim + in_dims_index] - kernelExtent) / - static_cast<float>(mAttributes->template getAttr<ConvAttr::StrideDims>()[dim])) + static_cast<float>(mAttributes->template getAttr<Attr::StrideDims>()[dim])) ); } - if(getOutput(0)->dataFormat() == Aidge::DataFormat::NHWC) + if(getOutput(0)->dataFormat() == Aidge::DataFormat::NHWC) outputDims[DIM+1] = outChannels(); - else + else outputDims[1] = outChannels(); outputDims[0] = inputDims[0]; mOutputs[0]->resize(outputDims); return true; - - + + } template <Aidge::DimIdx_t DIM> @@ -122,18 +123,18 @@ Aidge::Conv_Op<DIM>::computeReceptiveField( std::vector<DimSize_t> inputDims{outputDims[0], getInput(0)->dims()[1]}; for (DimIdx_t i = 0; i < DIM; ++i) { inputDims.push_back((outputDims[2+static_cast<std::size_t>(i)] - 1) - * mAttributes->template getAttr<ConvAttr::StrideDims>()[static_cast<std::size_t>(i)] + * mAttributes->template getAttr<Attr::StrideDims>()[static_cast<std::size_t>(i)] + 1 - + (mAttributes->template getAttr<ConvAttr::KernelDims>()[static_cast<std::size_t>(i)] - 1) - * mAttributes->template getAttr<ConvAttr::DilationDims>()[static_cast<std::size_t>(i)]); - inputIdxDims[2+i] *= mAttributes->template getAttr<ConvAttr::StrideDims>()[static_cast<std::size_t>(i)]; + + (mAttributes->template getAttr<Attr::KernelDims>()[static_cast<std::size_t>(i)] - 1) + * mAttributes->template getAttr<Attr::DilationDims>()[static_cast<std::size_t>(i)]); + inputIdxDims[2+i] *= mAttributes->template getAttr<Attr::StrideDims>()[static_cast<std::size_t>(i)]; } // Weight // same output value, every input channel is used std::vector<DimSize_t> weightDims{outputDims[1], getInput(0)->dims()[1]}; for (std::size_t i = 0; i < DIM; ++i) { - weightDims.push_back(mAttributes->template getAttr<ConvAttr::KernelDims>()[i]); + weightDims.push_back(mAttributes->template getAttr<Attr::KernelDims>()[i]); } std::vector<DimSize_t> weightIdxDims = std::vector<DimSize_t>(DIM+2, 0); weightIdxDims[0] = firstEltDims[1]; @@ -173,6 +174,28 @@ void Aidge::Conv_Op<DIM>::setBackend(const std::string &name, Aidge::DeviceIdx_t } } +template <Aidge::DimIdx_t DIM> +Aidge::DimSize_t Aidge::Conv_Op<DIM>::inChannels() const { + if (!getInput(1)) { + AIDGE_THROW_OR_ABORT(std::runtime_error, "Convolution operator has no weight Tensor associated so no specific number of input channel imposed."); + } + + // check format + if(getInput(1)->dataFormat()==Aidge::DataFormat::NHWC) + return getInput(1)->template dims<DIM+2>()[DIM+1]; + // default format is NCHW + return getInput(1)->template dims<DIM+2>()[1]; +} + +template <Aidge::DimIdx_t DIM> +Aidge::DimSize_t Aidge::Conv_Op<DIM>::outChannels() const { + if (!getInput(1)) { + AIDGE_THROW_OR_ABORT(std::runtime_error, "Convolution operator has no weight Tensor associated so no specific number of output channel imposed."); + } + // first weight dimension for both NCHW (Cout,Cin,H,W) and NHWC (Cout,H,W,Cin) data format + return getInput(1)->template dims<DIM+2>()[0]; +} + template <Aidge::DimIdx_t DIM> std::set<std::string> Aidge::Conv_Op<DIM>::getAvailableBackends() const { return Registrar<Conv_Op<DIM>>::getKeys(); @@ -203,3 +226,20 @@ std::shared_ptr<Aidge::Node> Aidge::Conv(Aidge::DimSize_t inChannels, template std::shared_ptr<Aidge::Node> Aidge::Conv<1>(Aidge::DimSize_t, Aidge::DimSize_t, const std::array<Aidge::DimSize_t, 1>&, const std::string&, const std::array<Aidge::DimSize_t, 1>&, const std::array<Aidge::DimSize_t, 1>&, bool); template std::shared_ptr<Aidge::Node> Aidge::Conv<2>(Aidge::DimSize_t, Aidge::DimSize_t, const std::array<Aidge::DimSize_t, 2>&, const std::string&, const std::array<Aidge::DimSize_t, 2>&, const std::array<Aidge::DimSize_t, 2>&, bool); + +template <Aidge::DimSize_t DIM> +std::shared_ptr<Aidge::Node> Aidge::Conv( + Aidge::DimSize_t inChannels, + Aidge::DimSize_t outChannels, + Aidge::DimSize_t const (&kernelDims)[DIM], + const std::string& name, + const std::array<Aidge::DimSize_t, DIM> &strideDims, + const std::array<Aidge::DimSize_t, DIM> &dilationDims, + bool noBias) +{ + static_assert(DIM<=MaxDim,"Too many kernel dimensions required by Conv, not supported"); + return Conv(inChannels, outChannels, to_array(kernelDims), name, strideDims, dilationDims, noBias); +} + +template std::shared_ptr<Aidge::Node> Aidge::Conv<1>(Aidge::DimSize_t, Aidge::DimSize_t, Aidge::DimSize_t const (&)[1], const std::string&, const std::array<Aidge::DimSize_t, 1>&, const std::array<Aidge::DimSize_t, 1>&, bool); +template std::shared_ptr<Aidge::Node> Aidge::Conv<2>(Aidge::DimSize_t, Aidge::DimSize_t, Aidge::DimSize_t const (&)[2], const std::string&, const std::array<Aidge::DimSize_t, 2>&, const std::array<Aidge::DimSize_t, 2>&, bool); \ No newline at end of file diff --git a/src/operator/Gather.cpp b/src/operator/Gather.cpp index e0990437a06d5b9fb72cf1909d78f6094120bf80..10e20046f0565d098275141e90e920ce78725e0f 100644 --- a/src/operator/Gather.cpp +++ b/src/operator/Gather.cpp @@ -28,9 +28,9 @@ Aidge::Gather_Op::Gather_Op(std::int8_t axis, const std::vector<Aidge::DimSize_t>& gatheredShape) : OperatorTensor(Type, {InputCategory::Data, InputCategory::OptionalData}, 1), mAttributes(std::make_shared<Attributes_>( - attr<GatherAttr::Axis>(axis), - attr<GatherAttr::Indices>(indices), - attr<GatherAttr::GatheredShape>(gatheredShape))) + attr<Attr::Axis>(axis), + attr<Attr::Indices>(indices), + attr<Attr::GatheredShape>(gatheredShape))) { mImpl = std::make_shared<Gather_OpImpl>(*this); } diff --git a/src/operator/Heaviside.cpp b/src/operator/Heaviside.cpp index 9ecb3b436d8312ef479d6bc0592cfe372235fa25..6555a530bd02edf6f1823469297d289fb4b57b87 100644 --- a/src/operator/Heaviside.cpp +++ b/src/operator/Heaviside.cpp @@ -30,7 +30,7 @@ const std::string Heaviside_Op::Type = "Heaviside"; Heaviside_Op::Heaviside_Op(float value) : OperatorTensor(Type, {InputCategory::Data}, 1), mAttributes( - std::make_shared<Attributes_>(attr<HeavisideAttr::Value>(value))) {} + std::make_shared<Attributes_>(attr<Attr::Value>(value))) {} Heaviside_Op::Heaviside_Op(const Heaviside_Op &op) : OperatorTensor(op), mAttributes(op.mAttributes) { diff --git a/src/operator/LRN.cpp b/src/operator/LRN.cpp index c5ce243bd6a48ae4b1ce8461924b498c804b53e6..5b7d663e78cf92047e3ed47212f2a27d42a8de49 100644 --- a/src/operator/LRN.cpp +++ b/src/operator/LRN.cpp @@ -23,10 +23,10 @@ const std::string Aidge::LRN_Op::Type = "LRN"; Aidge::LRN_Op::LRN_Op(std::int32_t size) : OperatorTensor(Type, {InputCategory::Data}, 1), mAttributes(std::make_shared<Attributes_>( - attr<LRNAttr::Alpha>(0.0001), - attr<LRNAttr::Beta>(0.75), - attr<LRNAttr::Bias>(1.0), - attr<LRNAttr::Size>(size))) + attr<Attr::Alpha>(0.0001), + attr<Attr::Beta>(0.75), + attr<Attr::Bias>(1.0), + attr<Attr::Size>(size))) {} Aidge::LRN_Op::LRN_Op(const Aidge::LRN_Op& op) diff --git a/src/operator/Memorize.cpp b/src/operator/Memorize.cpp index c4f0bc4bf7267d24264652d5ed6b0d50935e1aa4..76d3ddd22e113f087f5afc0ebb358edce0b0fc32 100644 --- a/src/operator/Memorize.cpp +++ b/src/operator/Memorize.cpp @@ -78,9 +78,9 @@ const std::string Aidge::Memorize_Op::Type = "Memorize"; Aidge::Memorize_Op::Memorize_Op(const std::uint32_t endStep) : OperatorTensor(Type, {InputCategory::Data, InputCategory::Data}, 2), mAttributes(std::make_shared<Attributes_>( - attr<MemorizeAttr::ScheduleStep>(0), - attr<MemorizeAttr::ForwardStep>(0), - attr<MemorizeAttr::EndStep>(endStep))) + attr<Attr::ScheduleStep>(0), + attr<Attr::ForwardStep>(0), + attr<Attr::EndStep>(endStep))) { // The input idx 0 is a back edge for Memorize where inputs are (back, init) setBackEdges({0}); @@ -106,8 +106,8 @@ std::shared_ptr<Aidge::Operator> Aidge::Memorize_Op::clone() const { void Aidge::Memorize_Op::updateConsummerProducer() { Operator::updateConsummerProducer(); - ++mAttributes->template getAttr<MemorizeAttr::ScheduleStep>(); - mAttributes->template getAttr<MemorizeAttr::ForwardStep>() = 0; + ++scheduleStep(); + forwardStep() = 0; } bool Aidge::Memorize_Op::forwardDims(bool /*allowDataDependency*/) { @@ -151,8 +151,8 @@ void Aidge::Memorize_Op::setBackend(const std::string& name, Aidge::DeviceIdx_t void Aidge::Memorize_Op::forward() { OperatorTensor::forward(); - ++mAttributes->template getAttr<MemorizeAttr::ForwardStep>(); - mAttributes->template getAttr<MemorizeAttr::ScheduleStep>() = 0; + ++forwardStep(); + scheduleStep() = 0; } std::set<std::string> Aidge::Memorize_Op::getAvailableBackends() const { diff --git a/src/operator/Producer.cpp b/src/operator/Producer.cpp index 9af4586886fc98c50862672392d3b704e6bc1d0c..0beaf91b3a31ee9347a91ae4b77287ac0abcdc20 100644 --- a/src/operator/Producer.cpp +++ b/src/operator/Producer.cpp @@ -32,7 +32,7 @@ Aidge::Producer_Op::Producer_Op( bool constant) : OperatorTensor(Type, {}, 1), mAttributes(std::make_shared<Attributes_>( - attr<ProdAttr::Constant>(constant))) + attr<ProducerAttr::Constant>(constant))) { mOutputs[0]->resize(dims); mImpl = std::make_shared<OperatorImpl>(*this); @@ -41,7 +41,7 @@ Aidge::Producer_Op::Producer_Op( Aidge::Producer_Op::Producer_Op(const std::shared_ptr<Aidge::Tensor> tensor, bool constant) : OperatorTensor(Type, {}, 1), mAttributes(std::make_shared<Attributes_>( - attr<ProdAttr::Constant>(constant))) + attr<ProducerAttr::Constant>(constant))) { mOutputs[0] = tensor; // copy the pointer of the Tensor if (mOutputs[0] && mOutputs[0]->hasImpl() && Registrar<Producer_Op>::exists({mOutputs[0]->getImpl()->backend()})){ @@ -100,7 +100,7 @@ void Aidge::Producer_Op::forward() { } void Aidge::Producer_Op::setOutput(const Aidge::IOIndex_t outputIdx, const std::shared_ptr<Aidge::Data>& data) const { - if (mAttributes->template getAttr<ProdAttr::Constant>()) { + if (mAttributes->template getAttr<ProducerAttr::Constant>()) { AIDGE_THROW_OR_ABORT(std::runtime_error, "Producer is constant, cannot update output."); } OperatorTensor::setOutput(outputIdx, data); diff --git a/src/operator/ReduceMean.cpp b/src/operator/ReduceMean.cpp index 7935edb050824af92a8f130f975aa09e41ca875f..dfaa75a4883ce2c9dcc77f89dc9f970c3f1ed2cd 100644 --- a/src/operator/ReduceMean.cpp +++ b/src/operator/ReduceMean.cpp @@ -30,9 +30,9 @@ const std::string Aidge::ReduceMean_Op::Type = "ReduceMean"; Aidge::ReduceMean_Op::ReduceMean_Op(const std::vector<std::int32_t>& axes, bool keep_dims, bool noop_with_empty_axes) : OperatorTensor(Type, {InputCategory::Data}, 1), mAttributes(std::make_shared<Attributes_>( - attr<ReduceMeanAttr::Axes>(axes), - attr<ReduceMeanAttr::KeepDims>(keep_dims), - attr<ReduceMeanAttr::NoopWithEmptyAxes>(noop_with_empty_axes))) + attr<Attr::Axes>(axes), + attr<Attr::KeepDims>(keep_dims), + attr<Attr::NoopWithEmptyAxes>(noop_with_empty_axes))) {} Aidge::ReduceMean_Op::ReduceMean_Op(const Aidge::ReduceMean_Op& op) @@ -53,32 +53,32 @@ std::shared_ptr<Aidge::Operator> Aidge::ReduceMean_Op::clone() const { bool Aidge::ReduceMean_Op::forwardDims(bool /*allowDataDependency*/) { if (inputsAssociated()) { // make Axes attribute positive - std::vector<std::int32_t>& axes = mAttributes->template getAttr<ReduceMeanAttr::Axes>(); - std::for_each(axes.begin(), axes.end(), [&] (std::int32_t& val) { + std::vector<std::int32_t>& reduced_axes = axes(); + std::for_each(reduced_axes.begin(), reduced_axes.end(), [&] (std::int32_t& val) { if (val < 0) val+=static_cast<std::int32_t>(getInput(0)->nbDims()); }); - std::sort(axes.begin(), axes.end()); + std::sort(reduced_axes.begin(), reduced_axes.end()); // build output dimensions std::vector<DimSize_t> outDims = getInput(0)->dims(); - if (axes.empty()) + if (reduced_axes.empty()) { - if(mAttributes->template getAttr<ReduceMeanAttr::NoopWithEmptyAxes>()) { + if(noopWithEmptyAxes()) { mOutputs[0]->resize(outDims); return true; } // if no axes are provided and NoopWithEmptyAxes is false, reduce on all axes - axes.resize(getInput(0)->nbDims()); - std::iota(axes.begin(), axes.end(), 0); + reduced_axes.resize(getInput(0)->nbDims()); + std::iota(reduced_axes.begin(), reduced_axes.end(), 0); } - if (mAttributes->template getAttr<ReduceMeanAttr::KeepDims>()) { - std::for_each(axes.cbegin(), axes.cend(), [&outDims] (const std::int32_t& val) { outDims[val] = 1; }); + if (keepDims()) { + std::for_each(reduced_axes.cbegin(), reduced_axes.cend(), [&outDims] (const std::int32_t& val) { outDims[val] = 1; }); } else { - for (auto it = axes.crbegin(); it != axes.crend(); ++it) + for (auto it = reduced_axes.crbegin(); it != reduced_axes.crend(); ++it) outDims.erase(outDims.begin() + static_cast<std::size_t>(*it)); } diff --git a/src/operator/ReduceSum.cpp b/src/operator/ReduceSum.cpp index 0786f53c6b761e5cd9020352a2ecb92469a609d7..73b6722e15ebc7a32cbb502e83d5779558c1cac7 100644 --- a/src/operator/ReduceSum.cpp +++ b/src/operator/ReduceSum.cpp @@ -30,32 +30,32 @@ const std::string Aidge::ReduceSum_Op::Type = "ReduceSum"; bool Aidge::ReduceSum_Op::forwardDims(bool /*allowDataDependency*/) { if (inputsAssociated()) { // make Axes attribute positive - std::vector<std::int32_t>& axes = mAttributes->template getAttr<ReduceSumAttr::Axes>(); - std::for_each(axes.begin(), axes.end(), [&] (std::int32_t& val) { + std::vector<std::int32_t>& reduced_axes = axes(); + std::for_each(reduced_axes.begin(), reduced_axes.end(), [&] (std::int32_t& val) { if (val < 0) val+=static_cast<std::int32_t>(getInput(0)->nbDims()); }); - std::sort(axes.begin(), axes.end()); + std::sort(reduced_axes.begin(), reduced_axes.end()); // build output dimensions std::vector<DimSize_t> outDims = getInput(0)->dims(); - if (axes.empty()) + if (reduced_axes.empty()) { - if(mAttributes->template getAttr<ReduceSumAttr::NoopWithEmptyAxes>()) { + if(noopWithEmptyAxes()) { mOutputs[0]->resize(outDims); return true; } // if no axes are provided and NoopWithEmptyAxes is false, reduce on all axes - axes.resize(getInput(0)->nbDims()); - std::iota(axes.begin(), axes.end(), 0); + reduced_axes.resize(getInput(0)->nbDims()); + std::iota(reduced_axes.begin(), reduced_axes.end(), 0); } - if (mAttributes->template getAttr<ReduceSumAttr::KeepDims>()) { - std::for_each(axes.cbegin(), axes.cend(), [&outDims] (const std::int32_t& val) { outDims[val] = 1; }); + if (keepDims()) { + std::for_each(reduced_axes.cbegin(), reduced_axes.cend(), [&outDims] (const std::int32_t& val) { outDims[val] = 1; }); } else { - for (auto it = axes.crbegin(); it != axes.crend(); ++it) + for (auto it = reduced_axes.crbegin(); it != reduced_axes.crend(); ++it) outDims.erase(outDims.begin() + static_cast<std::size_t>(*it)); } diff --git a/src/operator/Transpose.cpp b/src/operator/Transpose.cpp index b550db16dfee8286242df7cfbed9b3b300ee96d5..f9d612353a5fe8764419d6ac2f7fe1702f2a5df8 100644 --- a/src/operator/Transpose.cpp +++ b/src/operator/Transpose.cpp @@ -35,7 +35,7 @@ const std::string Aidge::Transpose_Op::Type = "Transpose"; Aidge::Transpose_Op::Transpose_Op(const std::vector<Aidge::DimSize_t> &outputDimsOrder) : OperatorTensor(Type, {InputCategory::Data}, 1), mAttributes(std::make_shared<Attributes_>( - attr<TransposeAttr::OutputDimsOrder>(outputDimsOrder))) + attr<Attr::OutputDimsOrder>(outputDimsOrder))) { mImpl = std::make_shared<TransposeImpl>(*this); }