From c50a7d1faa3a8a74e8d6e40dac5a3f2587b5235a Mon Sep 17 00:00:00 2001
From: Olivier BICHLER <olivier.bichler@cea.fr>
Date: Thu, 6 Feb 2025 12:23:37 +0100
Subject: [PATCH 1/5] Fixed attributes not properly cloned in GenericOperator
 copy constructor

---
 src/operator/GenericOperator.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/operator/GenericOperator.cpp b/src/operator/GenericOperator.cpp
index 1e28cf289..e0f7cf34a 100644
--- a/src/operator/GenericOperator.cpp
+++ b/src/operator/GenericOperator.cpp
@@ -45,7 +45,7 @@ Aidge::GenericOperator_Op::GenericOperator_Op(const std::string& type,
 Aidge::GenericOperator_Op::GenericOperator_Op(const Aidge::GenericOperator_Op& op)
     : OperatorTensor(op),
         mForwardDims(op.mForwardDims),
-        mAttributes(op.attributes() ? op.mAttributes : std::make_shared<DynamicAttributes>())
+        mAttributes(std::make_shared<DynamicAttributes>(*op.mAttributes))
 {
     mImpl = std::make_shared<OperatorImpl>(*this, op.backend());
 }
-- 
GitLab


From 62de1a25c9e4d69167f300982f81b66f8a211ed4 Mon Sep 17 00:00:00 2001
From: Olivier BICHLER <olivier.bichler@cea.fr>
Date: Thu, 6 Feb 2025 12:24:11 +0100
Subject: [PATCH 2/5] Coding style

---
 include/aidge/operator/Operator.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/aidge/operator/Operator.hpp b/include/aidge/operator/Operator.hpp
index 40899ffa7..dd59af175 100644
--- a/include/aidge/operator/Operator.hpp
+++ b/include/aidge/operator/Operator.hpp
@@ -118,12 +118,12 @@ public:
      */
     Operator(const Operator& op):
         std::enable_shared_from_this<Operator>(),
+        mType(op.mType),
         mOperatorType(op.mOperatorType),
         mInputsCategory(op.mInputsCategory),
         mNbOut(op.mNbOut),
         mBackEdges(op.mBackEdges)
     {
-        mType = op.mType;
         mImpl = nullptr;
         // Implementation is never cloned. It is up to the non-abstract Operator copy-constructor to create a new implementation matching the copied Operator implementation.
         // See https://gitlab.eclipse.org/eclipse/aidge/aidge_core/-/merge_requests/8#note_1214050 for the discussion.
-- 
GitLab


From 2463ebc95e4319e79d2176367eed41e645d80542 Mon Sep 17 00:00:00 2001
From: Olivier BICHLER <olivier.bichler@cea.fr>
Date: Thu, 6 Feb 2025 12:24:51 +0100
Subject: [PATCH 3/5] Fixed incorrect MetaOperator copy constructor and clone()
 method

---
 include/aidge/operator/MetaOperator.hpp |  5 +----
 src/operator/MetaOperator.cpp           | 22 +++++++++++++++++++++-
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/include/aidge/operator/MetaOperator.hpp b/include/aidge/operator/MetaOperator.hpp
index f7f1cdfd5..c6ab45290 100644
--- a/include/aidge/operator/MetaOperator.hpp
+++ b/include/aidge/operator/MetaOperator.hpp
@@ -69,10 +69,7 @@ public:
      * 
      * @param op The operator to copy.
      */
-    MetaOperator_Op(const MetaOperator_Op& op)
-        : OperatorTensor(op),
-          mGraph(op.mGraph->clone()) // Clone the micro-graph for isolation
-    {}
+    MetaOperator_Op(const MetaOperator_Op& op);
 
     /**
      * @brief Set the node for scheduling.
diff --git a/src/operator/MetaOperator.cpp b/src/operator/MetaOperator.cpp
index ae3c3ed6c..9a8a943fc 100644
--- a/src/operator/MetaOperator.cpp
+++ b/src/operator/MetaOperator.cpp
@@ -54,8 +54,28 @@ Aidge::MetaOperator_Op::MetaOperator_Op(const std::string& type, const std::shar
     }
 }
 
+Aidge::MetaOperator_Op::MetaOperator_Op(const MetaOperator_Op& op)
+    : OperatorTensor(op),
+        mGraph(op.mGraph->clone()), // Clone the micro-graph for isolation
+        mAttributes(std::make_shared<DynamicAttributes>(*op.mAttributes)) // Clone attributes
+{
+    // Associate outputs to micro-graph outputs for custom implementation
+    for (size_t outputIdx = 0; outputIdx < mOutputs.size(); ++outputIdx) {
+        const auto& outputOp = mGraph->getOrderedOutputs()[outputIdx];
+        if (outputOp.first) {
+            mOutputs[outputIdx] = std::dynamic_pointer_cast<Tensor>(outputOp.first->getOperator()->getRawOutput(outputOp.second));
+        }
+    }
+
+    // Attributes are already cloned.
+}
+
 std::shared_ptr<Aidge::Operator> Aidge::MetaOperator_Op::clone() const {
-    return std::make_shared<MetaOperator_Op>(type(), mGraph->clone());
+    auto metaOp = std::make_shared<MetaOperator_Op>(*this);
+    if (mImpl) {
+        metaOp->setBackend(mImpl->backend());
+    }
+    return metaOp;
 }
 
 void Aidge::MetaOperator_Op::associateInput(const IOIndex_t inputIdx, const std::shared_ptr<Data>& data) {
-- 
GitLab


From 86a757769d8b31ad9495b384988914c04d98e29a Mon Sep 17 00:00:00 2001
From: Olivier BICHLER <olivier.bichler@cea.fr>
Date: Thu, 6 Feb 2025 12:36:17 +0100
Subject: [PATCH 4/5] Added doc comment

---
 src/operator/MetaOperator.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/operator/MetaOperator.cpp b/src/operator/MetaOperator.cpp
index 9a8a943fc..96c5b219a 100644
--- a/src/operator/MetaOperator.cpp
+++ b/src/operator/MetaOperator.cpp
@@ -73,6 +73,9 @@ Aidge::MetaOperator_Op::MetaOperator_Op(const MetaOperator_Op& op)
 std::shared_ptr<Aidge::Operator> Aidge::MetaOperator_Op::clone() const {
     auto metaOp = std::make_shared<MetaOperator_Op>(*this);
     if (mImpl) {
+        // Only setBackend() is mImpl is not nullptr.
+        // The inner-graph backend is already set in MetaOperator_Op copy
+        // construtor, when the graph is cloned.
         metaOp->setBackend(mImpl->backend());
     }
     return metaOp;
-- 
GitLab


From 6c6b919954d3495bfca199e406305138e19a777d Mon Sep 17 00:00:00 2001
From: Olivier BICHLER <olivier.bichler@cea.fr>
Date: Thu, 6 Feb 2025 13:55:47 +0100
Subject: [PATCH 5/5] Removed mandatory type attribute for Meta op, which is
 redundant with Meta op impl registry

---
 src/backend/OperatorImpl.cpp | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/src/backend/OperatorImpl.cpp b/src/backend/OperatorImpl.cpp
index 71f4f04b2..08f5fe671 100644
--- a/src/backend/OperatorImpl.cpp
+++ b/src/backend/OperatorImpl.cpp
@@ -74,13 +74,6 @@ Aidge::ImplSpec Aidge::OperatorImpl::getRequiredSpec() const {
 
         requiredSpec.outputs.push_back({opTensor.getOutput(i)->dataType(), opTensor.getOutput(i)->dataFormat(), dims});
     }
-    // Attributes
-    if (!mOp.isAtomic()) {
-        requiredSpec.attrs.setAttr("type:!", mOp.type()); // :! mandatory qualifier
-    }
-    else {
-        requiredSpec.attrs.setAttr("type", mOp.type());
-    }
 
     const auto& inhAttrs = mOp.inheritedAttributes();
     if (inhAttrs) {
-- 
GitLab