From b83eb58000e0974d2b485c0a51d0010651ae0e23 Mon Sep 17 00:00:00 2001 From: cmoineau <cyril.moineau@cea.fr> Date: Thu, 29 Feb 2024 07:46:35 +0000 Subject: [PATCH] Add SET_IMPL_MACRO macro to fix copy ctor bug. --- include/aidge/operator/Conv.hpp | 4 ++-- include/aidge/utils/Registrar.hpp | 33 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/include/aidge/operator/Conv.hpp b/include/aidge/operator/Conv.hpp index 97e27f8d3..552aee6ba 100644 --- a/include/aidge/operator/Conv.hpp +++ b/include/aidge/operator/Conv.hpp @@ -23,7 +23,7 @@ #include "aidge/operator/OperatorTensor.hpp" #include "aidge/operator/Producer.hpp" #include "aidge/utils/StaticAttributes.hpp" -#include "aidge/utils/Registrar.hpp" +#include "aidge/utils/Registrar.hpp" // SET_IMPL_MACRO #include "aidge/utils/Types.h" namespace Aidge { @@ -174,7 +174,7 @@ std::vector<std::pair<std::vector<Aidge::DimSize_t>, std::vector<DimSize_t>>> co } void setBackend(const std::string &name, DeviceIdx_t device = 0) override { - mImpl = Registrar<Conv_Op<DIM>>::create(name)(*this); + SET_IMPL_MACRO(Conv_Op<DIM>, *this, name); mOutputs[0]->setBackend(name, device); // By default, automatically set backend for weight and bias inputs diff --git a/include/aidge/utils/Registrar.hpp b/include/aidge/utils/Registrar.hpp index 65ba636a5..b2a98113f 100644 --- a/include/aidge/utils/Registrar.hpp +++ b/include/aidge/utils/Registrar.hpp @@ -30,6 +30,9 @@ namespace Aidge { namespace py = pybind11; #endif +// Abstract class used to test if a class is Registrable. +class AbstractRegistrable {}; + template <class DerivedClass, class Key, class Func> // curiously rucurring template pattern class Registrable { public: @@ -110,6 +113,36 @@ void declare_registrable(py::module& m, const std::string& class_name){ } #endif +/* +* This macro allow to set an implementation to an operator +* This macro is mandatory for using implementation registered in python +* PyBind when calling create method will do a call to the copy ctor if +* op is not visible to the python world (if the create method return a python function) +* See this issue for more information https://github.com/pybind/pybind11/issues/4417 +* Note: using a method to do this is not possible has any call to a function will call +* the cpy ctor. This is why I used a macro +* Note: I duplicated +* (op).setImpl(Registrar<T_Op>::create(backend_name)(op)); \ +* This is because the py::cast need to be done in the same scope. +* I know this only empyrically not sure what happens under the hood... +* +* If someone wants to find an alternative to this Macro, you can contact me: +* cyril.moineau@cea.fr +*/ +#ifdef PYBIND +#define SET_IMPL_MACRO(T_Op, op, backend_name) \ + \ + if(Py_IsInitialized()) { \ + auto obj = py::cast(&(op)); \ + (op).setImpl(Registrar<T_Op>::create(backend_name)(op)); \ + } else { \ + (op).setImpl(Registrar<T_Op>::create(backend_name)(op)); \ + } +#else +#define SET_IMPL_MACRO(T_Op, op, backend_name) \ + (op).setImpl(Registrar<T_Op>::create(backend_name)(op)); +#endif + } #endif //AIDGE_CORE_UTILS_REGISTRAR_H_ -- GitLab