From f616e3d2187b2cfd642813d8953246073214e627 Mon Sep 17 00:00:00 2001 From: Olivier BICHLER <olivier.bichler@cea.fr> Date: Wed, 10 Apr 2024 10:48:08 +0200 Subject: [PATCH] Added default implementation for several operators --- include/aidge/backend/OperatorImpl.hpp | 2 +- include/aidge/operator/Cast.hpp | 18 ++-- include/aidge/operator/Concat.hpp | 14 ++- include/aidge/operator/GenericOperator.hpp | 2 +- include/aidge/operator/Identity.hpp | 2 +- include/aidge/operator/Memorize.hpp | 9 ++ include/aidge/operator/Move.hpp | 25 +++--- include/aidge/operator/Pop.hpp | 18 +++- include/aidge/operator/Producer.hpp | 7 +- include/aidge/operator/Reshape.hpp | 16 +++- include/aidge/utils/Registrar.hpp | 10 +-- src/operator/Cast.cpp | 19 ++-- src/operator/Concat.cpp | 46 +++++++++- src/operator/Memorize.cpp | 82 +++++++++++++++-- src/operator/Move.cpp | 16 ++-- src/operator/Pop.cpp | 29 ++++-- src/operator/Producer.cpp | 100 ++++++--------------- src/operator/Reshape.cpp | 14 ++- 18 files changed, 285 insertions(+), 144 deletions(-) diff --git a/include/aidge/backend/OperatorImpl.hpp b/include/aidge/backend/OperatorImpl.hpp index 6a9056723..1fc9168da 100644 --- a/include/aidge/backend/OperatorImpl.hpp +++ b/include/aidge/backend/OperatorImpl.hpp @@ -23,7 +23,7 @@ class Operator; class OperatorImpl { public: - OperatorImpl(const Operator& op, const std::string& backend); + OperatorImpl(const Operator& op, const std::string& backend = ""); virtual void forward(); virtual void backward(); diff --git a/include/aidge/operator/Cast.hpp b/include/aidge/operator/Cast.hpp index bbc776a11..6efbc0a21 100644 --- a/include/aidge/operator/Cast.hpp +++ b/include/aidge/operator/Cast.hpp @@ -24,13 +24,20 @@ #include "aidge/utils/Types.h" namespace Aidge { +class Cast_OpImpl : public OperatorImpl { +public: + Cast_OpImpl(const Operator& op, const std::string& backend = ""): OperatorImpl(op, backend) {} + void forward() override; +}; class Cast_Op : public OperatorTensor, public Registrable<Cast_Op, std::string, std::unique_ptr<OperatorImpl>(const Cast_Op&)> { public: static const std::string Type; - Cast_Op() : OperatorTensor(Type, 1, 0, 1) {} + Cast_Op() : OperatorTensor(Type, 1, 0, 1) { + mImpl = std::make_shared<Cast_OpImpl>(*this); + } /** * @brief Copy-constructor. Copy the operator attributes and its output tensor(s), but not its input tensors (the new operator has no input associated). @@ -39,10 +46,11 @@ public: Cast_Op(const Cast_Op& op) : OperatorTensor(op) { - if (op.mImpl) { + if (!op.backend().empty()) { SET_IMPL_MACRO(Cast_Op, *this, op.backend()); - } else { - mImpl = nullptr; + } + else { + mImpl = std::make_shared<Cast_OpImpl>(*this); } } @@ -56,8 +64,6 @@ public: void setBackend(const std::string& name, DeviceIdx_t device = 0) override; - void forward() override; - static const std::vector<std::string> getInputsName(){ return {"data_input"}; } diff --git a/include/aidge/operator/Concat.hpp b/include/aidge/operator/Concat.hpp index 97c477db5..32a519dbc 100644 --- a/include/aidge/operator/Concat.hpp +++ b/include/aidge/operator/Concat.hpp @@ -26,6 +26,12 @@ #include "aidge/utils/Types.h" namespace Aidge { +class Concat_OpImpl : public OperatorImpl { +public: + Concat_OpImpl(const Operator& op, const std::string& backend = ""): OperatorImpl(op, backend) {} + void forward() override; +}; + enum class ConcatAttr { Axis }; class Concat_Op : public OperatorTensor, @@ -45,6 +51,7 @@ public: if (nbIn == 0) { AIDGE_THROW_OR_ABORT(std::runtime_error, "Add operator should have at least one input."); } + mImpl = std::make_shared<Concat_OpImpl>(*this); } /** @@ -55,10 +62,11 @@ public: : OperatorTensor(op), Attributes_(op) { - if (op.mImpl){ + if (!op.backend().empty()) { SET_IMPL_MACRO(Concat_Op, *this, op.backend()); - }else{ - mImpl = nullptr; + } + else { + mImpl = std::make_shared<Concat_OpImpl>(*this); } } diff --git a/include/aidge/operator/GenericOperator.hpp b/include/aidge/operator/GenericOperator.hpp index 6208ea0a9..49885f9fd 100644 --- a/include/aidge/operator/GenericOperator.hpp +++ b/include/aidge/operator/GenericOperator.hpp @@ -37,7 +37,7 @@ public: GenericOperator_Op(const std::string& type, IOIndex_t nbData, IOIndex_t nbParam, IOIndex_t nbOut) : OperatorTensor(type, nbData, nbParam, nbOut) { - mImpl = std::make_shared<OperatorImpl>(*this, ""); + mImpl = std::make_shared<OperatorImpl>(*this); } /** diff --git a/include/aidge/operator/Identity.hpp b/include/aidge/operator/Identity.hpp index 51c70eae5..f49711837 100644 --- a/include/aidge/operator/Identity.hpp +++ b/include/aidge/operator/Identity.hpp @@ -42,7 +42,7 @@ public: Identity_Op() : OperatorTensor(Type, 1, 0, 1) { - mImpl = std::make_shared<OperatorImpl>(*this, ""); + mImpl = std::make_shared<OperatorImpl>(*this); } /** diff --git a/include/aidge/operator/Memorize.hpp b/include/aidge/operator/Memorize.hpp index 89d265283..6f668a942 100644 --- a/include/aidge/operator/Memorize.hpp +++ b/include/aidge/operator/Memorize.hpp @@ -25,6 +25,15 @@ #include "aidge/utils/Types.h" namespace Aidge { +class Memorize_OpImpl : public OperatorImpl { +public: + Memorize_OpImpl(const Operator& op, const std::string& backend = ""): OperatorImpl(op, backend) {} + Elts_t getNbRequiredData(const IOIndex_t inputIdx) const override final; + Elts_t getRequiredMemory(const IOIndex_t outputIdx, const std::vector<DimSize_t> &inputsSize) const override final; + void updateConsummerProducer() override; + void forward() override; +}; + enum class MemorizeAttr { ScheduleStep, ForwardStep, EndStep }; class Memorize_Op : public OperatorTensor, diff --git a/include/aidge/operator/Move.hpp b/include/aidge/operator/Move.hpp index 3652cf969..e9bcaa871 100644 --- a/include/aidge/operator/Move.hpp +++ b/include/aidge/operator/Move.hpp @@ -24,13 +24,20 @@ #include "aidge/utils/Types.h" namespace Aidge { +class Move_OpImpl : public OperatorImpl { +public: + Move_OpImpl(const Operator& op, const std::string& backend = ""): OperatorImpl(op, backend) {} + void forward() override; +}; class Move_Op : public OperatorTensor, public Registrable<Move_Op, std::tuple<std::string, std::string>, std::unique_ptr<OperatorImpl>(const Move_Op&)> { public: static const std::string Type; - Move_Op() : OperatorTensor(Type, 1, 0, 1) {} + Move_Op() : OperatorTensor(Type, 1, 0, 1) { + mImpl = std::make_shared<Move_OpImpl>(*this); + } /** * @brief Copy-constructor. Copy the operator attributes and its output tensor(s), but not its input tensors (the new operator has no input associated). @@ -39,7 +46,12 @@ public: Move_Op(const Move_Op& op) : OperatorTensor(op) { - mImpl = op.mImpl ? Registrar<Move_Op>::create({mInputs[0]->getImpl()->backend(), mOutputs[0]->getImpl()->backend()})(*this) : nullptr; + if (!op.backend().empty()) { + SET_IMPL_MACRO(Move_Op, *this, {op.getInput(0)->getImpl()->backend(), op.backend()}); + } + else { + mImpl = std::make_shared<Move_OpImpl>(*this); + } } /** @@ -50,14 +62,7 @@ public: return std::make_shared<Move_Op>(*this); } - void setBackend(const std::string& name, DeviceIdx_t device = 0) override { - if (mInputs[0]->getImpl() && Registrar<Move_Op>::exists({mInputs[0]->getImpl()->backend(), name})) { - mImpl = Registrar<Move_Op>::create({mInputs[0]->getImpl()->backend(), name})(*this); - } - mOutputs[0]->setBackend(name, device); - } - - void forward() override; + void setBackend(const std::string& name, DeviceIdx_t device = 0) override; static const std::vector<std::string> getInputsName(){ return {"data_input"}; diff --git a/include/aidge/operator/Pop.hpp b/include/aidge/operator/Pop.hpp index c584390ca..372faff6a 100644 --- a/include/aidge/operator/Pop.hpp +++ b/include/aidge/operator/Pop.hpp @@ -24,6 +24,13 @@ #include "aidge/utils/Types.h" namespace Aidge { +class Pop_OpImpl : public OperatorImpl { +public: + Pop_OpImpl(const Operator& op, const std::string& backend = ""): OperatorImpl(op, backend) {} + Elts_t getNbRequiredData(const IOIndex_t inputIdx) const override; + void forward() override; +}; + enum class PopAttr { ForwardStep }; class Pop_Op : public OperatorTensor, @@ -39,7 +46,9 @@ public: Pop_Op() : OperatorTensor(Type, 1, 0, 1), Attributes_(attr<PopAttr::ForwardStep>(0)) - {} + { + mImpl = std::make_shared<Pop_OpImpl>(*this); + } /** * @brief Copy-constructor. Copy the operator attributes and its output tensor(s), but not its input tensors (the new operator has no input associated). @@ -49,10 +58,11 @@ public: : OperatorTensor(op), Attributes_(op) { - if (op.mImpl){ + if (!op.backend().empty()) { SET_IMPL_MACRO(Pop_Op, *this, op.backend()); - } else { - mImpl = nullptr; + } + else { + mImpl = std::make_shared<Pop_OpImpl>(*this); } } diff --git a/include/aidge/operator/Producer.hpp b/include/aidge/operator/Producer.hpp index 79a116e4a..e21aa9aea 100644 --- a/include/aidge/operator/Producer.hpp +++ b/include/aidge/operator/Producer.hpp @@ -47,7 +47,7 @@ public: Attributes_(attr<ProdAttr::Constant>(constant)) { mOutputs[0]->resize(dims); - mImpl = std::make_shared<OperatorImpl>(*this, ""); + mImpl = std::make_shared<OperatorImpl>(*this); } /** @@ -102,9 +102,8 @@ public: return {"data_output"}; } - void forward() override final { - fmt::print("Basic Producer forward() function.\n"); - } + void forward() override final; + void backward() override final { fmt::print("Basic Producer backward() function.\n"); } diff --git a/include/aidge/operator/Reshape.hpp b/include/aidge/operator/Reshape.hpp index 8f1482019..bf0f7ee34 100644 --- a/include/aidge/operator/Reshape.hpp +++ b/include/aidge/operator/Reshape.hpp @@ -23,6 +23,11 @@ #include "aidge/utils/Types.h" namespace Aidge { +class Reshape_OpImpl : public OperatorImpl { +public: + Reshape_OpImpl(const Operator& op, const std::string& backend = ""): OperatorImpl(op, backend) {} + void forward() override; +}; enum class ReshapeAttr { Shape }; @@ -42,7 +47,9 @@ public: Reshape_Op(const std::vector<std::int64_t>& shape) : OperatorTensor(Type, 1, 0, 1), Attributes_(attr<ReshapeAttr::Shape>(shape)) - {} + { + mImpl = std::make_shared<Reshape_OpImpl>(*this); + } /** * @brief Copy-constructor. Copy the operator attributes and its output tensor(s), but not its input tensors (the new operator has no input associated). @@ -52,10 +59,11 @@ public: : OperatorTensor(op), Attributes_(op) { - if (op.mImpl){ + if (!op.backend().empty()) { SET_IMPL_MACRO(Reshape_Op, *this, op.backend()); - } else { - mImpl = nullptr; + } + else { + mImpl = std::make_shared<Reshape_OpImpl>(*this); } } diff --git a/include/aidge/utils/Registrar.hpp b/include/aidge/utils/Registrar.hpp index a6d1d7a9e..b0acdaff7 100644 --- a/include/aidge/utils/Registrar.hpp +++ b/include/aidge/utils/Registrar.hpp @@ -129,16 +129,16 @@ void declare_registrable(py::module& m, const std::string& class_name){ * cyril.moineau@cea.fr */ #ifdef PYBIND -#define SET_IMPL_MACRO(T_Op, op, backend_name) \ +#define SET_IMPL_MACRO(T_Op, op, ...) \ if(Py_IsInitialized()) { \ auto obj = py::cast(&(op)); \ - (op).setImpl(Registrar<T_Op>::create(backend_name)(op)); \ + (op).setImpl(Registrar<T_Op>::create(__VA_ARGS__)(op)); \ } else { \ - (op).setImpl(Registrar<T_Op>::create(backend_name)(op)); \ + (op).setImpl(Registrar<T_Op>::create(__VA_ARGS__)(op)); \ } #else -#define SET_IMPL_MACRO(T_Op, op, backend_name) \ - (op).setImpl(Registrar<T_Op>::create(backend_name)(op)); +#define SET_IMPL_MACRO(T_Op, op, ...) \ + (op).setImpl(Registrar<T_Op>::create(__VA_ARGS__)(op)); #endif } diff --git a/src/operator/Cast.cpp b/src/operator/Cast.cpp index 4f1ac5589..f1c8e25e1 100644 --- a/src/operator/Cast.cpp +++ b/src/operator/Cast.cpp @@ -20,22 +20,19 @@ #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" -const std::string Aidge::Cast_Op::Type = "Cast"; - -void Aidge::Cast_Op::forward() { - if (mImpl) { - mImpl->forward(); - } - else { - mOutputs[0]->copyCast(*(mInputs[0])); - } - - runHooks(); +void Aidge::Cast_OpImpl::forward() { + const Cast_Op& op = dynamic_cast<const Cast_Op&>(mOp); + op.getOutput(0)->copyCast(*(op.getInput(0))); } +const std::string Aidge::Cast_Op::Type = "Cast"; + void Aidge::Cast_Op::setBackend(const std::string& name, Aidge::DeviceIdx_t device) { if (Registrar<Cast_Op>::exists({name})) { SET_IMPL_MACRO(Cast_Op, *this, name); } + else { + mImpl = std::make_shared<Cast_OpImpl>(*this); + } mOutputs[0]->setBackend(name, device); } diff --git a/src/operator/Concat.cpp b/src/operator/Concat.cpp index d2bfd17ba..929000a5f 100644 --- a/src/operator/Concat.cpp +++ b/src/operator/Concat.cpp @@ -18,6 +18,45 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" +void Aidge::Concat_OpImpl::forward() { + const Concat_Op& op = dynamic_cast<const Concat_Op&>(mOp); + const DimSize_t axis = op.template getAttr<DimSize_t>("Axis"); + + assert(op.getInput(0) && "missing input in Concat operator"); + DataType datatypeFirstInput = op.getInput(0)->dataType(); + for (IOIndex_t i = 1; i < mOp.nbInputs(); ++i) { + assert(op.getInput(i) && "missing input in Concat operator"); + assert(op.getInput(i)->dataType() == datatypeFirstInput); + } + + DimSize_t outputAxisValue = 0; + for (IOIndex_t i = 0; i < mOp.nbInputs(); ++i) { + outputAxisValue += op.getInput(i)->dims()[axis]; + } + + DimSize_t prodDimLower = 1; + for (DimIdx_t i = 0; i < axis; ++i) { + prodDimLower *= op.getInput(0)->dims()[i]; + } + DimSize_t prodDimHigher = 1; + for (DimIdx_t i = axis + 1; static_cast<std::size_t>(i) < op.getInput(0)->dims().size(); + ++i) { + prodDimHigher *= op.getInput(0)->dims()[i]; + } + + std::size_t oIndexStart = 0; + std::size_t oIndex = 0; + for (std::size_t inputId = 0; inputId < op.nbInputs(); ++inputId) { + oIndex = oIndexStart; + const DimSize_t iOffset = prodDimHigher*op.getInput(inputId)->dims()[axis]; + for (std::size_t iIndex = 0; iIndex < prodDimLower; ++iIndex) { + op.getOutput(0)->getImpl()->copy(op.getInput(inputId)->getImpl()->rawPtr(iIndex*iOffset), iOffset, oIndex); + oIndex += prodDimHigher*outputAxisValue; + } + oIndexStart += op.getInput(inputId)->dims()[axis]*prodDimHigher; + } +} + const std::string Aidge::Concat_Op::Type = "Concat"; bool Aidge::Concat_Op::computeOutputDims(bool /*allowDataDependency*/) { @@ -54,6 +93,11 @@ bool Aidge::Concat_Op::computeOutputDims(bool /*allowDataDependency*/) { } void Aidge::Concat_Op::setBackend(const std::string& name, DeviceIdx_t device) { - SET_IMPL_MACRO(Concat_Op, *this, name); + if (Registrar<Concat_Op>::exists({name})) { + SET_IMPL_MACRO(Concat_Op, *this, name); + } + else { + mImpl = std::make_shared<Concat_OpImpl>(*this); + } mOutputs[0]->setBackend(name, device); } diff --git a/src/operator/Memorize.cpp b/src/operator/Memorize.cpp index 3490a5f6d..4e802816a 100644 --- a/src/operator/Memorize.cpp +++ b/src/operator/Memorize.cpp @@ -20,8 +20,73 @@ #include "aidge/utils/ErrorHandling.hpp" #include "aidge/utils/Types.h" +Aidge::Elts_t Aidge::Memorize_OpImpl::getNbRequiredData( + Aidge::IOIndex_t inputIdx) const +{ + const Memorize_Op& op = dynamic_cast<const Memorize_Op&>(mOp); + const unsigned int scheduleStep = op.template getAttr<MemorizeAttr::ScheduleStep>(); + + if (scheduleStep == 0 && inputIdx == 0) { + // No data input is required for the initial step. + // Initialization data is required however. + return Elts_t::NoneElts(); + } + else if (scheduleStep > 0 && inputIdx == 1) { + // No initialization data is required after the initial step. + return Elts_t::NoneElts(); + } + else { + return OperatorImpl::getNbRequiredData(inputIdx); + } +} + +Aidge::Elts_t Aidge::Memorize_OpImpl::getRequiredMemory(const Aidge::IOIndex_t outputIdx, + const std::vector<Aidge::DimSize_t> &/*inputsSize*/) const { + assert(mOp.getRawOutput(outputIdx) && "requires valid output"); + + const Memorize_Op& op = dynamic_cast<const Memorize_Op&>(mOp); + const unsigned int scheduleStep = op.template getAttr<MemorizeAttr::ScheduleStep>(); + const unsigned int endStep = op.template getAttr<MemorizeAttr::EndStep>(); + + if (endStep > 0 && outputIdx == 1 && scheduleStep >= endStep) { + return Elts_t::NoneElts(); + } + else { + return Elts_t::DataElts(op.getOutput(outputIdx)->size()); + } +} + +void Aidge::Memorize_OpImpl::updateConsummerProducer() { + OperatorImpl::updateConsummerProducer(); + + const Memorize_Op& op = dynamic_cast<const Memorize_Op&>(mOp); + const unsigned int scheduleStep = op.template getAttr<MemorizeAttr::ScheduleStep>(); + const unsigned int endStep = op.template getAttr<MemorizeAttr::EndStep>(); + AIDGE_ASSERT(endStep == 0 || scheduleStep <= endStep, "cannot update consumer producer anymore, number of cycles exceeded"); +} + +void Aidge::Memorize_OpImpl::forward() { + const Memorize_Op& op = dynamic_cast<const Memorize_Op&>(mOp); + const unsigned int forwardStep = op.template getAttr<MemorizeAttr::ForwardStep>(); + const unsigned int endStep = op.template getAttr<MemorizeAttr::EndStep>(); + AIDGE_ASSERT(endStep == 0 || forwardStep <= endStep, "cannot forward anymore, number of cycles exceeded"); + + if (forwardStep == 0) { + op.getOutput(0)->getImpl()->copy(op.getInput(1)->getImpl()->rawPtr(), op.getInput(1)->size()); + } + else { + op.getOutput(0)->getImpl()->copy(op.getInput(0)->getImpl()->rawPtr(), op.getInput(0)->size()); + } +} + const std::string Aidge::Memorize_Op::Type = "Memorize"; +void Aidge::Memorize_Op::updateConsummerProducer() { + Operator::updateConsummerProducer(); + ++this->template getAttr<MemorizeAttr::ScheduleStep>(); + this->template getAttr<MemorizeAttr::ForwardStep>() = 0; +} + bool Aidge::Memorize_Op::computeOutputDims(bool /*allowDataDependency*/) { for (size_t i = 0; i < 2; ++i) { if (!getInput(i)) { @@ -45,11 +110,6 @@ bool Aidge::Memorize_Op::computeOutputDims(bool /*allowDataDependency*/) { return false; } -void Aidge::Memorize_Op::setBackend(const std::string& name, Aidge::DeviceIdx_t device) { - mImpl = Registrar<Memorize_Op>::create({name})(*this); - mOutputs[0]->setBackend(name, device); -} - bool Aidge::Memorize_Op::outputDimsForwarded() const { // Only check the output dims bool forwarded = true; @@ -60,10 +120,14 @@ bool Aidge::Memorize_Op::outputDimsForwarded() const { return forwarded; } -void Aidge::Memorize_Op::updateConsummerProducer() { - Operator::updateConsummerProducer(); - ++this->template getAttr<MemorizeAttr::ScheduleStep>(); - this->template getAttr<MemorizeAttr::ForwardStep>() = 0; +void Aidge::Memorize_Op::setBackend(const std::string& name, Aidge::DeviceIdx_t device) { + if (Registrar<Memorize_Op>::exists({name})){ + SET_IMPL_MACRO(Memorize_Op, *this, name); + } + else { + mImpl = std::make_shared<Memorize_OpImpl>(*this); + } + mOutputs[0]->setBackend(name, device); } void Aidge::Memorize_Op::forward() { diff --git a/src/operator/Move.cpp b/src/operator/Move.cpp index d8776e32f..0f635ea65 100644 --- a/src/operator/Move.cpp +++ b/src/operator/Move.cpp @@ -12,15 +12,19 @@ #include "aidge/backend/OperatorImpl.hpp" #include "aidge/operator/Move.hpp" +void Aidge::Move_OpImpl::forward() { + const Move_Op& op = dynamic_cast<const Move_Op&>(mOp); + op.getOutput(0)->copyFrom(*(op.getInput(0))); +} + const std::string Aidge::Move_Op::Type = "Move"; -void Aidge::Move_Op::forward() { - if (mImpl) { - mImpl->forward(); +void Aidge::Move_Op::setBackend(const std::string& name, Aidge::DeviceIdx_t device) { + if (Registrar<Move_Op>::exists({mInputs[0]->getImpl()->backend(), name})) { + SET_IMPL_MACRO(Move_Op, *this, {mInputs[0]->getImpl()->backend(), name}); } else { - mOutputs[0]->copyFrom(*(mInputs[0])); + mImpl = std::make_shared<Move_OpImpl>(*this); } - - runHooks(); + mOutputs[0]->setBackend(name, device); } diff --git a/src/operator/Pop.cpp b/src/operator/Pop.cpp index 9e7b36025..6f09d402a 100644 --- a/src/operator/Pop.cpp +++ b/src/operator/Pop.cpp @@ -20,6 +20,20 @@ #include "aidge/utils/StaticAttributes.hpp" #include "aidge/utils/Types.h" +Aidge::Elts_t Aidge::Pop_OpImpl::getNbRequiredData(const Aidge::IOIndex_t inputIdx) const { + assert(mOp.getRawInput(inputIdx) && "requires valid input"); + + const Pop_Op& op = dynamic_cast<const Pop_Op&>(mOp); + return Elts_t::DataElts(op.getInput(inputIdx)->size() + / op.getInput(inputIdx)->dims()[0]); +} + +void Aidge::Pop_OpImpl::forward() { + const Pop_Op& op = dynamic_cast<const Pop_Op&>(mOp); + assert(op.getInput(0) && "missing input #0"); + const unsigned int forwardStep = op.template getAttr<PopAttr::ForwardStep>(); + *op.getOutput(0) = op.getInput(0)->extract({forwardStep}); +} const std::string Aidge::Pop_Op::Type = "Pop"; @@ -43,12 +57,17 @@ void Aidge::Pop_Op::updateConsummerProducer() { this->template getAttr<PopAttr::ForwardStep>() = 0; } +void Aidge::Pop_Op::setBackend(const std::string& name, Aidge::DeviceIdx_t device) { + if (Registrar<Pop_Op>::exists({name})){ + SET_IMPL_MACRO(Pop_Op, *this, name); + } + else { + mImpl = std::make_shared<Pop_OpImpl>(*this); + } + mOutputs[0]->setBackend(name, device); +} + void Aidge::Pop_Op::forward() { Operator::forward(); ++this->template getAttr<PopAttr::ForwardStep>(); } - -void Aidge::Pop_Op::setBackend(const std::string& name, Aidge::DeviceIdx_t device) { - SET_IMPL_MACRO(Pop_Op, *this, name); - mOutputs[0]->setBackend(name, device); -} diff --git a/src/operator/Producer.cpp b/src/operator/Producer.cpp index 38bbbc148..f384c1013 100644 --- a/src/operator/Producer.cpp +++ b/src/operator/Producer.cpp @@ -32,28 +32,12 @@ Aidge::Producer_Op::Producer_Op(const std::shared_ptr<Aidge::Tensor> tensor, boo Attributes_(attr<ProdAttr::Constant>(constant)) { mOutputs[0] = tensor; // copy the pointer of the Tensor -#ifdef PYBIND - if(Py_IsInitialized()) { - auto obj = py::cast(&(*this)); - setImpl((mOutputs[0]->hasImpl()) ? - (Registrar<Producer_Op>::exists({mOutputs[0]->getImpl()->backend()}) ? - Registrar<Producer_Op>::create(mOutputs[0]->getImpl()->backend())(*this) : - std::make_shared<OperatorImpl>(*this, mOutputs[0]->getImpl()->backend())) : - std::make_shared<OperatorImpl>(*this, "")); - } else { - setImpl((mOutputs[0]->hasImpl()) ? - (Registrar<Producer_Op>::exists({mOutputs[0]->getImpl()->backend()}) ? - Registrar<Producer_Op>::create(mOutputs[0]->getImpl()->backend())(*this) : - std::make_shared<OperatorImpl>(*this, mOutputs[0]->getImpl()->backend())) : - std::make_shared<OperatorImpl>(*this, "")); + if (mOutputs[0]->getImpl() && Registrar<Producer_Op>::exists({mOutputs[0]->getImpl()->backend()})){ + SET_IMPL_MACRO(Producer_Op, *this, mOutputs[0]->getImpl()->backend()); + } + else { + mImpl = std::make_shared<OperatorImpl>(*this); } -#else - setImpl((mOutputs[0]->hasImpl()) ? - (Registrar<Producer_Op>::exists({mOutputs[0]->getImpl()->backend()}) ? - Registrar<Producer_Op>::create(mOutputs[0]->getImpl()->backend())(*this) : - std::make_shared<OperatorImpl>(*this, mOutputs[0]->getImpl()->backend())) : - std::make_shared<OperatorImpl>(*this, "")); -#endif } /** @@ -66,57 +50,31 @@ Aidge::Producer_Op::Producer_Op(const Aidge::Producer_Op& op) Attributes_(op) { mOutputs[0] = std::make_shared<Tensor>(*(op.getOutput(0))); -#ifdef PYBIND - if(Py_IsInitialized()) { - auto obj = py::cast(&(*this)); - setImpl((mOutputs[0]->hasImpl()) ? - (Registrar<Producer_Op>::exists({mOutputs[0]->getImpl()->backend()}) ? - Registrar<Producer_Op>::create(mOutputs[0]->getImpl()->backend())(*this) : - std::make_shared<OperatorImpl>(*this, mOutputs[0]->getImpl()->backend())) : - std::make_shared<OperatorImpl>(*this, "")); - } else { - setImpl((mOutputs[0]->hasImpl()) ? - (Registrar<Producer_Op>::exists({mOutputs[0]->getImpl()->backend()}) ? - Registrar<Producer_Op>::create(mOutputs[0]->getImpl()->backend())(*this) : - std::make_shared<OperatorImpl>(*this, mOutputs[0]->getImpl()->backend())) : - std::make_shared<OperatorImpl>(*this, "")); - } -#else - setImpl((mOutputs[0]->hasImpl()) ? - (Registrar<Producer_Op>::exists({mOutputs[0]->getImpl()->backend()}) ? - Registrar<Producer_Op>::create(mOutputs[0]->getImpl()->backend())(*this) : - std::make_shared<OperatorImpl>(*this, mOutputs[0]->getImpl()->backend())) : - std::make_shared<OperatorImpl>(*this, "")); -#endif - // if (mOutputs[0]->hasImpl()) { - // if (Registrar<Producer_Op>::exists({mOutputs[0]->getImpl()->backend()})){ - // setImpl(Registrar<Producer_Op>::create(mOutputs[0]->getImpl()->backend())(*this)); - // } - // else { - // mImpl = std::make_shared<OperatorImpl>(*this, mOutputs[0]->getImpl()->backend()); - // } - - // } else { - // mImpl = nullptr; - // } + if (mOutputs[0]->getImpl() && Registrar<Producer_Op>::exists({mOutputs[0]->getImpl()->backend()})){ + SET_IMPL_MACRO(Producer_Op, *this, mOutputs[0]->getImpl()->backend()); + } + else { + mImpl = std::make_shared<OperatorImpl>(*this); + } } void Aidge::Producer_Op::setBackend(const std::string& name, Aidge::DeviceIdx_t device) { -#ifdef PYBIND - if(Py_IsInitialized()) { - auto obj = py::cast(&(*this)); - setImpl((Registrar<Producer_Op>::exists({name})) ? - Registrar<Producer_Op>::create(name)(*this) : - std::make_shared<OperatorImpl>(*this, "")); - } else { - setImpl((Registrar<Producer_Op>::exists({name})) ? - Registrar<Producer_Op>::create(name)(*this) : - std::make_shared<OperatorImpl>(*this, "")); - } -#else - setImpl((Registrar<Producer_Op>::exists({name})) ? - Registrar<Producer_Op>::create(name)(*this) : - std::make_shared<OperatorImpl>(*this, "")); -#endif + if (Registrar<Producer_Op>::exists({name})){ + SET_IMPL_MACRO(Producer_Op, *this, name); + } + else { + mImpl = std::make_shared<OperatorImpl>(*this); + } mOutputs[0]->setBackend(name, device); -} \ No newline at end of file +} + +void Aidge::Producer_Op::forward() { + if (!backend().empty()) { + mImpl->forward(); + } + else { + fmt::print("Basic Producer forward() function.\n"); + } + + runHooks(); +} diff --git a/src/operator/Reshape.cpp b/src/operator/Reshape.cpp index 4ae7b1217..8431971da 100644 --- a/src/operator/Reshape.cpp +++ b/src/operator/Reshape.cpp @@ -23,6 +23,11 @@ #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" +void Aidge::Reshape_OpImpl::forward() { + const Reshape_Op& op = dynamic_cast<const Reshape_Op&>(mOp); + op.getOutput(0)->getImpl()->copy(op.getInput(0)->getImpl()->rawPtr(), op.getInput(0)->size()); +} + const std::string Aidge::Reshape_Op::Type = "Reshape"; bool Aidge::Reshape_Op::computeOutputDims(bool /*allowDataDependency*/) { @@ -65,6 +70,11 @@ bool Aidge::Reshape_Op::computeOutputDims(bool /*allowDataDependency*/) { } void Aidge::Reshape_Op::setBackend(const std::string& name, Aidge::DeviceIdx_t device) { - SET_IMPL_MACRO(Reshape_Op, *this, name); + if (Registrar<Reshape_Op>::exists({name})){ + SET_IMPL_MACRO(Reshape_Op, *this, name); + } + else { + mImpl = std::make_shared<Reshape_OpImpl>(*this); + } mOutputs[0]->setBackend(name, device); -} \ No newline at end of file +} -- GitLab