Skip to content
Snippets Groups Projects
Commit 5aa49ccf authored by Olivier BICHLER's avatar Olivier BICHLER
Browse files

Unified interface for parameters

parent 44afa3b4
No related branches found
No related tags found
1 merge request!16Unified interface for attributes
Pipeline #32210 failed
Showing
with 458 additions and 295 deletions
......@@ -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"
......
......@@ -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 {
......
......@@ -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>
......
......@@ -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>()) {
......
......@@ -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);
......
......@@ -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),
......
......@@ -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),
......
......@@ -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>())
......
......@@ -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");
......
......@@ -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);
......
......@@ -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>())
{
......
......@@ -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>()) {
......
......@@ -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 {
......
......@@ -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);
......
......@@ -9,23 +9,25 @@
*
********************************************************************************/
#ifndef AIDGE_CPARAMETER_H_
#define AIDGE_CPARAMETER_H_
#ifndef AIDGE_CORE_UTILS_DYNAMICPARAMETERS_H_
#define AIDGE_CORE_UTILS_DYNAMICPARAMETERS_H_
#include <map>
#include <vector>
#include <type_traits>
#include <typeinfo>
#include <assert.h>
#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 CParameter {
class DynamicParameters : public Parameters {
private:
template<typename _ValueType>
inline _ValueType& any_cast_ref(const _any& __any)
......@@ -40,67 +42,106 @@ private:
}
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;
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 i_ParamName Parameter name
* \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& Get(const std::string i_ParamName)
template<class T> T& getParameter(const std::string& name)
{
return any_cast_ref<T>(m_Buffer[m_Params.at(i_ParamName)]);
return any_cast_ref<T>(mBuffer[mParams.at(name)]);
}
// template<class T> const T& Get(const std::string i_ParamName) const
// {
// return any_cast<T>(m_Buffer[m_Params.at(i_ParamName)]);
// }
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 i_ParamName Parameter name
///\param i_Value Parameter value
///\todo Pass i_Value by ref if large or not trivial
///\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 Add(const std::string &i_ParamName, T&& i_Value)
template<class T> void addParameter(const std::string& name, T&& value)
{
m_Params[i_ParamName] = m_Buffer.size(); // Copy pointer offset
m_Buffer.push_back(_any(std::forward<T>(i_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 getParamType(std::string const &i_ParamName){
return m_Buffer[m_Params.at(i_ParamName)].type().name();
std::string getParameterType(const std::string& name) const override final {
return mBuffer[mParams.at(name)].type().name();
}
std::vector<std::string> getParametersName(){
std::vector<std::string> getParametersName() const override final {
std::vector<std::string> parametersName;
for(auto const& it: m_Params)
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> m_Params; // { Param name : offset }
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> m_Buffer = {};
std::vector<_any> mBuffer;
};
}
#endif /* AIDGE_CPARAMETER_H_ */
#endif /* AIDGE_CORE_UTILS_DYNAMICPARAMETERS_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_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_ */
/********************************************************************************
* 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_ */
......@@ -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"
......
......@@ -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> &,
......
......@@ -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") = "");
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment