From fa8d7f33458ecb7d7e5c65eeb5e2387d027ea97c Mon Sep 17 00:00:00 2001
From: Olivier BICHLER <olivier.bichler@cea.fr>
Date: Fri, 15 Mar 2024 14:35:36 +0100
Subject: [PATCH] Updated C-P model to work with both data and tokens

---
 .../aidge/backend/cpu/operator/AddImpl.hpp    |  2 +-
 .../backend/cpu/operator/AvgPoolingImpl.hpp   |  2 +-
 .../backend/cpu/operator/BatchNormImpl.hpp    |  2 +-
 .../aidge/backend/cpu/operator/ConcatImpl.hpp | 12 ------
 .../cpu/operator/ConvDepthWiseImpl.hpp        |  2 +-
 .../aidge/backend/cpu/operator/ConvImpl.hpp   |  2 +-
 .../aidge/backend/cpu/operator/DivImpl.hpp    |  2 +-
 .../aidge/backend/cpu/operator/ErfImpl.hpp    |  2 +-
 .../aidge/backend/cpu/operator/GatherImpl.hpp |  1 -
 .../backend/cpu/operator/LeakyReLUImpl.hpp    |  2 +-
 .../backend/cpu/operator/MaxPoolingImpl.hpp   |  2 +-
 .../backend/cpu/operator/MemorizeImpl.hpp     |  4 +-
 .../aidge/backend/cpu/operator/MulImpl.hpp    |  2 +-
 .../aidge/backend/cpu/operator/PadImpl.hpp    |  2 +-
 .../aidge/backend/cpu/operator/PopImpl.hpp    |  2 +-
 .../aidge/backend/cpu/operator/PowImpl.hpp    |  2 +-
 .../aidge/backend/cpu/operator/ReLUImpl.hpp   |  2 +-
 .../backend/cpu/operator/ReduceMeanImpl.hpp   |  3 --
 .../backend/cpu/operator/ReshapeImpl.hpp      |  2 +-
 .../backend/cpu/operator/ScalingImpl.hpp      |  2 +-
 .../backend/cpu/operator/SigmoidImpl.hpp      |  2 +-
 .../aidge/backend/cpu/operator/SliceImpl.hpp  |  8 ----
 .../backend/cpu/operator/SoftmaxImpl.hpp      |  2 +-
 .../aidge/backend/cpu/operator/SqrtImpl.hpp   |  2 +-
 .../aidge/backend/cpu/operator/SubImpl.hpp    |  2 +-
 .../aidge/backend/cpu/operator/TanhImpl.hpp   |  2 +-
 .../backend/cpu/operator/TransposeImpl.hpp    |  5 ---
 src/operator/AddImpl.cpp                      |  4 +-
 src/operator/AvgPoolingImpl.cpp               |  4 +-
 src/operator/BatchNormImpl.cpp                |  4 +-
 src/operator/ConcatImpl.cpp                   | 40 -------------------
 src/operator/ConvDepthWiseImpl.cpp            |  4 +-
 src/operator/ConvImpl.cpp                     |  4 +-
 src/operator/DivImpl.cpp                      |  4 +-
 src/operator/ErfImpl.cpp                      |  4 +-
 src/operator/GatherImpl.cpp                   |  5 ---
 src/operator/LeakyReLUImpl.cpp                |  4 +-
 src/operator/MaxPoolingImpl.cpp               |  4 +-
 src/operator/MemorizeImpl.cpp                 | 12 +++---
 src/operator/MulImpl.cpp                      |  4 +-
 src/operator/PadImpl.cpp                      |  4 +-
 src/operator/PopImpl.cpp                      |  6 +--
 src/operator/PowImpl.cpp                      |  4 +-
 src/operator/ReLUImpl.cpp                     |  4 +-
 src/operator/ReduceMeanImpl.cpp               | 12 ------
 src/operator/ReshapeImpl.cpp                  |  4 +-
 src/operator/ScalingImpl.cpp                  |  4 +-
 src/operator/SigmoidImpl.cpp                  |  4 +-
 src/operator/SliceImpl.cpp                    | 36 -----------------
 src/operator/SoftmaxImpl.cpp                  |  4 +-
 src/operator/SqrtImpl.cpp                     |  4 +-
 src/operator/SubImpl.cpp                      |  4 +-
 src/operator/TanhImpl.cpp                     |  4 +-
 src/operator/TransposeImpl.cpp                | 21 ----------
 unit_tests/operator/Test_MetaOperator.cpp     |  8 ++--
 55 files changed, 76 insertions(+), 219 deletions(-)

diff --git a/include/aidge/backend/cpu/operator/AddImpl.hpp b/include/aidge/backend/cpu/operator/AddImpl.hpp
index 57669c62..6cb72e91 100644
--- a/include/aidge/backend/cpu/operator/AddImpl.hpp
+++ b/include/aidge/backend/cpu/operator/AddImpl.hpp
@@ -39,7 +39,7 @@ public:
         return std::make_unique<AddImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t /*inputIdx*/) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t /*inputIdx*/) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/AvgPoolingImpl.hpp b/include/aidge/backend/cpu/operator/AvgPoolingImpl.hpp
index bfb2b194..38dbd4b5 100644
--- a/include/aidge/backend/cpu/operator/AvgPoolingImpl.hpp
+++ b/include/aidge/backend/cpu/operator/AvgPoolingImpl.hpp
@@ -44,7 +44,7 @@ public:
         return std::make_unique<AvgPoolingImpl2D_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/BatchNormImpl.hpp b/include/aidge/backend/cpu/operator/BatchNormImpl.hpp
index a599aeb7..92797ab0 100644
--- a/include/aidge/backend/cpu/operator/BatchNormImpl.hpp
+++ b/include/aidge/backend/cpu/operator/BatchNormImpl.hpp
@@ -59,7 +59,7 @@ public:
         return std::make_unique<BatchNormImpl2D_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/ConcatImpl.hpp b/include/aidge/backend/cpu/operator/ConcatImpl.hpp
index d0d3e063..02d52c85 100644
--- a/include/aidge/backend/cpu/operator/ConcatImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ConcatImpl.hpp
@@ -48,18 +48,6 @@ public:
     }
 
 public:
-    NbElts_t getNbRequiredData(const IOIndex_t inputIdx) const override final;
-
-    NbElts_t getNbRequiredProtected(const IOIndex_t /*inputIdx*/) const override final;
-
-    NbElts_t getRequiredMemory(const IOIndex_t outputIdx, const std::vector<DimSize_t>& /*inputsSize*/) const override final;
-
-    NbElts_t getNbConsumedData(const IOIndex_t inputIdx) const override final;
-
-    NbElts_t getNbProducedData(const IOIndex_t outputIdx) const override final;
-
-    void updateConsummerProducer() override final;
-
     void forward() override;
 
     void backward() override;
diff --git a/include/aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp b/include/aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp
index f72890d8..44bc5da3 100644
--- a/include/aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp
@@ -46,7 +46,7 @@ public:
         return std::make_unique<ConvDepthWiseImpl2D_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/ConvImpl.hpp b/include/aidge/backend/cpu/operator/ConvImpl.hpp
index 9bc2f274..2915210d 100644
--- a/include/aidge/backend/cpu/operator/ConvImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ConvImpl.hpp
@@ -47,7 +47,7 @@ class ConvImpl2D_cpu : public OperatorImpl {
     }
 
    public:
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/DivImpl.hpp b/include/aidge/backend/cpu/operator/DivImpl.hpp
index 710e288d..6bedf627 100644
--- a/include/aidge/backend/cpu/operator/DivImpl.hpp
+++ b/include/aidge/backend/cpu/operator/DivImpl.hpp
@@ -40,7 +40,7 @@ public:
         return std::make_unique<DivImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
 
     void forward() override final;
 };
diff --git a/include/aidge/backend/cpu/operator/ErfImpl.hpp b/include/aidge/backend/cpu/operator/ErfImpl.hpp
index 5c0a6fd4..517eab35 100644
--- a/include/aidge/backend/cpu/operator/ErfImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ErfImpl.hpp
@@ -38,7 +38,7 @@ public:
         return std::make_unique<ErfImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/GatherImpl.hpp b/include/aidge/backend/cpu/operator/GatherImpl.hpp
index 1d235ff1..28c9a31d 100644
--- a/include/aidge/backend/cpu/operator/GatherImpl.hpp
+++ b/include/aidge/backend/cpu/operator/GatherImpl.hpp
@@ -38,7 +38,6 @@ public:
         return std::make_unique<GatherImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/LeakyReLUImpl.hpp b/include/aidge/backend/cpu/operator/LeakyReLUImpl.hpp
index 4a1da034..b60143db 100644
--- a/include/aidge/backend/cpu/operator/LeakyReLUImpl.hpp
+++ b/include/aidge/backend/cpu/operator/LeakyReLUImpl.hpp
@@ -39,7 +39,7 @@ public:
         return std::make_unique<LeakyReLUImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/MaxPoolingImpl.hpp b/include/aidge/backend/cpu/operator/MaxPoolingImpl.hpp
index 6cde34d9..675f3c4a 100644
--- a/include/aidge/backend/cpu/operator/MaxPoolingImpl.hpp
+++ b/include/aidge/backend/cpu/operator/MaxPoolingImpl.hpp
@@ -44,7 +44,7 @@ public:
         return std::make_unique<MaxPoolingImpl2D_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/MemorizeImpl.hpp b/include/aidge/backend/cpu/operator/MemorizeImpl.hpp
index 65694780..af571a0c 100644
--- a/include/aidge/backend/cpu/operator/MemorizeImpl.hpp
+++ b/include/aidge/backend/cpu/operator/MemorizeImpl.hpp
@@ -29,8 +29,8 @@ public:
         return std::make_unique<MemorizeImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredData(const IOIndex_t inputIdx) const override final;
-    NbElts_t getRequiredMemory(const Aidge::IOIndex_t outputIdx,
+    Elts_t getNbRequiredData(const IOIndex_t inputIdx) const override final;
+    Elts_t getRequiredMemory(const Aidge::IOIndex_t outputIdx,
                                const std::vector<Aidge::DimSize_t> &/*inputsSize*/) const override final;
     void updateConsummerProducer() override final;
     void forward() override;
diff --git a/include/aidge/backend/cpu/operator/MulImpl.hpp b/include/aidge/backend/cpu/operator/MulImpl.hpp
index a6f63ba2..6773b6f4 100644
--- a/include/aidge/backend/cpu/operator/MulImpl.hpp
+++ b/include/aidge/backend/cpu/operator/MulImpl.hpp
@@ -39,7 +39,7 @@ public:
         return std::make_unique<MulImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/PadImpl.hpp b/include/aidge/backend/cpu/operator/PadImpl.hpp
index 23206627..41032c72 100644
--- a/include/aidge/backend/cpu/operator/PadImpl.hpp
+++ b/include/aidge/backend/cpu/operator/PadImpl.hpp
@@ -46,7 +46,7 @@ public:
         return std::make_unique<PadImpl2D_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/PopImpl.hpp b/include/aidge/backend/cpu/operator/PopImpl.hpp
index 86c20349..d7e484a5 100644
--- a/include/aidge/backend/cpu/operator/PopImpl.hpp
+++ b/include/aidge/backend/cpu/operator/PopImpl.hpp
@@ -39,7 +39,7 @@ public:
         return std::make_unique<PopImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredData(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredData(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/PowImpl.hpp b/include/aidge/backend/cpu/operator/PowImpl.hpp
index c6e4cd36..7d17b370 100644
--- a/include/aidge/backend/cpu/operator/PowImpl.hpp
+++ b/include/aidge/backend/cpu/operator/PowImpl.hpp
@@ -39,7 +39,7 @@ public:
         return std::make_unique<PowImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/ReLUImpl.hpp b/include/aidge/backend/cpu/operator/ReLUImpl.hpp
index 3338d0c4..d8f8272f 100644
--- a/include/aidge/backend/cpu/operator/ReLUImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ReLUImpl.hpp
@@ -39,7 +39,7 @@ public:
         return std::make_unique<ReLUImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/ReduceMeanImpl.hpp b/include/aidge/backend/cpu/operator/ReduceMeanImpl.hpp
index 9b85eb81..3c0fe637 100644
--- a/include/aidge/backend/cpu/operator/ReduceMeanImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ReduceMeanImpl.hpp
@@ -64,7 +64,6 @@ class ReduceMeanImpl1D_cpu : public OperatorImpl {
     }
 
    public:
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
@@ -77,7 +76,6 @@ class ReduceMeanImpl2D_cpu : public OperatorImpl {
     }
 
    public:
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
@@ -90,7 +88,6 @@ class ReduceMeanImpl3D_cpu : public OperatorImpl {
     }
 
    public:
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 namespace {
diff --git a/include/aidge/backend/cpu/operator/ReshapeImpl.hpp b/include/aidge/backend/cpu/operator/ReshapeImpl.hpp
index d5754b34..0a8b851f 100644
--- a/include/aidge/backend/cpu/operator/ReshapeImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ReshapeImpl.hpp
@@ -38,7 +38,7 @@ public:
         return std::make_unique<ReshapeImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/ScalingImpl.hpp b/include/aidge/backend/cpu/operator/ScalingImpl.hpp
index bbcb4553..29b61704 100644
--- a/include/aidge/backend/cpu/operator/ScalingImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ScalingImpl.hpp
@@ -40,7 +40,7 @@ public:
         return std::make_unique<ScalingImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/SigmoidImpl.hpp b/include/aidge/backend/cpu/operator/SigmoidImpl.hpp
index 8678a5a5..a34650d6 100644
--- a/include/aidge/backend/cpu/operator/SigmoidImpl.hpp
+++ b/include/aidge/backend/cpu/operator/SigmoidImpl.hpp
@@ -39,7 +39,7 @@ public:
         return std::make_unique<SigmoidImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/SliceImpl.hpp b/include/aidge/backend/cpu/operator/SliceImpl.hpp
index 1cba5906..e129c2e6 100644
--- a/include/aidge/backend/cpu/operator/SliceImpl.hpp
+++ b/include/aidge/backend/cpu/operator/SliceImpl.hpp
@@ -46,14 +46,6 @@ public:
         return std::make_unique<SliceImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredData(const IOIndex_t /*inputIdx*/) const override final;
-    NbElts_t getNbRequiredProtected(const IOIndex_t /*inputIdx*/) const override final;
-    NbElts_t getRequiredMemory(const IOIndex_t outputIdx,
-                               const std::vector<DimSize_t>& inputsSize) const override final;
-    NbElts_t getNbConsumedData(const IOIndex_t /*inputIdx*/) const override final;
-    NbElts_t getNbProducedData(const IOIndex_t outputIdx) const override final;
-    void updateConsummerProducer() override final;
-
     void forward() override;
     void backward() override;
 };
diff --git a/include/aidge/backend/cpu/operator/SoftmaxImpl.hpp b/include/aidge/backend/cpu/operator/SoftmaxImpl.hpp
index 005b52f6..5625f7de 100644
--- a/include/aidge/backend/cpu/operator/SoftmaxImpl.hpp
+++ b/include/aidge/backend/cpu/operator/SoftmaxImpl.hpp
@@ -39,7 +39,7 @@ public:
         return std::make_unique<SoftmaxImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/SqrtImpl.hpp b/include/aidge/backend/cpu/operator/SqrtImpl.hpp
index b3723f27..f1848bde 100644
--- a/include/aidge/backend/cpu/operator/SqrtImpl.hpp
+++ b/include/aidge/backend/cpu/operator/SqrtImpl.hpp
@@ -39,7 +39,7 @@ public:
         return std::make_unique<SqrtImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/SubImpl.hpp b/include/aidge/backend/cpu/operator/SubImpl.hpp
index b329ec6e..a9006a04 100644
--- a/include/aidge/backend/cpu/operator/SubImpl.hpp
+++ b/include/aidge/backend/cpu/operator/SubImpl.hpp
@@ -39,7 +39,7 @@ public:
         return std::make_unique<SubImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/TanhImpl.hpp b/include/aidge/backend/cpu/operator/TanhImpl.hpp
index 3e88a3d0..b477d0bd 100644
--- a/include/aidge/backend/cpu/operator/TanhImpl.hpp
+++ b/include/aidge/backend/cpu/operator/TanhImpl.hpp
@@ -39,7 +39,7 @@ public:
         return std::make_unique<TanhImpl_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    Elts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/include/aidge/backend/cpu/operator/TransposeImpl.hpp b/include/aidge/backend/cpu/operator/TransposeImpl.hpp
index 712e6727..a1b9d274 100644
--- a/include/aidge/backend/cpu/operator/TransposeImpl.hpp
+++ b/include/aidge/backend/cpu/operator/TransposeImpl.hpp
@@ -63,7 +63,6 @@ public:
         return std::make_unique<TransposeImpl2D_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 class TransposeImpl3D_cpu : public OperatorImpl {
@@ -74,7 +73,6 @@ public:
         return std::make_unique<TransposeImpl3D_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 class TransposeImpl4D_cpu : public OperatorImpl {
@@ -85,7 +83,6 @@ public:
         return std::make_unique<TransposeImpl4D_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 class TransposeImpl5D_cpu : public OperatorImpl {
@@ -96,7 +93,6 @@ public:
         return std::make_unique<TransposeImpl5D_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 class TransposeImpl6D_cpu : public OperatorImpl {
@@ -107,7 +103,6 @@ public:
         return std::make_unique<TransposeImpl6D_cpu>(op);
     }
 
-    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
     void forward() override;
 };
 
diff --git a/src/operator/AddImpl.cpp b/src/operator/AddImpl.cpp
index 7355ebcb..98de9188 100644
--- a/src/operator/AddImpl.cpp
+++ b/src/operator/AddImpl.cpp
@@ -21,9 +21,9 @@
 #include "aidge/backend/cpu/operator/AddImpl.hpp"
 #include "aidge/backend/cpu/operator/AddImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t  Aidge::AddImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t  Aidge::AddImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void  Aidge::AddImpl_cpu::forward() {
diff --git a/src/operator/AvgPoolingImpl.cpp b/src/operator/AvgPoolingImpl.cpp
index 9e0a77e3..8ba6751b 100644
--- a/src/operator/AvgPoolingImpl.cpp
+++ b/src/operator/AvgPoolingImpl.cpp
@@ -21,9 +21,9 @@
 #include "aidge/backend/cpu/operator/AvgPoolingImpl.hpp"
 #include "aidge/backend/cpu/operator/AvgPoolingImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::AvgPoolingImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::AvgPoolingImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::AvgPoolingImpl2D_cpu::forward() {
diff --git a/src/operator/BatchNormImpl.cpp b/src/operator/BatchNormImpl.cpp
index c84f2cb6..96179d11 100644
--- a/src/operator/BatchNormImpl.cpp
+++ b/src/operator/BatchNormImpl.cpp
@@ -20,9 +20,9 @@
 #include "aidge/backend/cpu/operator/BatchNormImpl.hpp"
 #include "aidge/backend/cpu/operator/BatchNormImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::BatchNormImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::BatchNormImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::BatchNormImpl2D_cpu::forward() {
diff --git a/src/operator/ConcatImpl.cpp b/src/operator/ConcatImpl.cpp
index e142b79a..605f4a19 100644
--- a/src/operator/ConcatImpl.cpp
+++ b/src/operator/ConcatImpl.cpp
@@ -21,46 +21,6 @@
 #include "aidge/backend/cpu/operator/ConcatImpl.hpp"
 #include "aidge/backend/cpu/operator/ConcatImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::ConcatImpl_cpu::getNbRequiredData(const Aidge::IOIndex_t inputIdx) const {
-    assert(mOp.getRawInput(inputIdx) && "requires valid input");
-
-    // Requires the whole tensors
-    const auto& inputDims = std::static_pointer_cast<Tensor>(mOp.getRawInput(inputIdx))->dims();
-    return std::accumulate(inputDims.begin(), inputDims.end(), NbElts_t(1), std::multiplies<NbElts_t>());
-}
-
-Aidge::NbElts_t  Aidge::ConcatImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
-    // for the direct convolution algorithm, convolutions can be in-place, if there is no padding!
-    return 0;
-}
-
-Aidge::NbElts_t  Aidge::ConcatImpl_cpu::getRequiredMemory(const Aidge::IOIndex_t outputIdx, const std::vector<Aidge::DimSize_t>& /*inputsSize*/) const {
-    // Requires the whole tensors, regardless of available data on inputs
-    assert(outputIdx == 0 && "operator has only one output");
-    (void) outputIdx;
-
-    const auto& outputDims = std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dims();
-    return std::accumulate(outputDims.begin(), outputDims.end(), NbElts_t(1), std::multiplies<NbElts_t>());
-}
-
-Aidge::NbElts_t  Aidge::ConcatImpl_cpu::getNbConsumedData(const Aidge::IOIndex_t inputIdx) const {
-    assert(inputIdx < mNbConsumedData.size());
-    return mNbConsumedData[inputIdx];
-}
-
-Aidge::NbElts_t  Aidge::ConcatImpl_cpu::getNbProducedData(const Aidge::IOIndex_t outputIdx) const {
-    assert(outputIdx < mNbProducedData.size());
-    return mNbProducedData[outputIdx];
-}
-
-void  Aidge::ConcatImpl_cpu::updateConsummerProducer() {
-    for (IOIndex_t inputIdx = 0; static_cast<NbElts_t>(inputIdx) < mNbConsumedData.size(); ++inputIdx)
-        mNbConsumedData[inputIdx]+= getNbRequiredData(inputIdx); // each input is consumed by the minimum amount for a forward pass
-
-    mNbProducedData[0]+= getRequiredMemory(0, {});
-
-}
-
 void  Aidge::ConcatImpl_cpu::forward() {
     assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)) && "missing input in Concat operator");
     DataType datatypeFirstInput = std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType();
diff --git a/src/operator/ConvDepthWiseImpl.cpp b/src/operator/ConvDepthWiseImpl.cpp
index 1b4262e3..5c8d2fe3 100644
--- a/src/operator/ConvDepthWiseImpl.cpp
+++ b/src/operator/ConvDepthWiseImpl.cpp
@@ -22,9 +22,9 @@
 #include "aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp"
 #include "aidge/backend/cpu/operator/ConvDepthWiseImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::ConvDepthWiseImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::ConvDepthWiseImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::ConvDepthWiseImpl2D_cpu::forward() {
diff --git a/src/operator/ConvImpl.cpp b/src/operator/ConvImpl.cpp
index b849142d..3beb2bcf 100644
--- a/src/operator/ConvImpl.cpp
+++ b/src/operator/ConvImpl.cpp
@@ -22,9 +22,9 @@
 #include "aidge/backend/cpu/operator/ConvImpl.hpp"
 #include "aidge/backend/cpu/operator/ConvImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::ConvImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::ConvImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::ConvImpl2D_cpu::forward() {
diff --git a/src/operator/DivImpl.cpp b/src/operator/DivImpl.cpp
index 729aff24..bfb2ae64 100644
--- a/src/operator/DivImpl.cpp
+++ b/src/operator/DivImpl.cpp
@@ -19,9 +19,9 @@
 #include "aidge/data/Tensor.hpp"
 #include "aidge/utils/Types.h"
 
-Aidge::NbElts_t Aidge::DivImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::DivImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::DivImpl_cpu::forward() {
diff --git a/src/operator/ErfImpl.cpp b/src/operator/ErfImpl.cpp
index 06ec6500..1e6d2766 100644
--- a/src/operator/ErfImpl.cpp
+++ b/src/operator/ErfImpl.cpp
@@ -21,9 +21,9 @@
 #include "aidge/backend/cpu/operator/ErfImpl.hpp"
 #include "aidge/backend/cpu/operator/ErfImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::ErfImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::ErfImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::ErfImpl_cpu::forward() {
diff --git a/src/operator/GatherImpl.cpp b/src/operator/GatherImpl.cpp
index ce98627d..523cc036 100644
--- a/src/operator/GatherImpl.cpp
+++ b/src/operator/GatherImpl.cpp
@@ -21,11 +21,6 @@
 #include "aidge/backend/cpu/operator/GatherImpl.hpp"
 #include "aidge/backend/cpu/operator/GatherImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::GatherImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
-    // this implementation can be in-place
-    return 0;
-}
-
 void Aidge::GatherImpl_cpu::forward() {
 
     auto kernelFunc = Registrar<GatherImplForward_cpu>::create({
diff --git a/src/operator/LeakyReLUImpl.cpp b/src/operator/LeakyReLUImpl.cpp
index 17912eb1..7d41163e 100644
--- a/src/operator/LeakyReLUImpl.cpp
+++ b/src/operator/LeakyReLUImpl.cpp
@@ -22,9 +22,9 @@
 #include "aidge/backend/cpu/operator/LeakyReLUImpl.hpp"
 #include "aidge/backend/cpu/operator/LeakyReLUImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::LeakyReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::LeakyReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::LeakyReLUImpl_cpu::forward() {
diff --git a/src/operator/MaxPoolingImpl.cpp b/src/operator/MaxPoolingImpl.cpp
index e21dab07..94591eaa 100644
--- a/src/operator/MaxPoolingImpl.cpp
+++ b/src/operator/MaxPoolingImpl.cpp
@@ -21,9 +21,9 @@
 #include "aidge/backend/cpu/operator/MaxPoolingImpl.hpp"
 #include "aidge/backend/cpu/operator/MaxPoolingImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::MaxPoolingImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::MaxPoolingImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::MaxPoolingImpl2D_cpu::forward() {
diff --git a/src/operator/MemorizeImpl.cpp b/src/operator/MemorizeImpl.cpp
index b2956231..8a23bd35 100644
--- a/src/operator/MemorizeImpl.cpp
+++ b/src/operator/MemorizeImpl.cpp
@@ -21,7 +21,7 @@
 
 #include "aidge/backend/cpu/operator/MemorizeImpl.hpp"
 
-Aidge::DimSize_t Aidge::MemorizeImpl_cpu::getNbRequiredData(
+Aidge::Elts_t Aidge::MemorizeImpl_cpu::getNbRequiredData(
     Aidge::IOIndex_t inputIdx) const
 {
     const Memorize_Op& op = dynamic_cast<const Memorize_Op&>(mOp);
@@ -30,18 +30,18 @@ Aidge::DimSize_t Aidge::MemorizeImpl_cpu::getNbRequiredData(
     if (scheduleStep == 0 && inputIdx == 0) {
         // No data input is required for the initial step.
         // Initialization data is required however.
-        return 0;
+        return Elts_t::NoneElts();
     }
     else if (scheduleStep > 0 && inputIdx == 1) {
         // No initialization data is required after the initial step.
-        return 0;
+        return Elts_t::NoneElts();
     }
     else {
         return OperatorImpl::getNbRequiredData(inputIdx);
     }
 }
 
-Aidge::NbElts_t Aidge::MemorizeImpl_cpu::getRequiredMemory(const Aidge::IOIndex_t outputIdx,
+Aidge::Elts_t Aidge::MemorizeImpl_cpu::getRequiredMemory(const Aidge::IOIndex_t outputIdx,
                                                          const std::vector<Aidge::DimSize_t> &/*inputsSize*/) const {
     assert(mOp.getRawOutput(outputIdx) && "requires valid output");
 
@@ -50,10 +50,10 @@ Aidge::NbElts_t Aidge::MemorizeImpl_cpu::getRequiredMemory(const Aidge::IOIndex_
     const unsigned int endStep = op.template getAttr<MemorizeAttr::EndStep>();
 
     if (endStep > 0 && outputIdx == 1 && scheduleStep >= endStep) {
-        return 0;
+        return Elts_t::NoneElts();
     }
     else {
-        return std::static_pointer_cast<Tensor>(mOp.getRawOutput(outputIdx))->size();
+        return Elts_t::DataElts(std::static_pointer_cast<Tensor>(mOp.getRawOutput(outputIdx))->size());
     }
 }
 
diff --git a/src/operator/MulImpl.cpp b/src/operator/MulImpl.cpp
index 87d180b0..d7feb9b7 100644
--- a/src/operator/MulImpl.cpp
+++ b/src/operator/MulImpl.cpp
@@ -23,9 +23,9 @@
 #include "aidge/backend/cpu/operator/MulImpl.hpp"
 #include "aidge/backend/cpu/operator/MulImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::MulImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::MulImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::MulImpl_cpu::forward() {
diff --git a/src/operator/PadImpl.cpp b/src/operator/PadImpl.cpp
index 219bf425..cd420a62 100644
--- a/src/operator/PadImpl.cpp
+++ b/src/operator/PadImpl.cpp
@@ -22,7 +22,7 @@
 #include "aidge/backend/cpu/operator/PadImpl.hpp"
 #include "aidge/backend/cpu/operator/PadImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::PadImpl2D_cpu::getNbRequiredProtected(IOIndex_t inputIdx) const {
+Aidge::Elts_t Aidge::PadImpl2D_cpu::getNbRequiredProtected(IOIndex_t inputIdx) const {
     assert(inputIdx == 0 && "operator has only one input");
     (void) inputIdx;
 
@@ -30,7 +30,7 @@ Aidge::NbElts_t Aidge::PadImpl2D_cpu::getNbRequiredProtected(IOIndex_t inputIdx)
     // We must ensure that we do not override data that has not been consummed yet.
     const auto inputSize = std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size();
     const auto outputSize = std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->size();
-    return (outputSize - inputSize);
+    return Elts_t::DataElts(outputSize - inputSize);
 }
 
 void Aidge::PadImpl2D_cpu::forward() {
diff --git a/src/operator/PopImpl.cpp b/src/operator/PopImpl.cpp
index 86850610..02bbddba 100644
--- a/src/operator/PopImpl.cpp
+++ b/src/operator/PopImpl.cpp
@@ -21,11 +21,11 @@
 
 #include "aidge/backend/cpu/operator/PopImpl.hpp"
 
-Aidge::NbElts_t Aidge::PopImpl_cpu::getNbRequiredData(const Aidge::IOIndex_t inputIdx) const {
+Aidge::Elts_t Aidge::PopImpl_cpu::getNbRequiredData(const Aidge::IOIndex_t inputIdx) const {
     assert(mOp.getRawInput(inputIdx) && "requires valid input");
 
-    return std::static_pointer_cast<Tensor>(mOp.getRawInput(inputIdx))->size()
-        / std::static_pointer_cast<Tensor>(mOp.getRawInput(inputIdx))->dims()[0];
+    return Elts_t::DataElts(std::static_pointer_cast<Tensor>(mOp.getRawInput(inputIdx))->size()
+        / std::static_pointer_cast<Tensor>(mOp.getRawInput(inputIdx))->dims()[0]);
 }
 
 void Aidge::PopImpl_cpu::forward() {
diff --git a/src/operator/PowImpl.cpp b/src/operator/PowImpl.cpp
index 22b4e27a..782ca357 100644
--- a/src/operator/PowImpl.cpp
+++ b/src/operator/PowImpl.cpp
@@ -23,9 +23,9 @@
 #include "aidge/backend/cpu/operator/PowImpl.hpp"
 #include "aidge/backend/cpu/operator/PowImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::PowImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::PowImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::PowImpl_cpu::forward() {
diff --git a/src/operator/ReLUImpl.cpp b/src/operator/ReLUImpl.cpp
index 8863be28..81d1639d 100644
--- a/src/operator/ReLUImpl.cpp
+++ b/src/operator/ReLUImpl.cpp
@@ -22,9 +22,9 @@
 #include "aidge/backend/cpu/operator/ReLUImpl.hpp"
 #include "aidge/backend/cpu/operator/ReLUImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::ReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::ReLUImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::ReLUImpl_cpu::forward() {
diff --git a/src/operator/ReduceMeanImpl.cpp b/src/operator/ReduceMeanImpl.cpp
index e31a53d8..324daa9e 100644
--- a/src/operator/ReduceMeanImpl.cpp
+++ b/src/operator/ReduceMeanImpl.cpp
@@ -20,18 +20,6 @@
 
 #include "aidge/backend/cpu/operator/ReduceMeanImpl.hpp"
 #include "aidge/backend/cpu/operator/ReduceMeanImpl_forward_kernels.hpp"
-Aidge::NbElts_t Aidge::ReduceMeanImpl1D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
-    // this implementation can be in-place
-    return 0;
-}
-Aidge::NbElts_t Aidge::ReduceMeanImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
-    // this implementation can be in-place
-    return 0;
-}
-Aidge::NbElts_t Aidge::ReduceMeanImpl3D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
-    // this implementation can be in-place
-    return 0;
-}
 
 void Aidge::ReduceMeanImpl1D_cpu::forward() {
 
diff --git a/src/operator/ReshapeImpl.cpp b/src/operator/ReshapeImpl.cpp
index 02dea1da..8cd71c4e 100644
--- a/src/operator/ReshapeImpl.cpp
+++ b/src/operator/ReshapeImpl.cpp
@@ -17,9 +17,9 @@
 #include "aidge/backend/cpu/operator/ReshapeImpl.hpp"
 #include "aidge/backend/cpu/operator/ReshapeImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::ReshapeImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::ReshapeImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::ReshapeImpl_cpu::forward() {
diff --git a/src/operator/ScalingImpl.cpp b/src/operator/ScalingImpl.cpp
index 6b9aab31..d0b58702 100644
--- a/src/operator/ScalingImpl.cpp
+++ b/src/operator/ScalingImpl.cpp
@@ -21,9 +21,9 @@
 #include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <vector>
 
-Aidge::NbElts_t Aidge::ScalingImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::ScalingImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::ScalingImpl_cpu::forward() {
diff --git a/src/operator/SigmoidImpl.cpp b/src/operator/SigmoidImpl.cpp
index 7322e08b..dd7ec26c 100644
--- a/src/operator/SigmoidImpl.cpp
+++ b/src/operator/SigmoidImpl.cpp
@@ -22,9 +22,9 @@
 #include "aidge/backend/cpu/operator/SigmoidImpl.hpp"
 #include "aidge/backend/cpu/operator/SigmoidImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::SigmoidImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::SigmoidImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::SigmoidImpl_cpu::forward() {
diff --git a/src/operator/SliceImpl.cpp b/src/operator/SliceImpl.cpp
index c1a6480c..47b13c46 100644
--- a/src/operator/SliceImpl.cpp
+++ b/src/operator/SliceImpl.cpp
@@ -22,42 +22,6 @@
 #include <cassert>
 #include <tuple>
 
-Aidge::NbElts_t Aidge::SliceImpl_cpu::getNbRequiredData(const Aidge::IOIndex_t /*inputIdx*/) const {
-    assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)) && "requires valid input");
-
-    // Requires the whole tensors
-    const auto& inputDims = std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims();
-
-    return std::accumulate(inputDims.begin(), inputDims.end(), static_cast<NbElts_t>(1),
-                            std::multiplies<NbElts_t>());
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const { return 0; }
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu::getRequiredMemory(const Aidge::IOIndex_t outputIdx,
-                            const std::vector<Aidge::DimSize_t>& inputsSize) const {
-    (void)outputIdx;
-    (void)inputsSize;
-    const auto& outputDims = std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->dims();
-    return std::accumulate(outputDims.begin(), outputDims.end(), static_cast<NbElts_t>(1),
-                            std::multiplies<NbElts_t>());
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu::getNbConsumedData(const Aidge::IOIndex_t /*inputIdx*/) const {
-    return mNbConsumedData[0];
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu::getNbProducedData(const Aidge::IOIndex_t /*outputIdx*/) const {
-    return mNbProducedData[0];
-}
-
-void Aidge::SliceImpl_cpu::updateConsummerProducer() {
-    // each input is consumed by the minimum amount for a forward pass
-    mNbConsumedData[0] += getNbRequiredData(0);
-
-    mNbProducedData[0] += getRequiredMemory(0, {});
-}
-
 void Aidge::SliceImpl_cpu::forward() {
     // FIXME: uncomment the following code once memory handling will work
     assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)) && "missing input #0");
diff --git a/src/operator/SoftmaxImpl.cpp b/src/operator/SoftmaxImpl.cpp
index 5f5d7411..24026761 100644
--- a/src/operator/SoftmaxImpl.cpp
+++ b/src/operator/SoftmaxImpl.cpp
@@ -22,9 +22,9 @@
 #include "aidge/backend/cpu/operator/SoftmaxImpl.hpp"
 #include "aidge/backend/cpu/operator/SoftmaxImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::SoftmaxImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::SoftmaxImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::SoftmaxImpl_cpu::forward() {
diff --git a/src/operator/SqrtImpl.cpp b/src/operator/SqrtImpl.cpp
index 2766e8ae..8fcb2e9d 100644
--- a/src/operator/SqrtImpl.cpp
+++ b/src/operator/SqrtImpl.cpp
@@ -22,9 +22,9 @@
 #include "aidge/backend/cpu/operator/SqrtImpl.hpp"
 #include "aidge/backend/cpu/operator/SqrtImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::SqrtImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::SqrtImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::SqrtImpl_cpu::forward() {
diff --git a/src/operator/SubImpl.cpp b/src/operator/SubImpl.cpp
index 475f8cb8..ffddb59e 100644
--- a/src/operator/SubImpl.cpp
+++ b/src/operator/SubImpl.cpp
@@ -23,9 +23,9 @@
 #include "aidge/backend/cpu/operator/SubImpl.hpp"
 #include "aidge/backend/cpu/operator/SubImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::SubImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::SubImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::SubImpl_cpu::forward() {
diff --git a/src/operator/TanhImpl.cpp b/src/operator/TanhImpl.cpp
index c4658440..44e18073 100644
--- a/src/operator/TanhImpl.cpp
+++ b/src/operator/TanhImpl.cpp
@@ -22,9 +22,9 @@
 #include "aidge/backend/cpu/operator/TanhImpl.hpp"
 #include "aidge/backend/cpu/operator/TanhImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::TanhImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::Elts_t Aidge::TanhImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
     // this implementation can be in-place
-    return 0;
+    return Elts_t::DataElts(0);
 }
 
 void Aidge::TanhImpl_cpu::forward() {
diff --git a/src/operator/TransposeImpl.cpp b/src/operator/TransposeImpl.cpp
index 1fc4458c..710e67b4 100644
--- a/src/operator/TransposeImpl.cpp
+++ b/src/operator/TransposeImpl.cpp
@@ -21,27 +21,6 @@
 #include "aidge/backend/cpu/operator/TransposeImpl.hpp"
 #include "aidge/backend/cpu/operator/TransposeImpl_forward_kernels.hpp"
 
-Aidge::NbElts_t Aidge::TransposeImpl2D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
-    // this implementation can be in-place
-    return 0;
-}
-Aidge::NbElts_t Aidge::TransposeImpl3D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
-    // this implementation can be in-place
-    return 0;
-}
-Aidge::NbElts_t Aidge::TransposeImpl4D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
-    // this implementation can be in-place
-    return 0;
-}
-Aidge::NbElts_t Aidge::TransposeImpl5D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
-    // this implementation can be in-place
-    return 0;
-}
-Aidge::NbElts_t Aidge::TransposeImpl6D_cpu::getNbRequiredProtected(IOIndex_t /*inputIdx*/) const {
-    // this implementation can be in-place
-    return 0;
-}
-
 void Aidge::TransposeImpl2D_cpu::forward() {
     // Find the correct kernel type
     auto kernelFunc =
diff --git a/unit_tests/operator/Test_MetaOperator.cpp b/unit_tests/operator/Test_MetaOperator.cpp
index 5eea881d..63a11d19 100644
--- a/unit_tests/operator/Test_MetaOperator.cpp
+++ b/unit_tests/operator/Test_MetaOperator.cpp
@@ -245,10 +245,10 @@ TEST_CASE("[cpu/operator] MetaOperator", "[MetaOperator][CPU]") {
         auto microGraphScheduler = std::dynamic_pointer_cast<MetaOperator_Op>(op)->getMicroGraphScheduler();
         microGraphScheduler->saveSchedulingDiagram("lstm_scheduling");
 
-        REQUIRE(op->getNbConsumedData(0) == 512);
-        REQUIRE(op->getNbConsumedData(1) == 32768);
-        REQUIRE(op->getNbProducedData(0) == 34816);
-        REQUIRE(op->getNbProducedData(1) == 34816);
+        REQUIRE(op->getNbConsumedData(0).data == 512);
+        REQUIRE(op->getNbConsumedData(1).data == 32768);
+        REQUIRE(op->getNbProducedData(0).data == 34816);
+        REQUIRE(op->getNbProducedData(1).data == 34816);
         REQUIRE(microGraphScheduler->getStaticScheduling(0).size() == 26);
         REQUIRE(microGraphScheduler->getStaticScheduling(1).size() == 24);
         REQUIRE(microGraphScheduler->getStaticScheduling(15).size() == 24);
-- 
GitLab