diff --git a/include/aidge/aidge.hpp b/include/aidge/aidge.hpp index cfda3ac7fa024f8cf80b4589d978b9b5bff5b4f0..0ae6d89ae6de36ed7fd4ef9f48ba527de1e898e1 100644 --- a/include/aidge/aidge.hpp +++ b/include/aidge/aidge.hpp @@ -42,8 +42,9 @@ #include "aidge/operator/Softmax.hpp" #include "aidge/operator/Scaling.hpp" #include "aidge/scheduler/Scheduler.hpp" -#include "aidge/utils/CParameter.hpp" -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/Parameters.hpp" +#include "aidge/utils/StaticParameters.hpp" +#include "aidge/utils/DynamicParameters.hpp" #include "aidge/utils/Recipies.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" diff --git a/include/aidge/data/Data.hpp b/include/aidge/data/Data.hpp index 81b7810a8a548df7e5a2829b1a31cbe337491382..652ca1f7c7ee3efcd1de7275529970845f7a4a25 100644 --- a/include/aidge/data/Data.hpp +++ b/include/aidge/data/Data.hpp @@ -12,7 +12,7 @@ #ifndef AIDGE_DATA_H_ #define AIDGE_DATA_H_ -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/Parameters.hpp" namespace Aidge { enum class DataType { diff --git a/include/aidge/hook/hook.hpp b/include/aidge/hook/hook.hpp index 0448659b937c3498f57cae9935196ef2f38ecf6d..661f78e573bc624c2d3385cb82b3f47f8de1e3b5 100644 --- a/include/aidge/hook/hook.hpp +++ b/include/aidge/hook/hook.hpp @@ -17,7 +17,7 @@ #ifndef Hook_H_ #define Hook_H_ -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/Parameters.hpp" #include "aidge/utils/Registrar.hpp" #include <memory> diff --git a/include/aidge/operator/AvgPooling.hpp b/include/aidge/operator/AvgPooling.hpp index bf76bd45893b43043b81cd6563c500be27c66b42..63ac52d54e850b8c290ea2345970cbb83e93fb21 100644 --- a/include/aidge/operator/AvgPooling.hpp +++ b/include/aidge/operator/AvgPooling.hpp @@ -21,7 +21,7 @@ #include "aidge/graph/Node.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/operator/Producer.hpp" -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/StaticParameters.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" @@ -31,7 +31,7 @@ enum class AvgPoolingParam { StrideDims, KernelDims, PaddingDims }; template <DimIdx_t DIM> class AvgPooling_Op : public Operator, public Registrable<AvgPooling_Op<DIM>, std::string, std::unique_ptr<OperatorImpl>(const AvgPooling_Op<DIM> &)>, - public Parameterizable<AvgPoolingParam, + public StaticParameters<AvgPoolingParam, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, std::array<DimSize_t, (DIM<<1) >> { @@ -45,18 +45,18 @@ public: AvgPooling_Op() = delete; - using Parameterizable_ = Parameterizable<AvgPoolingParam, + using Parameters_ = StaticParameters<AvgPoolingParam, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, std::array<DimSize_t, (DIM<<1)> >; template <AvgPoolingParam e> - using param = typename Parameterizable_::template param<e>; + using param = typename Parameters_::template param<e>; constexpr AvgPooling_Op(const std::array<DimSize_t, DIM> &kernel_dims, const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1), const std::array<DimSize_t, (DIM<<1)> &padding_dims = create_array<DimSize_t,(DIM<<1)>(0)) : Operator(Type), - Parameterizable_(param<AvgPoolingParam::StrideDims>(stride_dims), + Parameters_(param<AvgPoolingParam::StrideDims>(stride_dims), param<AvgPoolingParam::KernelDims>(kernel_dims), param<AvgPoolingParam::PaddingDims>(padding_dims)), mOutput(std::make_shared<Tensor>()) { diff --git a/include/aidge/operator/BatchNorm.hpp b/include/aidge/operator/BatchNorm.hpp index 6861c1359737f3f344f0c7d9b2d12c9ff35b88ad..f308cc24932cff4e717edf3993a8682d6a3f4eca 100644 --- a/include/aidge/operator/BatchNorm.hpp +++ b/include/aidge/operator/BatchNorm.hpp @@ -21,7 +21,7 @@ #include "aidge/graph/Node.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/operator/Producer.hpp" -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/StaticParameters.hpp" #include "aidge/utils/Registrar.hpp" namespace Aidge { @@ -31,7 +31,7 @@ enum class BatchNormParam { Epsilon, Momentum }; template <DimIdx_t DIM> class BatchNorm_Op : public Operator, public Registrable<BatchNorm_Op<DIM>, std::string, std::unique_ptr<OperatorImpl>(const BatchNorm_Op<DIM> &)>, - public Parameterizable<BatchNormParam, float, float> { + public StaticParameters<BatchNormParam, float, float> { public: // FIXME: change accessibility std::array<std::shared_ptr<Tensor>, 5> mInputs = {std::make_shared<Tensor>(), std::make_shared<Tensor>(), @@ -44,13 +44,13 @@ public: BatchNorm_Op() = delete; - using Parameterizable_ = Parameterizable<BatchNormParam, float, float>; + using Parameters_ = StaticParameters<BatchNormParam, float, float>; template <BatchNormParam e> - using param = typename Parameterizable_::template param<e>; + using param = typename Parameters_::template param<e>; constexpr BatchNorm_Op(float epsilon, float momentum) : Operator(Type), - Parameterizable_(param<BatchNormParam::Epsilon>(epsilon), + Parameters_(param<BatchNormParam::Epsilon>(epsilon), param<BatchNormParam::Momentum>(momentum)), mOutput(std::make_shared<Tensor>()) { setDatatype(DataType::Float32); diff --git a/include/aidge/operator/Conv.hpp b/include/aidge/operator/Conv.hpp index 1edc94b96763cc163646037a8bd069023511df67..868bc7af181414741c492d91557b25b915489cc5 100644 --- a/include/aidge/operator/Conv.hpp +++ b/include/aidge/operator/Conv.hpp @@ -21,7 +21,7 @@ #include "aidge/graph/Node.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/operator/Producer.hpp" -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/StaticParameters.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" @@ -31,7 +31,7 @@ enum class ConvParam { StrideDims, DilationDims, InChannels, OutChannels, Kernel template <DimIdx_t DIM> class Conv_Op : public Operator, public Registrable<Conv_Op<DIM>, std::string, std::unique_ptr<OperatorImpl>(const Conv_Op<DIM> &)>, - public Parameterizable<ConvParam, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, DimSize_t, + public StaticParameters<ConvParam, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, DimSize_t, DimSize_t, std::array<DimSize_t, DIM>, std::array<DimSize_t, (DIM<<1) >> { public: // FIXME: change accessibility @@ -44,10 +44,10 @@ public: Conv_Op() = delete; - using Parameterizable_ = Parameterizable<ConvParam, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, + using Parameters_ = StaticParameters<ConvParam, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, DimSize_t, DimSize_t, std::array<DimSize_t, DIM>, std::array<DimSize_t, (DIM<<1) >>; template <ConvParam e> - using param = typename Parameterizable_::template param<e>; + using param = typename Parameters_::template param<e>; constexpr Conv_Op(DimSize_t in_channels, DimSize_t out_channels, @@ -56,7 +56,7 @@ public: const std::array<DimSize_t, (DIM<<1)> &padding_dims = create_array<DimSize_t,(DIM<<1)>(0), const std::array<DimSize_t, DIM> &dilation_dims = create_array<DimSize_t,DIM>(1)) : Operator(Type), - Parameterizable_(param<ConvParam::StrideDims>(stride_dims), + Parameters_(param<ConvParam::StrideDims>(stride_dims), param<ConvParam::DilationDims>(dilation_dims), param<ConvParam::InChannels>(in_channels), param<ConvParam::OutChannels>(out_channels), diff --git a/include/aidge/operator/ConvDepthWise.hpp b/include/aidge/operator/ConvDepthWise.hpp index 95a2ff55b70dbed9299fb3dca98fb9b0e700d210..ac6580a8e8fe394271445632bc879db4da45599c 100644 --- a/include/aidge/operator/ConvDepthWise.hpp +++ b/include/aidge/operator/ConvDepthWise.hpp @@ -21,7 +21,7 @@ #include "aidge/graph/Node.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/operator/Producer.hpp" -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/StaticParameters.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" @@ -31,7 +31,7 @@ enum class ConvDepthWiseParam { StrideDims, DilationDims, Channels, KernelDims, template <DimIdx_t DIM> class ConvDepthWise_Op : public Operator, public Registrable<ConvDepthWise_Op<DIM>, std::string, std::unique_ptr<OperatorImpl>(const ConvDepthWise_Op<DIM> &)>, - public Parameterizable<ConvDepthWiseParam, + public StaticParameters<ConvDepthWiseParam, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, DimSize_t, @@ -48,21 +48,21 @@ class ConvDepthWise_Op : public Operator, ConvDepthWise_Op() = delete; - using Parameterizable_ = Parameterizable<ConvDepthWiseParam, + using Parameters_ = StaticParameters<ConvDepthWiseParam, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, DimSize_t, std::array<DimSize_t, DIM>, std::array<DimSize_t, (DIM<<1) >>; template <ConvDepthWiseParam e> - using param = typename Parameterizable_::template param<e>; + using param = typename Parameters_::template param<e>; constexpr ConvDepthWise_Op(const std::array<DimSize_t, DIM> &kernel_dims, const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1), const std::array<DimSize_t, (DIM<<1)> &padding_dims = create_array<DimSize_t,(DIM<<1)>(0), const std::array<DimSize_t, DIM> &dilation_dims = create_array<DimSize_t,DIM>(1)) : Operator(Type), - Parameterizable_(param<ConvDepthWiseParam::StrideDims>(stride_dims), + Parameters_(param<ConvDepthWiseParam::StrideDims>(stride_dims), param<ConvDepthWiseParam::DilationDims>(dilation_dims), param<ConvDepthWiseParam::Channels>(0), param<ConvDepthWiseParam::KernelDims>(kernel_dims), diff --git a/include/aidge/operator/FC.hpp b/include/aidge/operator/FC.hpp index db92dc9c735416d250fa32e2f9010b21b8f808c0..3f36f11d235f2ad240d42c66a493dc8a6d7a9bfc 100644 --- a/include/aidge/operator/FC.hpp +++ b/include/aidge/operator/FC.hpp @@ -23,7 +23,7 @@ #include "aidge/graph/Node.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/operator/Producer.hpp" -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/StaticParameters.hpp" #include "aidge/utils/Registrar.hpp" namespace Aidge { @@ -33,7 +33,7 @@ class FC_Op : public Operator, public Registrable<FC_Op, std::string, std::unique_ptr<OperatorImpl>(const FC_Op &)>, - public Parameterizable<FCParam, DimSize_t, bool> { + public StaticParameters<FCParam, DimSize_t, bool> { public: // FIXME: change accessibility std::array<std::shared_ptr<Tensor>, 3> mInputs = {std::make_shared<Tensor>(), std::make_shared<Tensor>(), std::make_shared<Tensor>()}; @@ -44,12 +44,12 @@ public: FC_Op() = delete; - using Parameterizable_ = Parameterizable<FCParam, DimSize_t, bool>; - template <FCParam e> using param = typename Parameterizable_::template param<e>; + using Parameters_ = StaticParameters<FCParam, DimSize_t, bool>; + template <FCParam e> using param = typename Parameters_::template param<e>; FC_Op(DimSize_t out_channels, bool noBias) : Operator(Type), - Parameterizable_( + Parameters_( param<FCParam::OutChannels>(out_channels), param<FCParam::NoBias>(noBias)), mOutput(std::make_shared<Tensor>()) diff --git a/include/aidge/operator/GenericOperator.hpp b/include/aidge/operator/GenericOperator.hpp index 12fb7e16741e9f7ad96d51b0b847b91265c3a7d2..9561dd12df49e09e02d202a93e903ac2296f0c01 100644 --- a/include/aidge/operator/GenericOperator.hpp +++ b/include/aidge/operator/GenericOperator.hpp @@ -19,16 +19,16 @@ #include "aidge/graph/Node.hpp" #include "aidge/operator/Operator.hpp" -#include "aidge/utils/CParameter.hpp" +#include "aidge/utils/DynamicParameters.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" namespace Aidge { class GenericOperator_Op : public Operator, - public Registrable<GenericOperator_Op, std::string, std::unique_ptr<OperatorImpl>(std::shared_ptr<GenericOperator_Op>)> { + public Registrable<GenericOperator_Op, std::string, std::unique_ptr<OperatorImpl>(std::shared_ptr<GenericOperator_Op>)>, + public DynamicParameters { private: - CParameter mParams; IOIndex_t mNbDataIn; IOIndex_t mNbIn; IOIndex_t mNbOut; @@ -49,46 +49,6 @@ class GenericOperator_Op } } - /** - * @brief Get the Parameter object identified by its name. - * @tparam T expected parameter type. - * @param key Parameter name. - * @details assert if T is not the actual parameter type, if the parameter - * does not exist or internal parameter position is invalid. - * @todo Returning a T const& ? But dangerous => may get an address within - * param buffer that will get invalid after the CParam death. - * @note at() throws if the parameter does not exist, using find to test - * for parameter existance - * @return template<class T> The parameter. - */ - template <class T> - const T& getParameter(std::string const &key) const { - return mParams.Get<const T>(key); - } - - template <class T> - T& getParameter(std::string const &key) { - return mParams.Get<T>(key); - } - - ///\brief Add a parameter value, identified by its name - ///\tparam T expected parameter type - ///\param i_ParamName Parameter name - ///\param i_Value Parameter value - ///\todo Pass i_Value by ref if large or not trivial - ///\bug If parameter already exists, its value is changed but written in the - /// internal buffer in a new location (previous value is still in memory at - /// its previous location) - template <class T> - void addParameter(std::string const &key, T&& value) { - mParams.Add<T>(key, std::forward<T>(value)); - } - - - std::string getParameterType(std::string const &key) { return mParams.getParamType(key); } - - std::vector<std::string> getParametersName() { return mParams.getParametersName(); } - // Override Virtual Opertor methods void associateInput(const IOIndex_t /*inputIdx*/, std::shared_ptr<Data> /*data*/) override final { printf("Info: using associateInput() on a GenericOperator.\n"); diff --git a/include/aidge/operator/LeakyReLU.hpp b/include/aidge/operator/LeakyReLU.hpp index 1dff2550a42245351afab5b8bb1a708a8d0d8c0b..f9f4c6fd475022d673c6bbb441c090701ed4d74d 100644 --- a/include/aidge/operator/LeakyReLU.hpp +++ b/include/aidge/operator/LeakyReLU.hpp @@ -15,7 +15,7 @@ #include <vector> #include <memory> -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/StaticParameters.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/backend/OperatorImpl.hpp" @@ -31,7 +31,7 @@ enum class LeakyReLUParam { class LeakyReLU_Op : public Operator, public Registrable<LeakyReLU_Op, std::string, std::unique_ptr<OperatorImpl>(const LeakyReLU_Op&)>, - public Parameterizable<LeakyReLUParam, float> { + public StaticParameters<LeakyReLUParam, float> { public: // FIXME: change accessibility std::shared_ptr<Tensor> mInput = std::make_shared<Tensor>(); @@ -42,12 +42,12 @@ public: LeakyReLU_Op() = delete; - using Parameterizable_ = Parameterizable<LeakyReLUParam, float>; - template <LeakyReLUParam e> using param = typename Parameterizable_::template param<e>; + using Parameters_ = StaticParameters<LeakyReLUParam, float>; + template <LeakyReLUParam e> using param = typename Parameters_::template param<e>; LeakyReLU_Op(float negativeSlope) : Operator(Type), - Parameterizable_( + Parameters_( param<LeakyReLUParam::NegativeSlope>(negativeSlope)) { setDatatype(DataType::Float32); diff --git a/include/aidge/operator/Matmul.hpp b/include/aidge/operator/Matmul.hpp index 639b366912060b3e085510f312d94568e6b65f03..e768bf7e437ae7474358c90e759af2a4ebd12ada 100644 --- a/include/aidge/operator/Matmul.hpp +++ b/include/aidge/operator/Matmul.hpp @@ -23,7 +23,7 @@ #include "aidge/graph/Node.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/operator/Producer.hpp" -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/StaticParameters.hpp" #include "aidge/utils/Registrar.hpp" namespace Aidge { @@ -33,7 +33,7 @@ class Matmul_Op : public Operator, public Registrable<Matmul_Op, std::string, std::unique_ptr<OperatorImpl>(const Matmul_Op &)>, - public Parameterizable<MatmulParam, DimSize_t> { + public StaticParameters<MatmulParam, DimSize_t> { public: std::array<std::shared_ptr<Tensor>, 2> mInputs = {std::make_shared<Tensor>(), std::make_shared<Tensor>()}; const std::shared_ptr<Tensor> mOutput = std::make_shared<Tensor>(); @@ -43,12 +43,12 @@ public: Matmul_Op() = delete; - using Parameterizable_ = Parameterizable<MatmulParam, DimSize_t>; - template <MatmulParam e> using param = typename Parameterizable_::template param<e>; + using Parameters_ = StaticParameters<MatmulParam, DimSize_t>; + template <MatmulParam e> using param = typename Parameters_::template param<e>; Matmul_Op(DimSize_t out_channels) : Operator(Type), - Parameterizable_( + Parameters_( param<MatmulParam::OutChannels>(out_channels)), mOutput(std::make_shared<Tensor>()) { diff --git a/include/aidge/operator/MaxPooling.hpp b/include/aidge/operator/MaxPooling.hpp index 073243e801c6e1297129424b0c93b1a7c4f112f3..cf85af9b45d58d26a25fd9e6e041ae587670b2b1 100644 --- a/include/aidge/operator/MaxPooling.hpp +++ b/include/aidge/operator/MaxPooling.hpp @@ -21,7 +21,7 @@ #include "aidge/graph/Node.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/operator/Producer.hpp" -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/StaticParameters.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" @@ -31,7 +31,7 @@ enum class MaxPoolingParam { StrideDims, KernelDims, PaddingDims }; template <DimIdx_t DIM> class MaxPooling_Op : public Operator, public Registrable<MaxPooling_Op<DIM>, std::string, std::unique_ptr<OperatorImpl>(const MaxPooling_Op<DIM> &)>, - public Parameterizable<MaxPoolingParam, + public StaticParameters<MaxPoolingParam, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, std::array<DimSize_t, (DIM<<1) >> { @@ -45,18 +45,18 @@ public: MaxPooling_Op() = delete; - using Parameterizable_ = Parameterizable<MaxPoolingParam, + using Parameters_ = StaticParameters<MaxPoolingParam, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, std::array<DimSize_t, (DIM<<1)> >; template <MaxPoolingParam e> - using param = typename Parameterizable_::template param<e>; + using param = typename Parameters_::template param<e>; constexpr MaxPooling_Op(const std::array<DimSize_t, DIM> &kernel_dims, const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1), const std::array<DimSize_t, (DIM<<1)> &padding_dims = create_array<DimSize_t,(DIM<<1)>(0)) : Operator(Type), - Parameterizable_(param<MaxPoolingParam::StrideDims>(stride_dims), + Parameters_(param<MaxPoolingParam::StrideDims>(stride_dims), param<MaxPoolingParam::KernelDims>(kernel_dims), param<MaxPoolingParam::PaddingDims>(padding_dims)), mOutput(std::make_shared<Tensor>()) { diff --git a/include/aidge/operator/Producer.hpp b/include/aidge/operator/Producer.hpp index acdc69b69ab86b25a11d889980b9236e41928316..e2f6daa4a0380e18331ff5cb7a94fb9b0828d65f 100644 --- a/include/aidge/operator/Producer.hpp +++ b/include/aidge/operator/Producer.hpp @@ -19,7 +19,7 @@ #include "aidge/data/Tensor.hpp" #include "aidge/graph/Node.hpp" #include "aidge/operator/Operator.hpp" -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/StaticParameters.hpp" #include "aidge/utils/Registrar.hpp" namespace Aidge { diff --git a/include/aidge/operator/Scaling.hpp b/include/aidge/operator/Scaling.hpp index e158ecd7567eb683558d9e09a6cf03e5cc35ce42..3499b501b35f72520a51db3cbeb10dadc51a4be4 100644 --- a/include/aidge/operator/Scaling.hpp +++ b/include/aidge/operator/Scaling.hpp @@ -17,7 +17,7 @@ -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/StaticParameters.hpp" #include "aidge/utils/Registrar.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/backend/OperatorImpl.hpp" @@ -33,7 +33,7 @@ enum class ScalingParam { class Scaling_Op : public Operator, public Registrable<Scaling_Op, std::string, std::unique_ptr<OperatorImpl>(const Scaling_Op&)>, - public Parameterizable<ScalingParam, float> { + public StaticParameters<ScalingParam, float> { public: // FIXME: change accessibility std::shared_ptr<Tensor> mInput = std::make_shared<Tensor>(); @@ -44,12 +44,12 @@ public: Scaling_Op() = delete; - using Parameterizable_ = Parameterizable<ScalingParam, float>; - template <ScalingParam e> using param = typename Parameterizable_::template param<e>; + using Parameters_ = StaticParameters<ScalingParam, float>; + template <ScalingParam e> using param = typename Parameters_::template param<e>; Scaling_Op(float scalingFactor) : Operator(Type), - Parameterizable_( + Parameters_( param<ScalingParam::scalingFactor>(scalingFactor)) { setDatatype(DataType::Float32); diff --git a/include/aidge/utils/CParameter.hpp b/include/aidge/utils/CParameter.hpp deleted file mode 100644 index 7d60ed239ae58666833c4ce227aaf16542679036..0000000000000000000000000000000000000000 --- a/include/aidge/utils/CParameter.hpp +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 CEA-List - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - ********************************************************************************/ - -#ifndef AIDGE_CPARAMETER_H_ -#define AIDGE_CPARAMETER_H_ - -#include <map> -#include <vector> -#include <type_traits> -#include <typeinfo> -#include <assert.h> - -#include "aidge/utils/Any.hpp" - - -namespace Aidge { - -///\todo store also a fix-sized code that indicates the type -///\todo managing complex types or excluding non-trivial, non-aggregate types -class CParameter { -private: - template<typename _ValueType> - inline _ValueType& any_cast_ref(const _any& __any) - { - using _Up = std::remove_cv_t<std::remove_reference_t<_ValueType>>; - assert(((std::is_reference<_ValueType>::value || std::is_copy_constructible<_ValueType>::value) && "Template argument must be a reference or CopyConstructible type")); - assert((std::is_constructible<_ValueType, const _Up&>::value && "Template argument must be constructible from a const value.")); - assert(std::is_object<_Up>::value); - assert(__any.type() == typeid(_Up)); - if (_any::Manager<_Up>::access(&__any)) { // assess if _any object is empty - return *static_cast<_ValueType*>(_any::Manager<_Up>::access(&__any)); - } - throw std::bad_cast(); - } -public: - // not copyable, not movable - CParameter(CParameter const &) = delete; - CParameter(CParameter &&) = delete; - CParameter &operator=(CParameter const &) = delete; - CParameter &operator=(CParameter &&) = delete; - CParameter() : m_Params({}){}; - ~CParameter() = default; - - /** - * \brief Returning a parameter identified by its name - * \tparam T expected parameter type - * \param i_ParamName Parameter name - * \details assert if T is not the actual parameter type, if the parameter does not - * exist or interna parameter position is invalid. - * \todo Returning a T const& ? But dangerous => the client may get an address within - * param buffer that will get invalid after the CParam death. - * \note at() throws if the parameter does not exist, using find to test for parameter existance - */ - template<class T> T& Get(const std::string i_ParamName) - { - return any_cast_ref<T>(m_Buffer[m_Params.at(i_ParamName)]); - } - - // template<class T> const T& Get(const std::string i_ParamName) const - // { - // return any_cast<T>(m_Buffer[m_Params.at(i_ParamName)]); - // } - - ///\brief Add a parameter value, identified by its name - ///\tparam T expected parameter type - ///\param i_ParamName Parameter name - ///\param i_Value Parameter value - ///\todo Pass i_Value by ref if large or not trivial - ///\bug If parameter already exists, its value is changed but written in the - /// internal buffer in a new location (previous value is still in memory at its previous location) - template<class T> void Add(const std::string &i_ParamName, T&& i_Value) - { - m_Params[i_ParamName] = m_Buffer.size(); // Copy pointer offset - m_Buffer.push_back(_any(std::forward<T>(i_Value))); - } - - - std::string getParamType(std::string const &i_ParamName){ - return m_Buffer[m_Params.at(i_ParamName)].type().name(); - } - - std::vector<std::string> getParametersName(){ - std::vector<std::string> parametersName; - for(auto const& it: m_Params) - parametersName.push_back(it.first); - return parametersName; - } - -private: - std::map<std::string, std::size_t> m_Params; // { Param name : offset } - - ///\brief All raw pointers to parameters values concatenated. Use custom any class compatible with C++14. - std::vector<_any> m_Buffer = {}; -}; - -} - -#endif /* AIDGE_CPARAMETER_H_ */ diff --git a/include/aidge/utils/DynamicParameters.hpp b/include/aidge/utils/DynamicParameters.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3a66e5c74d7443b3d48f87a3254690b92a47627b --- /dev/null +++ b/include/aidge/utils/DynamicParameters.hpp @@ -0,0 +1,147 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#ifndef AIDGE_CORE_UTILS_DYNAMICPARAMETERS_H_ +#define AIDGE_CORE_UTILS_DYNAMICPARAMETERS_H_ + +#include <map> +#include <vector> +#include <type_traits> +#include <typeinfo> +#include <cassert> +#include <string> + +#include "aidge/utils/Any.hpp" +#include "aidge/utils/Parameters.hpp" + + +namespace Aidge { + +///\todo store also a fix-sized code that indicates the type +///\todo managing complex types or excluding non-trivial, non-aggregate types +class DynamicParameters : public Parameters { +private: + template<typename _ValueType> + inline _ValueType& any_cast_ref(const _any& __any) + { + using _Up = std::remove_cv_t<std::remove_reference_t<_ValueType>>; + assert(((std::is_reference<_ValueType>::value || std::is_copy_constructible<_ValueType>::value) && "Template argument must be a reference or CopyConstructible type")); + assert((std::is_constructible<_ValueType, const _Up&>::value && "Template argument must be constructible from a const value.")); + assert(std::is_object<_Up>::value); + assert(__any.type() == typeid(_Up)); + if (_any::Manager<_Up>::access(&__any)) { // assess if _any object is empty + return *static_cast<_ValueType*>(_any::Manager<_Up>::access(&__any)); + } + throw std::bad_cast(); + } + + template<typename _ValueType> + inline const _ValueType& any_cast_ref(const _any& __any) const + { + using _Up = std::remove_cv_t<std::remove_reference_t<_ValueType>>; + assert(((std::is_reference<_ValueType>::value || std::is_copy_constructible<_ValueType>::value) && "Template argument must be a reference or CopyConstructible type")); + assert((std::is_constructible<_ValueType, const _Up&>::value && "Template argument must be constructible from a const value.")); + assert(std::is_object<_Up>::value); + assert(__any.type() == typeid(_Up)); + if (_any::Manager<_Up>::access(&__any)) { // assess if _any object is empty + return *static_cast<const _ValueType*>(_any::Manager<_Up>::access(&__any)); + } + throw std::bad_cast(); + } +public: + /** + * \brief Returning a parameter identified by its name + * \tparam T expected parameter type + * \param name Parameter name + * \details assert if T is not the actual parameter type, if the parameter does not + * exist or interna parameter position is invalid. + * \todo Returning a T const& ? But dangerous => the client may get an address within + * param buffer that will get invalid after the CParam death. + * \note at() throws if the parameter does not exist, using find to test for parameter existance + */ + template<class T> T& getParameter(const std::string& name) + { + return any_cast_ref<T>(mBuffer[mParams.at(name)]); + } + + template<class T> const T& getParameter(const std::string& name) const + { + return any_cast_ref<T>(mBuffer[mParams.at(name)]); + } + + ///\brief Add a parameter value, identified by its name + ///\tparam T expected parameter type + ///\param name Parameter name + ///\param value Parameter value + ///\todo Pass value by ref if large or not trivial + ///\bug If parameter already exists, its value is changed but written in the + /// internal buffer in a new location (previous value is still in memory at its previous location) + template<class T> void addParameter(const std::string& name, T&& value) + { + mParams[name] = mBuffer.size(); // Copy pointer offset + mBuffer.push_back(_any(std::forward<T>(value))); + } + + ////////////////////////////////////// + /// Generic Parameters API + ////////////////////////////////////// + bool isParameter(const std::string& name) const override final { + return (mParams.find(name) != mParams.end()); + } + + std::string getParameterType(const std::string& name) const override final { + return mBuffer[mParams.at(name)].type().name(); + } + + std::vector<std::string> getParametersName() const override final { + std::vector<std::string> parametersName; + for(auto const& it: mParams) + parametersName.push_back(it.first); + return parametersName; + } + + #ifdef PYBIND + py::object getPy(const std::string& name) const { + py::object res = py::none(); + const std::string paramType = getParameterType(name); + if(paramType == typeid(int).name()) + res = py::cast(getParameter<int>(name)); + else if(paramType == typeid(float).name()) + res = py::cast(getParameter<float>(name)); + else if(paramType == typeid(bool).name()) + res = py::cast(getParameter<bool>(name)); + else if(paramType == typeid(std::string).name()) + res = py::cast(getParameter<std::string>(name)); + else if(paramType == typeid(std::vector<bool>).name()) + res = py::cast(getParameter<std::vector<bool>>(name)); + else if(paramType == typeid(std::vector<int>).name()) + res = py::cast(getParameter<std::vector<int>>(name)); + else if(paramType == typeid(std::vector<float>).name()) + res = py::cast(getParameter<std::vector<float>>(name)); + else if(paramType == typeid(std::vector<std::string>).name()) + res = py::cast(getParameter<std::vector<std::string>>(name)); + else { + throw py::key_error("Failed to convert parameter type " + name + ", this issue may come from typeid function which gave an unknown key : [" + paramType + "]. Please open an issue asking to add the support for this key."); + } + return res; + }; + #endif + +private: + std::map<std::string, std::size_t> mParams; // { Param name : offset } + + ///\brief All raw pointers to parameters values concatenated. Use custom any class compatible with C++14. + std::vector<_any> mBuffer; +}; + +} + +#endif /* AIDGE_CORE_UTILS_DYNAMICPARAMETERS_H_ */ diff --git a/include/aidge/utils/Parameters.hpp b/include/aidge/utils/Parameters.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d71a932aa495474813a8ce164acf6e5e15599253 --- /dev/null +++ b/include/aidge/utils/Parameters.hpp @@ -0,0 +1,59 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#ifndef AIDGE_CORE_UTILS_PARAMETERS_H_ +#define AIDGE_CORE_UTILS_PARAMETERS_H_ + +#ifdef PYBIND +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> +#endif +#include <vector> +#include <string> + +#ifdef PYBIND +namespace py = pybind11; +#endif + +namespace { +// This is the type that will hold all the strings. Each enumerate type will +// declare its own specialization. +template <typename T> struct EnumStrings { + static const char* const data[]; +}; +} + +namespace Aidge { +template<class T, std::size_t N> +constexpr std::size_t size(T (&)[N]) { return N; } + +/* This abstract class allows to avoid binding Parametrizable. +* Otherwise we would need to bind every template possible of Parametrizable. +* Every operators can access the methods of this class by inheriting from +* Parameters in the binding code. +*/ +class Parameters { +public: + virtual bool isParameter(const std::string& name) const = 0; + virtual std::string getParameterType(const std::string& name) const = 0; + virtual std::vector<std::string> getParametersName() const = 0; + +#ifdef PYBIND + /* Bindable get function, does not recquire any templating. + * This is thanks to py::object which allow the function to + * be agnostic from its return type. + */ + virtual py::object getPy(const std::string& name) const = 0; +#endif +}; +} + +#endif /* AIDGE_CORE_UTILS_PARAMETERS_H_ */ diff --git a/include/aidge/utils/Parameter.hpp b/include/aidge/utils/StaticParameters.hpp similarity index 69% rename from include/aidge/utils/Parameter.hpp rename to include/aidge/utils/StaticParameters.hpp index b0c6e35950187f17d991cfe5b2c9bd2b09f1e70f..1cedd584260103fb07781436cb9e7eeae134e048 100644 --- a/include/aidge/utils/Parameter.hpp +++ b/include/aidge/utils/StaticParameters.hpp @@ -1,197 +1,196 @@ -/******************************************************************************** - * Copyright (c) 2023 CEA-List - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - ********************************************************************************/ - -#ifndef AIDGE_CORE_UTILS_PARAMETER_H_ -#define AIDGE_CORE_UTILS_PARAMETER_H_ - -#ifdef PYBIND -#include <pybind11/pybind11.h> -#include <pybind11/stl.h> -#include <string> // Add this inclue to print error -#endif -#include <tuple> -#include <cassert> -#include <cstddef> - -#ifdef PYBIND -namespace py = pybind11; -#endif - -namespace { -// This is the type that will hold all the strings. Each enumerate type will -// declare its own specialization. -template <typename T> struct EnumStrings { - static const char* const data[]; -}; -} - -namespace Aidge { -template<class T, std::size_t N> -constexpr std::size_t size(T (&)[N]) { return N; } - -#ifdef PYBIND -/* This abstract class allows to avoid binding Parametrizable. -* Otherwise we would need to bind every template possible of Parametrizable. -* Every operators can access the methods of this class by inheriting from -* PyAbstractParametrizable in the binding code. -*/ -class PyAbstractParametrizable{ - public: - /* Bindable get function, does not recquire any templating. - * This is thanks to py::object which allow the function to - * be agnostic from its return type. - */ - virtual py::object getPy(const char* /*name*/) = 0; -}; -#endif - -template <class PARAM_ENUM, class ...T> -class Parameterizable -#ifdef PYBIND - : public PyAbstractParametrizable -#endif - { -public: - using Parameters = std::tuple<T...>; - - // Helper class to pass to the constructor - template <PARAM_ENUM paramEnum> - class param { - public: - constexpr param(const typename std::tuple_element<static_cast<std::size_t>(paramEnum),std::tuple<T...>>::type& v) : value(v) {} - const typename std::tuple_element<static_cast<std::size_t>(paramEnum),std::tuple<T...>>::type value; - }; - -/* - // Direct tuple initialization - Parameterizable(T... params) : mParams({params...}) { - - } -*/ - - // Constructor for parameters initialization. - // Compile-time garantee that every parameter is initialized. - template <PARAM_ENUM ...paramEnum> // non-type parameter pack - constexpr Parameterizable(const param<paramEnum>&&... params) { - // Check number of params consistency - static_assert(sizeof...(params) == std::tuple_size<std::tuple<T...>>::value, "wrong number of parameters in constructor"); - // static_assert(size(EnumStrings<PARAM_ENUM>::data) == std::tuple_size<std::tuple<T...>>::value, "wrong number of parameters in enum string"); - - // Check no duplicates - constexpr std::array<PARAM_ENUM, std::tuple_size<std::tuple<T...>>::value> pe = { paramEnum... }; - static_assert(!hasDuplicates(pe), "duplicate parameter"); // requires C++14 - - // Init params with constructor arguments - const std::array<PARAM_ENUM, std::tuple_size<std::tuple<T...>>::value> p = { ((void)(get<paramEnum>() = params.value), paramEnum) ... }; - (void)p; // avoid unused warning - } - - // Compile-time access with enum - template <PARAM_ENUM paramEnum> - constexpr typename std::tuple_element<static_cast<std::size_t>(paramEnum),std::tuple<T...>>::type& get() { - return std::get<static_cast<std::size_t>(paramEnum)>(mParams); - } - - template <PARAM_ENUM paramEnum> - constexpr const typename std::tuple_element<static_cast<std::size_t>(paramEnum),std::tuple<T...>>::type& get() const { - return std::get<static_cast<std::size_t>(paramEnum)>(mParams); - } - - // Runtime access with enum - template <typename R> - constexpr R& get(PARAM_ENUM paramEnum) { - return get<R>(static_cast<std::size_t>(paramEnum)); - } - - template <typename R> - constexpr const R& get(PARAM_ENUM paramEnum) const { - return get<R>(static_cast<std::size_t>(paramEnum)); - } - - // Runtime existance check with name - constexpr bool isParam(const char* name) const { - for (std::size_t i = 0; i < size(EnumStrings<PARAM_ENUM>::data); ++i) { - if (strcmp(EnumStrings<PARAM_ENUM>::data[i], name) == 0) { - return true; - } - } - - return false; - } - - // Runtime access with name - template <typename R> - constexpr R& get(const char* name) { - for (std::size_t i = 0; i < size(EnumStrings<PARAM_ENUM>::data); ++i) { - if (strcmp(EnumStrings<PARAM_ENUM>::data[i], name) == 0) { - return get<R>(i); - } - } - - assert(false && "parameter not found"); - } - - template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value-1> - constexpr typename std::enable_if<(SIZE > 0), R&>::type get(std::size_t i) { - if (i == SIZE) { - if (std::is_same<R, typename std::tuple_element<SIZE,std::tuple<T...>>::type>::value) { - return reinterpret_cast<R&>(std::get<SIZE>(mParams)); - } - else { - assert(false && "wrong parameter type"); - } - } - else { - return get<R, SIZE-1>(i); - } - } - - template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value-1> - constexpr typename std::enable_if<(SIZE <= 0), R&>::type get(std::size_t i) { - assert(false && "parameter not found"); - } - - constexpr const std::tuple<T...>& getParams() const { - return mParams; - } - - #ifdef PYBIND - py::object getPy(const char* name){ - for (std::size_t i = 0; i < size(EnumStrings<PARAM_ENUM>::data); ++i) { - if (strcmp(EnumStrings<PARAM_ENUM>::data[i], name) == 0) { - // https://github.com/pybind/pybind11/blob/f3e0602802c7840992c97f4960515777cad6a5c7/include/pybind11/pytypes.h#L1119-L1138 - // Normal accessor would not work has we convert the tuple to a py::object which can be anything - return py::detail::accessor_policies::tuple_item::get(py::cast(mParams), static_cast<py::size_t>(i)); - } - } - throw py::value_error("Parameter : " + std::string(name) + " does not exist." ); - }; - #endif - -private: - template <typename V, std::size_t N> - static constexpr bool hasDuplicates(const std::array<V, N>& array) { - for (std::size_t i = 1; i < N; i++) { - for (std::size_t j = 0; j < i; j++) { - if (array[i] == array[j]) { - return true; - } - } - } - - return false; - } - - std::tuple<T...> mParams; -}; -} - -#endif /* AIDGE_CORE_UTILS_PARAMETER_H_ */ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#ifndef AIDGE_CORE_UTILS_STATICPARAMETERS_H_ +#define AIDGE_CORE_UTILS_STATICPARAMETERS_H_ + +#include <tuple> +#include <cassert> +#include <cstddef> + +#include "aidge/utils/Parameters.hpp" + +namespace Aidge { +template <class PARAM_ENUM, class ...T> +class StaticParameters : public Parameters { +public: + using Params = std::tuple<T...>; + + // Helper class to pass to the constructor + template <PARAM_ENUM paramEnum> + class param { + public: + constexpr param(const typename std::tuple_element<static_cast<std::size_t>(paramEnum),std::tuple<T...>>::type& v) : value(v) {} + const typename std::tuple_element<static_cast<std::size_t>(paramEnum),std::tuple<T...>>::type value; + }; + +/* + // Direct tuple initialization + StaticParameters(T... params) : mParams({params...}) { + + } +*/ + + // Constructor for parameters initialization. + // Compile-time garantee that every parameter is initialized. + template <PARAM_ENUM ...paramEnum> // non-type parameter pack + constexpr StaticParameters(const param<paramEnum>&&... params) { + // Check number of params consistency + static_assert(sizeof...(params) == std::tuple_size<std::tuple<T...>>::value, "wrong number of parameters in constructor"); + // static_assert(size(EnumStrings<PARAM_ENUM>::data) == std::tuple_size<std::tuple<T...>>::value, "wrong number of parameters in enum string"); + + // Check no duplicates + constexpr std::array<PARAM_ENUM, std::tuple_size<std::tuple<T...>>::value> pe = { paramEnum... }; + static_assert(!hasDuplicates(pe), "duplicate parameter"); // requires C++14 + + // Init params with constructor arguments + const std::array<PARAM_ENUM, std::tuple_size<std::tuple<T...>>::value> p = { ((void)(get<paramEnum>() = params.value), paramEnum) ... }; + (void)p; // avoid unused warning + } + + // Compile-time access with enum + template <PARAM_ENUM paramEnum> + constexpr typename std::tuple_element<static_cast<std::size_t>(paramEnum),std::tuple<T...>>::type& get() { + return std::get<static_cast<std::size_t>(paramEnum)>(mParams); + } + + template <PARAM_ENUM paramEnum> + constexpr const typename std::tuple_element<static_cast<std::size_t>(paramEnum),std::tuple<T...>>::type& get() const { + return std::get<static_cast<std::size_t>(paramEnum)>(mParams); + } + + // Runtime access with enum + template <typename R> + constexpr R& get(PARAM_ENUM paramEnum) { + return get<R>(static_cast<std::size_t>(paramEnum)); + } + + template <typename R> + constexpr const R& get(PARAM_ENUM paramEnum) const { + return get<R>(static_cast<std::size_t>(paramEnum)); + } + + // Runtime access with name + template <typename R> + constexpr R& get(const char* name) { + for (std::size_t i = 0; i < size(EnumStrings<PARAM_ENUM>::data); ++i) { + if (strcmp(EnumStrings<PARAM_ENUM>::data[i], name) == 0) { + return get<R>(i); + } + } + + assert(false && "parameter not found"); + } + + template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value-1> + constexpr typename std::enable_if<(SIZE > 0), R&>::type get(std::size_t i) { + if (i == SIZE) { + if (std::is_same<R, typename std::tuple_element<SIZE,std::tuple<T...>>::type>::value) { + return reinterpret_cast<R&>(std::get<SIZE>(mParams)); + } + else { + assert(false && "wrong parameter type"); + } + } + else { + return get<R, SIZE-1>(i); + } + } + + template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value-1> + constexpr typename std::enable_if<(SIZE <= 0), R&>::type get(std::size_t /*i*/) { + assert(false && "parameter not found"); + } + + template <std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value-1> + constexpr typename std::enable_if<(SIZE > 0), std::string>::type getType(std::size_t i) const { + if (i == SIZE) { + return typeid(typename std::tuple_element<SIZE,std::tuple<T...>>::type).name(); + } + else { + return getType<SIZE-1>(i); + } + } + + template <std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value-1> + constexpr typename std::enable_if<(SIZE <= 0), std::string>::type getType(std::size_t /*i*/) const { + assert(false && "parameter not found"); + } + + constexpr const std::tuple<T...>& getStaticParameters() const { + return mParams; + } + + ////////////////////////////////////// + /// Generic Parameters API + ////////////////////////////////////// + // Runtime existance check with name + constexpr bool isParameter(const std::string& name) const override final { + for (std::size_t i = 0; i < size(EnumStrings<PARAM_ENUM>::data); ++i) { + if (name == EnumStrings<PARAM_ENUM>::data[i]) { + return true; + } + } + + return false; + } + + // Runtime type access with name + constexpr std::string getParameterType(const std::string& name) const override final { + for (std::size_t i = 0; i < size(EnumStrings<PARAM_ENUM>::data); ++i) { + if (name == EnumStrings<PARAM_ENUM>::data[i]) { + return getType(i); + } + } + + assert(false && "parameter not found"); + } + + std::vector<std::string> getParametersName() const override final { + std::vector<std::string> parametersName; + for (std::size_t i = 0; i < size(EnumStrings<PARAM_ENUM>::data); ++i) { + parametersName.push_back(EnumStrings<PARAM_ENUM>::data[i]); + } + return parametersName; + } + + #ifdef PYBIND + py::object getPy(const std::string& name) const { + for (std::size_t i = 0; i < size(EnumStrings<PARAM_ENUM>::data); ++i) { + if (name == EnumStrings<PARAM_ENUM>::data[i]) { + // https://github.com/pybind/pybind11/blob/f3e0602802c7840992c97f4960515777cad6a5c7/include/pybind11/pytypes.h#L1119-L1138 + // Normal accessor would not work has we convert the tuple to a py::object which can be anything + return py::detail::accessor_policies::tuple_item::get(py::cast(mParams), static_cast<py::size_t>(i)); + } + } + throw py::value_error("Parameter : " + name + " does not exist." ); + }; + #endif + +private: + template <typename V, std::size_t N> + static constexpr bool hasDuplicates(const std::array<V, N>& array) { + for (std::size_t i = 1; i < N; i++) { + for (std::size_t j = 0; j < i; j++) { + if (array[i] == array[j]) { + return true; + } + } + } + + return false; + } + + std::tuple<T...> mParams; +}; +} + +#endif /* AIDGE_CORE_UTILS_STATICPARAMETERS_H_ */ diff --git a/python_binding/operator/pybind_Add.cpp b/python_binding/operator/pybind_Add.cpp index 3efcf7c5345bbc835aeaf6dcbc416769b8654439..ab8b4cf7b91d5eea2db5245a8c5122ab004b4766 100644 --- a/python_binding/operator/pybind_Add.cpp +++ b/python_binding/operator/pybind_Add.cpp @@ -12,7 +12,6 @@ #include <pybind11/pybind11.h> #include "aidge/operator/Add.hpp" -#include "aidge/utils/Parameter.hpp" #include "aidge/backend/OperatorImpl.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/utils/Types.h" diff --git a/python_binding/operator/pybind_AvgPooling.cpp b/python_binding/operator/pybind_AvgPooling.cpp index ecbb743d33cc5750bc60aeed8e5207dcec0c23dc..3d44ab90ca55482a6228a09e50bdcea24b176911 100644 --- a/python_binding/operator/pybind_AvgPooling.cpp +++ b/python_binding/operator/pybind_AvgPooling.cpp @@ -16,7 +16,6 @@ #include <vector> #include <array> -#include "aidge/utils/Parameter.hpp" #include "aidge/backend/OperatorImpl.hpp" #include "aidge/operator/AvgPooling.hpp" #include "aidge/operator/Operator.hpp" @@ -27,7 +26,7 @@ namespace py = pybind11; namespace Aidge { template <DimIdx_t DIM> void declare_AvgPoolingOp(py::module &m) { - py::class_<AvgPooling_Op<DIM>, std::shared_ptr<AvgPooling_Op<DIM>>, Operator, PyAbstractParametrizable>( + py::class_<AvgPooling_Op<DIM>, std::shared_ptr<AvgPooling_Op<DIM>>, Operator, Parameters>( m, ("AvgPoolingOp" + std::to_string(DIM) + "D").c_str(), py::multiple_inheritance()) .def(py::init<const std::array<DimSize_t, DIM> &, diff --git a/python_binding/operator/pybind_BatchNorm.cpp b/python_binding/operator/pybind_BatchNorm.cpp index 70d9bce003033e1264ac39764271773fa84c760f..146d3f10b5cbe045f16d4b0616c2c7695e797a20 100644 --- a/python_binding/operator/pybind_BatchNorm.cpp +++ b/python_binding/operator/pybind_BatchNorm.cpp @@ -14,7 +14,6 @@ #include "aidge/operator/BatchNorm.hpp" #include "aidge/operator/Operator.hpp" -#include "aidge/utils/Parameter.hpp" #include "aidge/utils/Types.h" namespace py = pybind11; @@ -22,7 +21,7 @@ namespace Aidge { template <DimSize_t DIM> void declare_BatchNormOp(py::module& m) { - py::class_<BatchNorm_Op<DIM>, std::shared_ptr<BatchNorm_Op<DIM>>, Operator, PyAbstractParametrizable>(m, ("BatchNorm_Op" + std::to_string(DIM) + "D").c_str(), py::multiple_inheritance()); + py::class_<BatchNorm_Op<DIM>, std::shared_ptr<BatchNorm_Op<DIM>>, Operator, Parameters>(m, ("BatchNorm_Op" + std::to_string(DIM) + "D").c_str(), py::multiple_inheritance()); m.def(("BatchNorm" + std::to_string(DIM) + "D").c_str(), &BatchNorm<DIM>, py::arg("epsilon") = 1.0e-5F, py::arg("momentum") = 0.1F, py::arg("name") = ""); } diff --git a/python_binding/operator/pybind_Conv.cpp b/python_binding/operator/pybind_Conv.cpp index 7e366305f287e958ea7500695c1f3285908017b1..af4a5d6487cb4445350227743c8e9b1bc0676541 100644 --- a/python_binding/operator/pybind_Conv.cpp +++ b/python_binding/operator/pybind_Conv.cpp @@ -16,7 +16,6 @@ #include <vector> #include <array> -#include "aidge/utils/Parameter.hpp" #include "aidge/backend/OperatorImpl.hpp" #include "aidge/operator/Conv.hpp" #include "aidge/operator/Operator.hpp" @@ -26,7 +25,7 @@ namespace py = pybind11; namespace Aidge { template <DimIdx_t DIM> void declare_ConvOp(py::module &m) { - py::class_<Conv_Op<DIM>, std::shared_ptr<Conv_Op<DIM>>, Operator, PyAbstractParametrizable>( + py::class_<Conv_Op<DIM>, std::shared_ptr<Conv_Op<DIM>>, Operator, Parameters>( m, ("ConvOp" + std::to_string(DIM) + "D").c_str(), py::multiple_inheritance()) .def(py::init<DimSize_t, diff --git a/python_binding/operator/pybind_ConvDepthWise.cpp b/python_binding/operator/pybind_ConvDepthWise.cpp index 8a81e7ba184536cbd535db24519495400bce6fdb..333bad8bbade40cbe549429e4fbc1b88921ef099 100644 --- a/python_binding/operator/pybind_ConvDepthWise.cpp +++ b/python_binding/operator/pybind_ConvDepthWise.cpp @@ -16,7 +16,6 @@ #include <vector> #include <array> -#include "aidge/utils/Parameter.hpp" #include "aidge/backend/OperatorImpl.hpp" #include "aidge/operator/ConvDepthWise.hpp" #include "aidge/operator/Operator.hpp" @@ -27,7 +26,7 @@ namespace py = pybind11; namespace Aidge { template <DimIdx_t DIM> void declare_ConvDepthWiseOp(py::module &m) { - py::class_<ConvDepthWise_Op<DIM>, std::shared_ptr<ConvDepthWise_Op<DIM>>, Operator, PyAbstractParametrizable>( + py::class_<ConvDepthWise_Op<DIM>, std::shared_ptr<ConvDepthWise_Op<DIM>>, Operator, Parameters>( m, ("ConvDepthWiseOp" + std::to_string(DIM) + "D").c_str(), py::multiple_inheritance()) .def(py::init<const std::array<DimSize_t, DIM> &, diff --git a/python_binding/operator/pybind_FC.cpp b/python_binding/operator/pybind_FC.cpp index 3b4137c6f208f96d256c72300437cc978658b84f..963db0caae26cd0ccbdd670c9b909f56243e0613 100644 --- a/python_binding/operator/pybind_FC.cpp +++ b/python_binding/operator/pybind_FC.cpp @@ -12,7 +12,6 @@ #include <pybind11/pybind11.h> #include "aidge/operator/FC.hpp" -#include "aidge/utils/Parameter.hpp" #include "aidge/backend/OperatorImpl.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/utils/Types.h" @@ -21,7 +20,7 @@ namespace py = pybind11; namespace Aidge { void declare_FC(py::module &m) { - py::class_<FC_Op, std::shared_ptr<FC_Op>, Operator, PyAbstractParametrizable>(m, "FC_Op", py::multiple_inheritance()); + py::class_<FC_Op, std::shared_ptr<FC_Op>, Operator, Parameters>(m, "FC_Op", py::multiple_inheritance()); m.def("FC", &FC, py::arg("out_channels"), py::arg("nobias") = false, py::arg("name") = ""); } diff --git a/python_binding/operator/pybind_GenericOperator.cpp b/python_binding/operator/pybind_GenericOperator.cpp index bec59eaf2cecdc7f64d1da07580116c4b3334992..3e2c195e850b9c9b6f46c7b57fb7a2812e93f7a5 100644 --- a/python_binding/operator/pybind_GenericOperator.cpp +++ b/python_binding/operator/pybind_GenericOperator.cpp @@ -21,46 +21,7 @@ namespace Aidge { void init_GenericOperator(py::module& m) { py::class_<GenericOperator_Op, std::shared_ptr<GenericOperator_Op>, Operator>(m, "GenericOperatorOp", - py::multiple_inheritance()) - .def("get_parameter_type", &GenericOperator_Op::getParameterType) - .def("get_parameters_name", &GenericOperator_Op::getParametersName) - .def("add_parameter", &GenericOperator_Op::addParameter<bool>) - .def("add_parameter", &GenericOperator_Op::addParameter<int>) - .def("add_parameter", &GenericOperator_Op::addParameter<float>) - .def("add_parameter", &GenericOperator_Op::addParameter<std::string>) - .def("add_parameter", &GenericOperator_Op::addParameter<std::vector<bool>>) - .def("add_parameter", &GenericOperator_Op::addParameter<std::vector<int>>) - .def("add_parameter", &GenericOperator_Op::addParameter<std::vector<float>>) - .def("add_parameter", &GenericOperator_Op::addParameter<std::vector<std::string>>) - .def("get_parameter", [](GenericOperator_Op& self, std::string key) -> py::object { - /* - This getParameter method returns the good python type without having to have - prior knowledge of the parameter type. - */ - py::object res = py::none(); - std::string paramType = self.getParameterType(key); - if(paramType == typeid(int).name()) - res = py::cast(self.getParameter<int>(key)); - else if(paramType == typeid(float).name()) - res = py::cast(self.getParameter<float>(key)); - else if(paramType == typeid(bool).name()) - res = py::cast(self.getParameter<bool>(key)); - else if(paramType == typeid(std::string).name()) - res = py::cast(self.getParameter<std::string>(key)); - else if(paramType == typeid(std::vector<bool>).name()) - res = py::cast(self.getParameter<std::vector<bool>>(key)); - else if(paramType == typeid(std::vector<int>).name()) - res = py::cast(self.getParameter<std::vector<int>>(key)); - else if(paramType == typeid(std::vector<float>).name()) - res = py::cast(self.getParameter<std::vector<float>>(key)); - else if(paramType == typeid(std::vector<std::string>).name()) - res = py::cast(self.getParameter<std::vector<std::string>>(key)); - else { - throw py::key_error("Failed to convert parameter type " + key + ", this issue may come from typeid function which gave an unknown key : [" + paramType + "]. Please open an issue asking to add the support for this key."); - } - return res; - }); - + py::multiple_inheritance()); m.def("GenericOperator", &GenericOperator, py::arg("type"), py::arg("nbDataIn"), py::arg("nbIn"), py::arg("nbOut"), py::arg("name") = ""); } diff --git a/python_binding/operator/pybind_LeakyReLU.cpp b/python_binding/operator/pybind_LeakyReLU.cpp index c062d93f5c40fe46336fe34f6d1664f24da07732..0592a286948911dab4f8f47b5e963367b53fbe94 100644 --- a/python_binding/operator/pybind_LeakyReLU.cpp +++ b/python_binding/operator/pybind_LeakyReLU.cpp @@ -13,13 +13,12 @@ #include "aidge/operator/LeakyReLU.hpp" #include "aidge/operator/Operator.hpp" -#include "aidge/utils/Parameter.hpp" namespace py = pybind11; namespace Aidge { void init_LeakyReLU(py::module& m) { - py::class_<LeakyReLU_Op, std::shared_ptr<LeakyReLU_Op>, Operator, PyAbstractParametrizable>(m, "LeakyReLU_Op", py::multiple_inheritance()); + py::class_<LeakyReLU_Op, std::shared_ptr<LeakyReLU_Op>, Operator, Parameters>(m, "LeakyReLU_Op", py::multiple_inheritance()); m.def("LeakyReLU", &LeakyReLU, py::arg("negative_slope") = 0.0f, py::arg("name") = ""); } diff --git a/python_binding/operator/pybind_Matmul.cpp b/python_binding/operator/pybind_Matmul.cpp index b6ae27289fabe1fe4dbeea60704a61373bc850cf..4ad18ff744c4b88071dd682be7c6527a63157c46 100644 --- a/python_binding/operator/pybind_Matmul.cpp +++ b/python_binding/operator/pybind_Matmul.cpp @@ -12,7 +12,6 @@ #include <pybind11/pybind11.h> #include "aidge/operator/Matmul.hpp" -#include "aidge/utils/Parameter.hpp" #include "aidge/backend/OperatorImpl.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/utils/Types.h" @@ -21,7 +20,7 @@ namespace py = pybind11; namespace Aidge { void declare_Matmul(py::module &m) { - py::class_<Matmul_Op, std::shared_ptr<Matmul_Op>, Operator, PyAbstractParametrizable>(m, "Matmul_Op", py::multiple_inheritance()); + py::class_<Matmul_Op, std::shared_ptr<Matmul_Op>, Operator, Parameters>(m, "Matmul_Op", py::multiple_inheritance()); m.def("Matmul", &Matmul, py::arg("out_channels"), py::arg("name") = ""); } diff --git a/python_binding/operator/pybind_MaxPooling.cpp b/python_binding/operator/pybind_MaxPooling.cpp index 9bd951c446e080ff27b099527ac9bbc350646140..45daf075e331f1aad7b168add6b2d77b0cf7214a 100644 --- a/python_binding/operator/pybind_MaxPooling.cpp +++ b/python_binding/operator/pybind_MaxPooling.cpp @@ -16,7 +16,6 @@ #include <vector> #include <array> -#include "aidge/utils/Parameter.hpp" #include "aidge/backend/OperatorImpl.hpp" #include "aidge/operator/MaxPooling.hpp" #include "aidge/operator/Operator.hpp" @@ -27,7 +26,7 @@ namespace py = pybind11; namespace Aidge { template <DimIdx_t DIM> void declare_MaxPoolingOp(py::module &m) { - py::class_<MaxPooling_Op<DIM>, std::shared_ptr<MaxPooling_Op<DIM>>, Operator, PyAbstractParametrizable>( + py::class_<MaxPooling_Op<DIM>, std::shared_ptr<MaxPooling_Op<DIM>>, Operator, Parameters>( m, ("MaxPoolingOp" + std::to_string(DIM) + "D").c_str(), py::multiple_inheritance()) .def(py::init<const std::array<DimSize_t, DIM> &, diff --git a/python_binding/operator/pybind_Producer.cpp b/python_binding/operator/pybind_Producer.cpp index ea9880800059e8993996e67138f89419c165fc4f..e1c351255097da112de4cf24d9be69cfaef4e442 100644 --- a/python_binding/operator/pybind_Producer.cpp +++ b/python_binding/operator/pybind_Producer.cpp @@ -13,7 +13,6 @@ #include <pybind11/stl.h> #include "aidge/utils/Types.h" -#include "aidge/utils/Parameter.hpp" // #include "aidge/backend/OperatorImpl.hpp" #include "aidge/operator/Operator.hpp" #include "aidge/operator/Producer.hpp" diff --git a/python_binding/pybind_core.cpp b/python_binding/pybind_core.cpp index 78418d51a5c410cb56bb8421fd7f3dc6ec6d32db..293e33ff047aa6dd37ac50d072951746748aebb3 100644 --- a/python_binding/pybind_core.cpp +++ b/python_binding/pybind_core.cpp @@ -17,7 +17,7 @@ namespace Aidge { void init_Data(py::module&); void init_Tensor(py::module&); void init_OperatorImpl(py::module&); -void init_Parameterizable(py::module&); +void init_Parameters(py::module&); void init_Operator(py::module&); void init_Add(py::module&); @@ -65,7 +65,7 @@ void init_Aidge(py::module& m){ init_Connector(m); init_OperatorImpl(m); - init_Parameterizable(m); + init_Parameters(m); init_Operator(m); init_Add(m); init_AvgPooling(m); diff --git a/python_binding/utils/pybind_Parameter.cpp b/python_binding/utils/pybind_Parameter.cpp index 358316ea00413813d6d482a8a4601e69af3aa992..f9344796e6062db7789bb2431c5c05e0aed1ad35 100644 --- a/python_binding/utils/pybind_Parameter.cpp +++ b/python_binding/utils/pybind_Parameter.cpp @@ -1,12 +1,25 @@ #include <pybind11/pybind11.h> -#include "aidge/utils/Parameter.hpp" +#include "aidge/utils/Parameters.hpp" +#include "aidge/utils/DynamicParameters.hpp" namespace py = pybind11; namespace Aidge { -void init_Parameterizable(py::module& m){ - py::class_<PyAbstractParametrizable, std::shared_ptr<PyAbstractParametrizable>>(m, "PyAbstractParametrizable") - .def("get", &PyAbstractParametrizable::getPy, py::arg("name")) - ; +void init_Parameters(py::module& m){ + py::class_<Parameters, std::shared_ptr<Parameters>>(m, "Parameters") + .def("is_parameter", &Parameters::isParameter) + .def("get_parameter_type", &Parameters::getParameterType) + .def("get_parameters_name", &Parameters::getParametersName) + .def("get_parameter", &Parameters::getPy, py::arg("name")); + + py::class_<DynamicParameters, std::shared_ptr<DynamicParameters>>(m, "DynamicParameters") + .def("add_parameter", &DynamicParameters::addParameter<bool>) + .def("add_parameter", &DynamicParameters::addParameter<int>) + .def("add_parameter", &DynamicParameters::addParameter<float>) + .def("add_parameter", &DynamicParameters::addParameter<std::string>) + .def("add_parameter", &DynamicParameters::addParameter<std::vector<bool>>) + .def("add_parameter", &DynamicParameters::addParameter<std::vector<int>>) + .def("add_parameter", &DynamicParameters::addParameter<std::vector<float>>) + .def("add_parameter", &DynamicParameters::addParameter<std::vector<std::string>>); } } diff --git a/src/graphmatching/NodeRegex.cpp b/src/graphmatching/NodeRegex.cpp index bbb116d1b12a31b491b26d2a64d04b416b61c6b7..5fa984eb6d88bbe285d908b98a4ae6e128c90874 100644 --- a/src/graphmatching/NodeRegex.cpp +++ b/src/graphmatching/NodeRegex.cpp @@ -39,7 +39,7 @@ bool Aidge::NodeRegex::isA(std::string NodeType){ /**bool NodeRegex::_is(string &Node_op){ // Parsing the condition is done in the initialization of the NodeRegex - // assert parameters exist in the node with the parameter function isParam() + // assert parameters exist in the node with the parameter function isParameter() // get the parameters