From db71ebaf86f024802ac6b8eaa23ef381e79ed299 Mon Sep 17 00:00:00 2001
From: SOULIER Laurent <laurent.soulier@cea.fr>
Date: Fri, 1 Dec 2023 12:39:35 +0100
Subject: [PATCH] [fix/rawPtr][MIN][DSGN] encapsulating raw pointer access into
 an helper function in order to make it easier to change implementation
 related to aidge_core#21 and related to aidge_core!41 (which will get easier
 to merge threafter)

---
 include/aidge/backend/cpu/data/GetCPUPtr.h    |  23 ++
 .../aidge/backend/cpu/operator/AddImpl.hpp    |   1 +
 .../backend/cpu/operator/AvgPoolingImpl.hpp   |   1 +
 .../AvgPoolingImpl_forward_kernels.hpp        |   1 +
 .../backend/cpu/operator/BatchNormImpl.hpp    |   1 +
 .../BatchNormImpl_forward_kernels.hpp         |   1 +
 .../aidge/backend/cpu/operator/ConcatImpl.hpp |   1 +
 .../operator/ConcatImpl_forward_kernels.hpp   |   1 +
 .../cpu/operator/ConvDepthWiseImpl.hpp        |   1 +
 .../ConvDepthWiseImpl_forward_kernels.hpp     |   1 +
 .../aidge/backend/cpu/operator/ConvImpl.hpp   |   1 +
 .../cpu/operator/ConvImpl_forward_kernels.hpp |   1 +
 .../aidge/backend/cpu/operator/DivImpl.hpp    |   1 +
 include/aidge/backend/cpu/operator/FCImpl.hpp |   1 +
 .../backend/cpu/operator/LeakyReLUImpl.hpp    |   1 +
 .../aidge/backend/cpu/operator/MatMulImpl.hpp |   1 +
 .../backend/cpu/operator/MaxPoolingImpl.hpp   |   1 +
 .../MaxPoolingImpl_forward_kernels.hpp        |   1 +
 .../aidge/backend/cpu/operator/MulImpl.hpp    |   1 +
 .../aidge/backend/cpu/operator/PadImpl.hpp    |   1 +
 .../cpu/operator/PadImpl_forward_kernels.hpp  |   1 +
 .../aidge/backend/cpu/operator/PowImpl.hpp    |   1 +
 .../backend/cpu/operator/ProducerImpl.hpp     |   1 +
 .../aidge/backend/cpu/operator/ReLUImpl.hpp   |   1 +
 .../backend/cpu/operator/ScalingImpl.hpp      |   1 +
 .../aidge/backend/cpu/operator/SliceImpl.hpp  | 166 +-------------
 .../operator/SliceImpl_forward_kernels.hpp    |  75 +++----
 .../backend/cpu/operator/SoftmaxImpl.hpp      |   1 +
 .../operator/SoftmaxImpl_forward_kernels.hpp  |   1 +
 .../aidge/backend/cpu/operator/SqrtImpl.hpp   |   1 +
 .../aidge/backend/cpu/operator/SubImpl.hpp    |   1 +
 src/operator/AddImpl.cpp                      |   5 +-
 src/operator/AvgPoolingImpl.cpp               |   5 +-
 src/operator/BatchNormImpl.cpp                |  13 +-
 src/operator/ConcatImpl.cpp                   |   5 +-
 src/operator/ConvDepthWiseImpl.cpp            |   9 +-
 src/operator/ConvImpl.cpp                     |   5 +-
 src/operator/DivImpl.cpp                      |   7 +-
 src/operator/FCImpl.cpp                       |  11 +-
 src/operator/LeakyReLUImpl.cpp                |   5 +-
 src/operator/MatMulImpl.cpp                   |   9 +-
 src/operator/MaxPoolingImpl.cpp               |   5 +-
 src/operator/MulImpl.cpp                      |   7 +-
 src/operator/PadImpl.cpp                      |   5 +-
 src/operator/PowImpl.cpp                      |   7 +-
 src/operator/ProducerImpl.cpp                 |   1 +
 src/operator/ReLUImpl.cpp                     |   5 +-
 src/operator/ScalingImpl.cpp                  |   5 +-
 src/operator/SliceImpl.cpp                    | 208 ++----------------
 src/operator/SoftmaxImpl.cpp                  |   5 +-
 src/operator/SqrtImpl.cpp                     |   5 +-
 src/operator/SubImpl.cpp                      |   7 +-
 52 files changed, 177 insertions(+), 449 deletions(-)
 create mode 100644 include/aidge/backend/cpu/data/GetCPUPtr.h

diff --git a/include/aidge/backend/cpu/data/GetCPUPtr.h b/include/aidge/backend/cpu/data/GetCPUPtr.h
new file mode 100644
index 00000000..38ea848a
--- /dev/null
+++ b/include/aidge/backend/cpu/data/GetCPUPtr.h
@@ -0,0 +1,23 @@
+/********************************************************************************
+ * 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_CPU_DATA_GETCPUPTR_H_
+#define AIDGE_CPU_DATA_GETCPUPTR_H_
+
+#include "aidge/data/Tensor.hpp"
+
+namespace Aidge {
+inline void *getCPUPtr(std::shared_ptr<Aidge::Data> const &data) {
+  return std::static_pointer_cast<Tensor>(data)->getImpl()->rawPtr();
+}
+} // namespace Aidge
+
+#endif // AIDGE_CPU_DATA_GETCPUPTR_H_
\ No newline at end of file
diff --git a/include/aidge/backend/cpu/operator/AddImpl.hpp b/include/aidge/backend/cpu/operator/AddImpl.hpp
index 806bbb02..fa1b8379 100644
--- a/include/aidge/backend/cpu/operator/AddImpl.hpp
+++ b/include/aidge/backend/cpu/operator/AddImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/Add.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 
diff --git a/include/aidge/backend/cpu/operator/AvgPoolingImpl.hpp b/include/aidge/backend/cpu/operator/AvgPoolingImpl.hpp
index e3c3a6a2..bfb2b194 100644
--- a/include/aidge/backend/cpu/operator/AvgPoolingImpl.hpp
+++ b/include/aidge/backend/cpu/operator/AvgPoolingImpl.hpp
@@ -21,6 +21,7 @@
 #include "aidge/operator/AvgPooling.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 namespace Aidge {
 // class AvgPooling_Op;
diff --git a/include/aidge/backend/cpu/operator/AvgPoolingImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/AvgPoolingImpl_forward_kernels.hpp
index ea46a540..5598cc9c 100644
--- a/include/aidge/backend/cpu/operator/AvgPoolingImpl_forward_kernels.hpp
+++ b/include/aidge/backend/cpu/operator/AvgPoolingImpl_forward_kernels.hpp
@@ -16,6 +16,7 @@
 
 #include "aidge/backend/cpu/operator/AvgPoolingImpl.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include "aidge/data/Data.hpp"
 #include <array>
 #include <tuple>
diff --git a/include/aidge/backend/cpu/operator/BatchNormImpl.hpp b/include/aidge/backend/cpu/operator/BatchNormImpl.hpp
index 060e19b1..a599aeb7 100644
--- a/include/aidge/backend/cpu/operator/BatchNormImpl.hpp
+++ b/include/aidge/backend/cpu/operator/BatchNormImpl.hpp
@@ -21,6 +21,7 @@
 #include "aidge/operator/BatchNorm.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 namespace Aidge {
 // class BatchNorm_Op;
diff --git a/include/aidge/backend/cpu/operator/BatchNormImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/BatchNormImpl_forward_kernels.hpp
index 486829e7..cfde6ebe 100644
--- a/include/aidge/backend/cpu/operator/BatchNormImpl_forward_kernels.hpp
+++ b/include/aidge/backend/cpu/operator/BatchNormImpl_forward_kernels.hpp
@@ -16,6 +16,7 @@
 
 #include "aidge/backend/cpu/operator/BatchNormImpl.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <array>
 #include <cmath>
 #include <algorithm>
diff --git a/include/aidge/backend/cpu/operator/ConcatImpl.hpp b/include/aidge/backend/cpu/operator/ConcatImpl.hpp
index a5e0c56e..d0d3e063 100644
--- a/include/aidge/backend/cpu/operator/ConcatImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ConcatImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/Concat.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 
diff --git a/include/aidge/backend/cpu/operator/ConcatImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/ConcatImpl_forward_kernels.hpp
index b76f384b..ed849b0e 100644
--- a/include/aidge/backend/cpu/operator/ConcatImpl_forward_kernels.hpp
+++ b/include/aidge/backend/cpu/operator/ConcatImpl_forward_kernels.hpp
@@ -22,6 +22,7 @@
 #include "aidge/operator/Concat.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 namespace Aidge {
 
diff --git a/include/aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp b/include/aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp
index 7b5dbfb0..f72890d8 100644
--- a/include/aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp
@@ -21,6 +21,7 @@
 #include "aidge/operator/ConvDepthWise.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 namespace Aidge {
 // class ConvDepthWise_Op;
diff --git a/include/aidge/backend/cpu/operator/ConvDepthWiseImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/ConvDepthWiseImpl_forward_kernels.hpp
index f40dfee0..95a1aaec 100644
--- a/include/aidge/backend/cpu/operator/ConvDepthWiseImpl_forward_kernels.hpp
+++ b/include/aidge/backend/cpu/operator/ConvDepthWiseImpl_forward_kernels.hpp
@@ -16,6 +16,7 @@
 
 #include "aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <cmath>
 #include <cstddef>
 #include <array>
diff --git a/include/aidge/backend/cpu/operator/ConvImpl.hpp b/include/aidge/backend/cpu/operator/ConvImpl.hpp
index 3db91ab5..9bc2f274 100644
--- a/include/aidge/backend/cpu/operator/ConvImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ConvImpl.hpp
@@ -21,6 +21,7 @@
 #include "aidge/operator/Conv.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 namespace Aidge {
 // class Conv_Op;
diff --git a/include/aidge/backend/cpu/operator/ConvImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/ConvImpl_forward_kernels.hpp
index 03e2c351..cbd78469 100644
--- a/include/aidge/backend/cpu/operator/ConvImpl_forward_kernels.hpp
+++ b/include/aidge/backend/cpu/operator/ConvImpl_forward_kernels.hpp
@@ -16,6 +16,7 @@
 
 #include "aidge/backend/cpu/operator/ConvImpl.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <cmath>
 #include <array>
 #include <algorithm>
diff --git a/include/aidge/backend/cpu/operator/DivImpl.hpp b/include/aidge/backend/cpu/operator/DivImpl.hpp
index 655a9f6c..73809ee8 100644
--- a/include/aidge/backend/cpu/operator/DivImpl.hpp
+++ b/include/aidge/backend/cpu/operator/DivImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/Div.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 
diff --git a/include/aidge/backend/cpu/operator/FCImpl.hpp b/include/aidge/backend/cpu/operator/FCImpl.hpp
index 5d793690..86bb7fd1 100644
--- a/include/aidge/backend/cpu/operator/FCImpl.hpp
+++ b/include/aidge/backend/cpu/operator/FCImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/FC.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 #include <array>
diff --git a/include/aidge/backend/cpu/operator/LeakyReLUImpl.hpp b/include/aidge/backend/cpu/operator/LeakyReLUImpl.hpp
index 371e2905..4a1da034 100644
--- a/include/aidge/backend/cpu/operator/LeakyReLUImpl.hpp
+++ b/include/aidge/backend/cpu/operator/LeakyReLUImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/LeakyReLU.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 
diff --git a/include/aidge/backend/cpu/operator/MatMulImpl.hpp b/include/aidge/backend/cpu/operator/MatMulImpl.hpp
index 2e4b3157..e8654c6e 100644
--- a/include/aidge/backend/cpu/operator/MatMulImpl.hpp
+++ b/include/aidge/backend/cpu/operator/MatMulImpl.hpp
@@ -20,6 +20,7 @@
 #include "aidge/operator/MatMul.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 namespace Aidge {
 // class MatMul_Op;
diff --git a/include/aidge/backend/cpu/operator/MaxPoolingImpl.hpp b/include/aidge/backend/cpu/operator/MaxPoolingImpl.hpp
index a96fcc22..6cde34d9 100644
--- a/include/aidge/backend/cpu/operator/MaxPoolingImpl.hpp
+++ b/include/aidge/backend/cpu/operator/MaxPoolingImpl.hpp
@@ -21,6 +21,7 @@
 #include "aidge/operator/MaxPooling.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 namespace Aidge {
 // class MaxPooling_Op;
diff --git a/include/aidge/backend/cpu/operator/MaxPoolingImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/MaxPoolingImpl_forward_kernels.hpp
index caa99e86..c4baccde 100644
--- a/include/aidge/backend/cpu/operator/MaxPoolingImpl_forward_kernels.hpp
+++ b/include/aidge/backend/cpu/operator/MaxPoolingImpl_forward_kernels.hpp
@@ -16,6 +16,7 @@
 
 #include "aidge/backend/cpu/operator/MaxPoolingImpl.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include "aidge/data/Data.hpp"
 #include <array>
 #include <tuple>
diff --git a/include/aidge/backend/cpu/operator/MulImpl.hpp b/include/aidge/backend/cpu/operator/MulImpl.hpp
index 54361e4f..f1b58e59 100644
--- a/include/aidge/backend/cpu/operator/MulImpl.hpp
+++ b/include/aidge/backend/cpu/operator/MulImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/Mul.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 
diff --git a/include/aidge/backend/cpu/operator/PadImpl.hpp b/include/aidge/backend/cpu/operator/PadImpl.hpp
index 9d93828f..23206627 100644
--- a/include/aidge/backend/cpu/operator/PadImpl.hpp
+++ b/include/aidge/backend/cpu/operator/PadImpl.hpp
@@ -21,6 +21,7 @@
 #include "aidge/operator/Pad.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 namespace Aidge {
 // class Pad_Op;
diff --git a/include/aidge/backend/cpu/operator/PadImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/PadImpl_forward_kernels.hpp
index 8b793257..f6f00bc4 100644
--- a/include/aidge/backend/cpu/operator/PadImpl_forward_kernels.hpp
+++ b/include/aidge/backend/cpu/operator/PadImpl_forward_kernels.hpp
@@ -16,6 +16,7 @@
 
 #include "aidge/backend/cpu/operator/PadImpl.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <cmath>
 #include <array>
 #include <algorithm>
diff --git a/include/aidge/backend/cpu/operator/PowImpl.hpp b/include/aidge/backend/cpu/operator/PowImpl.hpp
index c33fbf0e..d3cafa7e 100644
--- a/include/aidge/backend/cpu/operator/PowImpl.hpp
+++ b/include/aidge/backend/cpu/operator/PowImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/Pow.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 
diff --git a/include/aidge/backend/cpu/operator/ProducerImpl.hpp b/include/aidge/backend/cpu/operator/ProducerImpl.hpp
index 19361f19..c1d27f7e 100644
--- a/include/aidge/backend/cpu/operator/ProducerImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ProducerImpl.hpp
@@ -18,6 +18,7 @@
 #include "aidge/operator/Producer.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 namespace Aidge {
 class ProducerImpl_cpu : public OperatorImpl {
diff --git a/include/aidge/backend/cpu/operator/ReLUImpl.hpp b/include/aidge/backend/cpu/operator/ReLUImpl.hpp
index 6596c1c9..3338d0c4 100644
--- a/include/aidge/backend/cpu/operator/ReLUImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ReLUImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/ReLU.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 
diff --git a/include/aidge/backend/cpu/operator/ScalingImpl.hpp b/include/aidge/backend/cpu/operator/ScalingImpl.hpp
index e336adb0..bbcb4553 100644
--- a/include/aidge/backend/cpu/operator/ScalingImpl.hpp
+++ b/include/aidge/backend/cpu/operator/ScalingImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/Scaling.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 #include <array>
diff --git a/include/aidge/backend/cpu/operator/SliceImpl.hpp b/include/aidge/backend/cpu/operator/SliceImpl.hpp
index 06c7cf29..56fdf8b6 100644
--- a/include/aidge/backend/cpu/operator/SliceImpl.hpp
+++ b/include/aidge/backend/cpu/operator/SliceImpl.hpp
@@ -26,95 +26,26 @@ namespace Aidge {
 // class Slice_Op;
 
 // compute kernel registry for forward and backward
-template <DimIdx_t DIM>
 class SliceImplForward_cpu
-    : public Registrable<SliceImplForward_cpu<DIM>, std::tuple<DataType>,
-                         void(const typename Slice_Op<DIM>::Attrs&,
-                              const std::array<std::size_t, DIM>,
+    : public Registrable<SliceImplForward_cpu, std::tuple<DataType>,
+                         void(const typename Slice_Op::Attrs&,
+                              const std::vector<std::size_t>,
                               const void*,
                               void*)> {};
-template <DimIdx_t DIM>
 class SliceImplBackward_cpu
-    : public Registrable<SliceImplBackward_cpu<DIM>, std::tuple<DataType>,
-                         void(const typename Slice_Op<DIM>::Attrs&,
-                              const std::array<std::size_t, DIM>,
+    : public Registrable<SliceImplBackward_cpu, std::tuple<DataType>,
+                         void(const typename Slice_Op::Attrs&,
+                              const std::vector<std::size_t>,
                               const void*,
                               void*)> {};
 
-template <DimIdx_t DIM>
-class SliceImpl_cpu : public OperatorImpl {
-   public:
-    SliceImpl_cpu(const Slice_Op<DIM>& op) : OperatorImpl(op) {}
-
-    static std::unique_ptr<SliceImpl_cpu<DIM>> create(const Slice_Op<DIM>& op) {
-        return std::make_unique<SliceImpl_cpu<DIM>>(op);
-    }
-
-   public:
-    NbElts_t getNbRequiredData(const IOIndex_t /*inputIdx*/) const override final {
-        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>());
-    }
-    NbElts_t getNbRequiredProtected(const IOIndex_t /*inputIdx*/) const override final { return 0; }
-    NbElts_t getRequiredMemory(const IOIndex_t outputIdx,
-                               const std::vector<DimSize_t>& inputsSize) const override final {
-        (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>());
-    }
-    NbElts_t getNbConsumedData(const IOIndex_t /*inputIdx*/) const override final {
-        return mNbConsumedData[0];
-    }
-    NbElts_t getNbProducedData(const IOIndex_t /*outputIdx*/) const override final {
-        return mNbProducedData[0];
-    }
-    void updateConsummerProducer() override final {
-        // each input is consumed by the minimum amount for a forward pass
-        mNbConsumedData[0] += getNbRequiredData(0);
-
-        mNbProducedData[0] += getRequiredMemory(0, {});
-    }
-
-    void forward() override {
-        // FIXME: uncomment the following code once memory handling will work
-        assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)) && "missing input #0");
-
-        // Find the correct kernel type
-        auto kernelFunc = Registrar<SliceImplForward_cpu<DIM>>::create(
-                {std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType()});
-
-        // Call kernel
-        kernelFunc(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<DIM>(),
-                   std::get<1>(std::static_pointer_cast<const Slice_Op<DIM>&>(mOp).getStaticAttributes()),
-                   std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-                   std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr()
-                );
-
-        // each input is consumed by the minimum amount for a forward pass
-        mNbConsumedData[0] += getNbRequiredData(0);
-
-        mNbProducedData[0] += getRequiredMemory(0, {});
-    }
-
-    void backward() override { printf("Not implemented yet.\n"); }
-};
 
-/******************************************************************************/
-
-template <>
-class SliceImpl_cpu<1> : public OperatorImpl {
+class SliceImpl_cpu : public OperatorImpl {
 public:
-    SliceImpl_cpu(const Slice_Op<1>& op) : OperatorImpl(op) {}
+    SliceImpl_cpu(const Slice_Op& op) : OperatorImpl(op) {}
 
-    static std::unique_ptr<SliceImpl_cpu<1>> create(const Slice_Op<1>& op) {
-        return std::make_unique<SliceImpl_cpu<1>>(op);
+    static std::unique_ptr<SliceImpl_cpu> create(const Slice_Op& op) {
+        return std::make_unique<SliceImpl_cpu>(op);
     }
 
 public:
@@ -127,88 +58,13 @@ public:
     void updateConsummerProducer() override final;
 
     void forward() override;
-    void backward() override;
-};
-
-/******************************************************************************/
-
-template <>
-class SliceImpl_cpu<2> : public OperatorImpl {
-   public:
-    SliceImpl_cpu(const Slice_Op<2>& op) : OperatorImpl(op) {}
 
-    static std::unique_ptr<SliceImpl_cpu<2>> create(const Slice_Op<2>& op) {
-        return std::make_unique<SliceImpl_cpu<2>>(op);
-    }
-
-   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;
-};
-
-/******************************************************************************/
-
-template <>
-class SliceImpl_cpu<3> : public OperatorImpl {
-   public:
-    SliceImpl_cpu(const Slice_Op<3>& op) : OperatorImpl(op) {}
-
-    static std::unique_ptr<SliceImpl_cpu<3>> create(const Slice_Op<3>& op) {
-        return std::make_unique<SliceImpl_cpu<3>>(op);
-    }
-
-   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;
 };
 
-/******************************************************************************/
-
-template <>
-class SliceImpl_cpu<4> : public OperatorImpl {
-   public:
-    SliceImpl_cpu(const Slice_Op<4>& op) : OperatorImpl(op) {}
-
-    static std::unique_ptr<SliceImpl_cpu<4>> create(const Slice_Op<4>& op) {
-        return std::make_unique<SliceImpl_cpu<4>>(op);
-    }
-
-   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;
-};
-
-
 
 namespace {
-static Registrar<Slice_Op<1>> registrarSliceImpl_1D_cpu("cpu", Aidge::SliceImpl_cpu<1>::create);
-static Registrar<Slice_Op<2>> registrarSliceImpl_2D_cpu("cpu", Aidge::SliceImpl_cpu<2>::create);
-static Registrar<Slice_Op<3>> registrarSliceImpl_3D_cpu("cpu", Aidge::SliceImpl_cpu<3>::create);
-static Registrar<Slice_Op<4>> registrarSliceImpl_4D_cpu("cpu", Aidge::SliceImpl_cpu<4>::create);
+static Registrar<Slice_Op> registrarSliceImpl_cpu("cpu", Aidge::SliceImpl_cpu::create);
 }  // namespace
 }  // namespace Aidge
 
diff --git a/include/aidge/backend/cpu/operator/SliceImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/SliceImpl_forward_kernels.hpp
index bbf4ccba..7eb4b9dc 100644
--- a/include/aidge/backend/cpu/operator/SliceImpl_forward_kernels.hpp
+++ b/include/aidge/backend/cpu/operator/SliceImpl_forward_kernels.hpp
@@ -15,46 +15,47 @@
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/operator/Slice.hpp"
 #include "aidge/backend/cpu/operator/SliceImpl.hpp"
-#include <array>
+#include <vector>
 #include <cstddef>
 
 #include "aidge/data/Data.hpp"
 
 namespace Aidge {
-template <class I, std::size_t DIM>
-void SliceImpl_cpu_forward_kernel(const typename Slice_Op<DIM>::Attrs& attrs,
-                                     const std::array<std::size_t, DIM> inputDims,
+template <class I>
+void SliceImpl_cpu_forward_kernel(const typename Slice_Op::Attrs& attrs,
+                                     const std::vector<std::size_t> inputDims,
                                      const void* input_,
                                      void* output_) {
 
     const I* input = static_cast<const I*>(input_) + std::get<0>(attrs);
     I* output = static_cast<I*>(output_);
-	const std::array<std::size_t, DIM> slicedDims = std::get<1>(attrs);
+    const std::vector<std::size_t> slicedDims = std::get<1>(attrs);
+    const std::size_t nbDims = slicedDims.size();
 
 	// for inputDims = {4,5,5,3} & slicedDims = {3,2,2,1}, substractDims = {1,5,5,3}
-    std::array<std::size_t, DIM> substractedDims;
-    for (std::size_t i = 0; i < DIM; ++i) {
+    std::vector<std::size_t> substractedDims = std::vector<std::size_t>(nbDims);
+    for (std::size_t i = 0; i < nbDims; ++i) {
         substractedDims[i] = inputDims[i] - slicedDims[i];
     }
 
 	// for slicedDims = {3,2,2,1}, prodSlicedDims = {12,4,2,1}
-    std::array<std::size_t, DIM> prodSlicedDims;
-    std::array<std::size_t, DIM+1> prodInputDims;
-	prodSlicedDims[DIM - 1] = slicedDims[DIM - 1];
-	prodInputDims[DIM - 1] = inputDims[DIM - 1];
-	prodInputDims[DIM] = 1;
-	for (std::size_t i = 2; i <= DIM; ++i) {
-		prodSlicedDims[DIM - i] = prodSlicedDims[DIM - i + 1]*slicedDims[DIM - i];
-		prodInputDims[DIM - i] = prodInputDims[DIM - i + 1]*inputDims[DIM - i];
+    std::vector<std::size_t> prodSlicedDims = std::vector<std::size_t>(nbDims);
+    std::vector<std::size_t> prodInputDims = std::vector<std::size_t>(nbDims+1);
+	prodSlicedDims[nbDims - 1] = slicedDims[nbDims - 1];
+	prodInputDims[nbDims - 1] = inputDims[nbDims - 1];
+	prodInputDims[nbDims] = 1;
+	for (std::size_t i = 2; i <= nbDims; ++i) {
+		prodSlicedDims[nbDims - i] = prodSlicedDims[nbDims - i + 1]*slicedDims[nbDims - i];
+		prodInputDims[nbDims - i] = prodInputDims[nbDims - i + 1]*inputDims[nbDims - i];
 	}
 
 	std::size_t j = 0;
 	std::size_t i = 0;
 	for (; j < prodSlicedDims[0];) {
 		output[j] = input[i++];
-                ++j;
-		for (std::size_t idx = DIM - 1; idx > 0; --idx) {
-				i += j % prodSlicedDims[idx] == 0 ? substractedDims[idx]*prodInputDims[idx+1] : 0;
+        ++j;
+		for (std::size_t idx = nbDims - 1; idx > 0; --idx) {
+			i += j % prodSlicedDims[idx] == 0 ? substractedDims[idx]*prodInputDims[idx+1] : 0;
 		}
 	}
 }
@@ -62,37 +63,13 @@ void SliceImpl_cpu_forward_kernel(const typename Slice_Op<DIM>::Attrs& attrs,
 namespace {
 
 // DIM = 1
-static Registrar<SliceImplForward_cpu<1>> registrarSliceImplForward_1D_cpu_Float32(
-        {DataType::Float32}, Aidge::SliceImpl_cpu_forward_kernel<float, 1>);
-static Registrar<SliceImplForward_cpu<1>> registrarSliceImplForward_1D_cpu_Int32(
-        {DataType::Int32}, Aidge::SliceImpl_cpu_forward_kernel<int, 1>);
-static Registrar<SliceImplForward_cpu<1>> registrarSliceImplForward_1D_cpu_Float64(
-        {DataType::Float64}, Aidge::SliceImpl_cpu_forward_kernel<double, 1>);
-
-// DIM = 2
-static Registrar<SliceImplForward_cpu<2>> registrarSliceImplForward_2D_cpu_Float32(
-        {DataType::Float32}, Aidge::SliceImpl_cpu_forward_kernel<float, 2>);
-static Registrar<SliceImplForward_cpu<2>> registrarSliceImplForward_2D_cpu_Int32(
-        {DataType::Int32}, Aidge::SliceImpl_cpu_forward_kernel<int, 2>);
-static Registrar<SliceImplForward_cpu<2>> registrarSliceImplForward_2D_cpu_Float64(
-        {DataType::Float64}, Aidge::SliceImpl_cpu_forward_kernel<double, 2>);
-
-// DIM = 3
-static Registrar<SliceImplForward_cpu<3>> registrarSliceImplForward_3D_cpu_Float32(
-        {DataType::Float32}, Aidge::SliceImpl_cpu_forward_kernel<float, 3>);
-static Registrar<SliceImplForward_cpu<3>> registrarSliceImplForward_3D_cpu_Int32(
-        {DataType::Int32}, Aidge::SliceImpl_cpu_forward_kernel<int, 3>);
-static Registrar<SliceImplForward_cpu<3>> registrarSliceImplForward_3D_cpu_Float64(
-        {DataType::Float64}, Aidge::SliceImpl_cpu_forward_kernel<double, 3>);
-
-// DIM = 4
-static Registrar<SliceImplForward_cpu<4>> registrarSliceImplForward_4D_cpu_Float32(
-        {DataType::Float32}, Aidge::SliceImpl_cpu_forward_kernel<float, 4>);
-static Registrar<SliceImplForward_cpu<4>> registrarSliceImplForward_4D_cpu_Int32(
-        {DataType::Int32}, Aidge::SliceImpl_cpu_forward_kernel<int, 4>);
-static Registrar<SliceImplForward_cpu<4>> registrarSliceImplForward_4D_cpu_Float64(
-        {DataType::Float64}, Aidge::SliceImpl_cpu_forward_kernel<double, 4>);
+static Registrar<SliceImplForward_cpu> registrarSliceImplForward_cpu_Float32(
+        {DataType::Float32}, Aidge::SliceImpl_cpu_forward_kernel<float>);
+static Registrar<SliceImplForward_cpu> registrarSliceImplForward_cpu_Int32(
+        {DataType::Int32}, Aidge::SliceImpl_cpu_forward_kernel<int>);
+static Registrar<SliceImplForward_cpu> registrarSliceImplForward_cpu_Float64(
+        {DataType::Float64}, Aidge::SliceImpl_cpu_forward_kernel<double>);
 }  // namespace
 }  // namespace Aidge
 
-#endif /* AIDGE_CPU_OPERATOR_LEAKYRELUIMPL_FORWARD_KERNEL_H_ */
+#endif /* AIDGE_CPU_OPERATOR_SLICEIMPL_FORWARD_KERNEL_H_ */
diff --git a/include/aidge/backend/cpu/operator/SoftmaxImpl.hpp b/include/aidge/backend/cpu/operator/SoftmaxImpl.hpp
index 995f57f7..15fb2b5d 100644
--- a/include/aidge/backend/cpu/operator/SoftmaxImpl.hpp
+++ b/include/aidge/backend/cpu/operator/SoftmaxImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/Softmax.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 
diff --git a/include/aidge/backend/cpu/operator/SoftmaxImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/SoftmaxImpl_forward_kernels.hpp
index 297a3a32..a5a168a0 100644
--- a/include/aidge/backend/cpu/operator/SoftmaxImpl_forward_kernels.hpp
+++ b/include/aidge/backend/cpu/operator/SoftmaxImpl_forward_kernels.hpp
@@ -17,6 +17,7 @@
 #include <cmath>
 #include "aidge/data/Data.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/SoftmaxImpl.hpp"
 
diff --git a/include/aidge/backend/cpu/operator/SqrtImpl.hpp b/include/aidge/backend/cpu/operator/SqrtImpl.hpp
index 1880408c..b3723f27 100644
--- a/include/aidge/backend/cpu/operator/SqrtImpl.hpp
+++ b/include/aidge/backend/cpu/operator/SqrtImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/Sqrt.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 
diff --git a/include/aidge/backend/cpu/operator/SubImpl.hpp b/include/aidge/backend/cpu/operator/SubImpl.hpp
index 08ec69e5..2d4c22f0 100644
--- a/include/aidge/backend/cpu/operator/SubImpl.hpp
+++ b/include/aidge/backend/cpu/operator/SubImpl.hpp
@@ -16,6 +16,7 @@
 #include "aidge/operator/Sub.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <memory>
 #include <vector>
 
diff --git a/src/operator/AddImpl.cpp b/src/operator/AddImpl.cpp
index 851aaa5c..91d4533c 100644
--- a/src/operator/AddImpl.cpp
+++ b/src/operator/AddImpl.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include "aidge/data/Data.hpp"
 #include "aidge/data/Tensor.hpp"
 
@@ -74,10 +75,10 @@ void  Aidge::AddImpl_cpu::forward() {
 
     std::vector<const void*> opInputs;
     for (IOIndex_t i = 0; i < mOp.nbInputs(); ++i) {
-        opInputs.push_back(std::static_pointer_cast<Tensor>(mOp.getRawInput(i))->getImpl()->rawPtr());
+        opInputs.push_back(getCPUPtr(mOp.getRawInput(i)));
     }
 
     kernelFunc(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(),
                opInputs,
-               std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+               getCPUPtr(mOp.getRawOutput(0)));
 }
\ No newline at end of file
diff --git a/src/operator/AvgPoolingImpl.cpp b/src/operator/AvgPoolingImpl.cpp
index ad236f00..9e0a77e3 100644
--- a/src/operator/AvgPoolingImpl.cpp
+++ b/src/operator/AvgPoolingImpl.cpp
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include "aidge/operator/AvgPooling.hpp"
 
 #include "aidge/backend/cpu/operator/AvgPoolingImpl.hpp"
@@ -35,6 +36,6 @@ void Aidge::AvgPoolingImpl2D_cpu::forward() {
     // Call kernel
     kernelFunc(dynamic_cast<const AvgPooling_Op<2>&>(mOp).getStaticAttributes(),
                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<4>(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+               getCPUPtr(mOp.getRawInput(0)),
+               getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/BatchNormImpl.cpp b/src/operator/BatchNormImpl.cpp
index 4cfd4b1b..c84f2cb6 100644
--- a/src/operator/BatchNormImpl.cpp
+++ b/src/operator/BatchNormImpl.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include "aidge/operator/BatchNorm.hpp"
 
 #include "aidge/backend/cpu/operator/BatchNormImpl.hpp"
@@ -41,11 +42,11 @@ void Aidge::BatchNormImpl2D_cpu::forward() {
     // Call kernel
     kernelFunc(dynamic_cast<const BatchNorm_Op<2>&>(mOp).getStaticAttributes(),
                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<4>(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(2))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(3))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(4))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr(),
+               getCPUPtr(mOp.getRawInput(0)),
+               getCPUPtr(mOp.getRawInput(1)),
+               getCPUPtr(mOp.getRawInput(2)),
+               getCPUPtr(mOp.getRawInput(3)),
+               getCPUPtr(mOp.getRawInput(4)),
+               getCPUPtr(mOp.getRawOutput(0)),
                true);
 }
diff --git a/src/operator/ConcatImpl.cpp b/src/operator/ConcatImpl.cpp
index d4605448..ceefb903 100644
--- a/src/operator/ConcatImpl.cpp
+++ b/src/operator/ConcatImpl.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include "aidge/data/Data.hpp"
 #include "aidge/data/Tensor.hpp"
 
@@ -75,7 +76,7 @@ void  Aidge::ConcatImpl_cpu::forward() {
     std::vector<const void*> opInputs;
     std::vector<DimSize_t> opInputAxis;
     for (IOIndex_t i = 0; i < mOp.nbInputs(); ++i) {
-        opInputs.push_back(std::static_pointer_cast<Tensor>(mOp.getRawInput(i))->getImpl()->rawPtr());
+        opInputs.push_back(getCPUPtr(mOp.getRawInput(i)));
         opInputAxis.push_back(std::static_pointer_cast<Tensor>(mOp.getRawInput(i))->dims()[dynamic_cast<const Concat_Op&>(mOp).template getAttr<DimSize_t>("Axis")]);
     }
 
@@ -83,7 +84,7 @@ void  Aidge::ConcatImpl_cpu::forward() {
                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims(),
                opInputAxis,
                opInputs,
-               std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+               getCPUPtr(mOp.getRawOutput(0)));
 }
 
 void  Aidge::ConcatImpl_cpu::backward() { printf("Not implemented yet.\n"); }
\ No newline at end of file
diff --git a/src/operator/ConvDepthWiseImpl.cpp b/src/operator/ConvDepthWiseImpl.cpp
index 4a722a5e..1b4262e3 100644
--- a/src/operator/ConvDepthWiseImpl.cpp
+++ b/src/operator/ConvDepthWiseImpl.cpp
@@ -16,6 +16,7 @@
 #include <vector>
 
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include "aidge/operator/ConvDepthWise.hpp"
 
 #include "aidge/backend/cpu/operator/ConvDepthWiseImpl.hpp"
@@ -42,8 +43,8 @@ void Aidge::ConvDepthWiseImpl2D_cpu::forward() {
 
     // Call kernel
     kernelFunc(dynamic_cast<const ConvDepthWise_Op<2>&>(mOp).getStaticAttributes(), std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<4>(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(2))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+               getCPUPtr(mOp.getRawInput(0)),
+               getCPUPtr(mOp.getRawInput(1)),
+               getCPUPtr(mOp.getRawInput(2)),
+               getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/ConvImpl.cpp b/src/operator/ConvImpl.cpp
index 87b54afb..d476f847 100644
--- a/src/operator/ConvImpl.cpp
+++ b/src/operator/ConvImpl.cpp
@@ -16,6 +16,7 @@
 #include <vector>
 
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include "aidge/operator/Conv.hpp"
 
 #include "aidge/backend/cpu/operator/ConvImpl.hpp"
@@ -41,6 +42,6 @@ void Aidge::ConvImpl2D_cpu::forward() {
 
     // Call kernel
     kernelFunc(dynamic_cast<const Conv_Op<2>&>(mOp).getStaticAttributes(), std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<4>(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(), std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(2))->getImpl()->rawPtr(), std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+               getCPUPtr(mOp.getRawInput(0)), getCPUPtr(mOp.getRawInput(1)),
+               getCPUPtr(mOp.getRawInput(2)), getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/DivImpl.cpp b/src/operator/DivImpl.cpp
index 2e913df1..f5cde077 100644
--- a/src/operator/DivImpl.cpp
+++ b/src/operator/DivImpl.cpp
@@ -17,6 +17,7 @@
 
 #include "aidge/operator/Div.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/DivImpl.hpp"
 #include "aidge/backend/cpu/operator/DivImpl_forward_kernels.hpp"
@@ -36,7 +37,7 @@ void Aidge::DivImpl_cpu::forward() {
     // Call kernel
     kernelFunc(std::static_pointer_cast<Tensor>(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)))->size(),
         std::static_pointer_cast<Tensor>(std::static_pointer_cast<Tensor>(mOp.getRawInput(1)))->size(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+        getCPUPtr(mOp.getRawInput(0)),
+        getCPUPtr(mOp.getRawInput(1)),
+        getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/FCImpl.cpp b/src/operator/FCImpl.cpp
index 1e5450d3..14f59f6f 100644
--- a/src/operator/FCImpl.cpp
+++ b/src/operator/FCImpl.cpp
@@ -17,6 +17,7 @@
 
 #include "aidge/operator/FC.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/FCImpl.hpp"
 #include "aidge/backend/cpu/operator/FCImpl_forward_kernels.hpp"
@@ -39,7 +40,7 @@ void Aidge::FCImpl_cpu::forward()
     //     kernelFunc(
     //         mOp.getStaticAttributes(),
     //         std::static_pointer_cast<Tensor>(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<4>(),
-    //         std::static_pointer_cast<Tensor>(mOp.getRawInput(0)->getImpl()->rawPtr(),
+    //         getCPUPtr(mOp.getRawInput(0),
     //         mOp.mInputs[1]->getImpl()->rawPtr(),
     //         mOp.mInputs[2]->getImpl()->rawPtr(),
     //         mOp.getOutput(0)->getImpl()->rawPtr());
@@ -49,8 +50,8 @@ void Aidge::FCImpl_cpu::forward()
         dynamic_cast<const FC_Op&>(mOp).getStaticAttributes(),
         std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims()[0],
         std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->sizeM1(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(2))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+        getCPUPtr(mOp.getRawInput(0)),
+        getCPUPtr(mOp.getRawInput(1)),
+        getCPUPtr(mOp.getRawInput(2)),
+        getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/LeakyReLUImpl.cpp b/src/operator/LeakyReLUImpl.cpp
index 9ea0f240..17912eb1 100644
--- a/src/operator/LeakyReLUImpl.cpp
+++ b/src/operator/LeakyReLUImpl.cpp
@@ -17,6 +17,7 @@
 
 #include "aidge/operator/LeakyReLU.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/LeakyReLUImpl.hpp"
 #include "aidge/backend/cpu/operator/LeakyReLUImpl_forward_kernels.hpp"
@@ -37,6 +38,6 @@ void Aidge::LeakyReLUImpl_cpu::forward() {
     // Call kernel
     kernelFunc(dynamic_cast<const LeakyReLU_Op&>(mOp).getStaticAttributes(),
         std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+        getCPUPtr(mOp.getRawInput(0)),
+        getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/MatMulImpl.cpp b/src/operator/MatMulImpl.cpp
index 0ad9bd6c..1abd75db 100644
--- a/src/operator/MatMulImpl.cpp
+++ b/src/operator/MatMulImpl.cpp
@@ -17,6 +17,7 @@
 
 #include "aidge/operator/MatMul.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/MatMulImpl.hpp"
 #include "aidge/backend/cpu/operator/MatMulImpl_forward_kernels.hpp"
@@ -40,16 +41,16 @@ void Aidge::MatMulImpl_cpu::forward()
     //         mOp.getInput(0))->getImpl()->rawPtr(),
     //         mOp.mInputs[1]->getImpl()->rawPtr(),
     //         mOp.mInputs[2]->getImpl()->rawPtr(),
-    //         std::static_pointer_cast<Tensor>(mOp.getRawOutput(0)->getImpl()->rawPtr());
+    //         getCPUPtr(mOp.getRawOutput(0));
     // }
     // else
     kernelFunc(
         dynamic_cast<const MatMul_Op&>(mOp).getStaticAttributes(),
         std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims()[0],
         std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->sizeM1(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+        getCPUPtr(mOp.getRawInput(0)),
+        getCPUPtr(mOp.getRawInput(1)),
+        getCPUPtr(mOp.getRawOutput(0)));
 
 
 }
diff --git a/src/operator/MaxPoolingImpl.cpp b/src/operator/MaxPoolingImpl.cpp
index 00a27970..e21dab07 100644
--- a/src/operator/MaxPoolingImpl.cpp
+++ b/src/operator/MaxPoolingImpl.cpp
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include "aidge/operator/MaxPooling.hpp"
 
 #include "aidge/backend/cpu/operator/MaxPoolingImpl.hpp"
@@ -35,6 +36,6 @@ void Aidge::MaxPoolingImpl2D_cpu::forward() {
     // Call kernel
     kernelFunc(dynamic_cast<const MaxPooling_Op<2>&>(mOp).getStaticAttributes(),
                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<4>(),
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+               getCPUPtr(mOp.getRawInput(0)),
+               getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/MulImpl.cpp b/src/operator/MulImpl.cpp
index dfd33445..fda49c3f 100644
--- a/src/operator/MulImpl.cpp
+++ b/src/operator/MulImpl.cpp
@@ -17,6 +17,7 @@
 
 #include "aidge/operator/Mul.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/MulImpl.hpp"
 #include "aidge/backend/cpu/operator/MulImpl_forward_kernels.hpp"
@@ -36,7 +37,7 @@ void Aidge::MulImpl_cpu::forward() {
     // Call kernel
     kernelFunc(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(),
         std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->size(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+        getCPUPtr(mOp.getRawInput(0)),
+        getCPUPtr(mOp.getRawInput(1)),
+        getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/PadImpl.cpp b/src/operator/PadImpl.cpp
index a5bf1c52..219bf425 100644
--- a/src/operator/PadImpl.cpp
+++ b/src/operator/PadImpl.cpp
@@ -16,6 +16,7 @@
 #include <vector>
 
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include "aidge/operator/Conv.hpp"
 
 #include "aidge/backend/cpu/operator/PadImpl.hpp"
@@ -42,6 +43,6 @@ void Aidge::PadImpl2D_cpu::forward() {
     // Call kernel
     kernelFunc(dynamic_cast<const Pad_Op<2>&>(mOp).getStaticAttributes(),
                         std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<4>(),
-                        std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-                        std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+                        getCPUPtr(mOp.getRawInput(0)),
+                        getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/PowImpl.cpp b/src/operator/PowImpl.cpp
index 30fafa9b..49664640 100644
--- a/src/operator/PowImpl.cpp
+++ b/src/operator/PowImpl.cpp
@@ -17,6 +17,7 @@
 
 #include "aidge/operator/Pow.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/PowImpl.hpp"
 #include "aidge/backend/cpu/operator/PowImpl_forward_kernels.hpp"
@@ -36,7 +37,7 @@ void Aidge::PowImpl_cpu::forward() {
     // Call kernel
     kernelFunc(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(),
         std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->size(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+        getCPUPtr(mOp.getRawInput(0)),
+        getCPUPtr(mOp.getRawInput(1)),
+        getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/ProducerImpl.cpp b/src/operator/ProducerImpl.cpp
index 827f969e..4c5883a9 100644
--- a/src/operator/ProducerImpl.cpp
+++ b/src/operator/ProducerImpl.cpp
@@ -16,6 +16,7 @@
 #include "aidge/data/Tensor.hpp"
 #include "aidge/operator/Producer.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/ProducerImpl.hpp"
 
diff --git a/src/operator/ReLUImpl.cpp b/src/operator/ReLUImpl.cpp
index 2819bb86..8863be28 100644
--- a/src/operator/ReLUImpl.cpp
+++ b/src/operator/ReLUImpl.cpp
@@ -17,6 +17,7 @@
 
 #include "aidge/operator/ReLU.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/ReLUImpl.hpp"
 #include "aidge/backend/cpu/operator/ReLUImpl_forward_kernels.hpp"
@@ -36,6 +37,6 @@ void Aidge::ReLUImpl_cpu::forward() {
 
     // Call kernel
     kernelFunc(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+        getCPUPtr(mOp.getRawInput(0)),
+        getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/ScalingImpl.cpp b/src/operator/ScalingImpl.cpp
index c2d2b172..6b9aab31 100644
--- a/src/operator/ScalingImpl.cpp
+++ b/src/operator/ScalingImpl.cpp
@@ -18,6 +18,7 @@
 #include "aidge/backend/cpu/operator/ScalingImpl.hpp"
 #include "aidge/backend/cpu/operator/ScalingImpl_forward_kernels.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 #include <vector>
 
 Aidge::NbElts_t Aidge::ScalingImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
@@ -36,6 +37,6 @@ void Aidge::ScalingImpl_cpu::forward() {
     // Call kernel
     kernelFunc(dynamic_cast<const Scaling_Op&>(mOp).getStaticAttributes(),
         std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+        getCPUPtr(mOp.getRawInput(0)),
+        getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/SliceImpl.cpp b/src/operator/SliceImpl.cpp
index 3ae56e1a..b60bbe60 100644
--- a/src/operator/SliceImpl.cpp
+++ b/src/operator/SliceImpl.cpp
@@ -22,231 +22,55 @@
 #include <cassert>
 #include <tuple>
 
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<1>::getNbRequiredData(const Aidge::IOIndex_t /*inputIdx*/) const {
-    assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)) && "requires valid input");
-
-    // Requires the whole tensors
-    return std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<1>()[0];
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<1>::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const { return 0; }
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<1>::getRequiredMemory(const Aidge::IOIndex_t outputIdx,
-                               const std::vector<Aidge::DimSize_t>& inputsSize) const {
-    (void)outputIdx;
-    (void)inputsSize;
-    return std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->template dims<1>()[0];
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<1>::getNbConsumedData(const Aidge::IOIndex_t /*inputIdx*/) const {
-    return mNbConsumedData[0];
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<1>::getNbProducedData(const Aidge::IOIndex_t /*outputIdx*/) const {
-    return mNbProducedData[0];
-}
-
-void Aidge::SliceImpl_cpu<1>::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<1>::forward() {
-    // FIXME: uncomment the following code once memory handling will work
-    assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)) && "missing input #0");
-
-    // Find the correct kernel type
-    auto kernelFunc = Registrar<SliceImplForward_cpu<1>>::create(
-            {std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType()});
-
-    // Call kernel
-    kernelFunc(dynamic_cast<const Slice_Op<1>&>(mOp).getStaticAttributes(),
-                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<1>(),
-                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-                std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr()
-            );
-
-    // each input is consumed by the minimum amount for a forward pass
-    mNbConsumedData[0] += getNbRequiredData(0);
-
-    mNbProducedData[0] += getRequiredMemory(0, {});
-}
-
-void Aidge::SliceImpl_cpu<1>::backward() { printf("Not implemented yet.\n"); }
-
-/////////////////////////////////////////////////////////////////////////
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<2>::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))->template dims<2>();
-    return inputDims[0]*inputDims[1];
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<2>::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const { return 0; }
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<2>::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))->template dims<2>();
-    return outputDims[0]*outputDims[1];
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<2>::getNbConsumedData(const Aidge::IOIndex_t /*inputIdx*/) const {
-    return mNbConsumedData[0];
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<2>::getNbProducedData(const Aidge::IOIndex_t /*outputIdx*/) const {
-    return mNbProducedData[0];
-}
-
-void Aidge::SliceImpl_cpu<2>::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<2>::forward() {
-    // FIXME: uncomment the following code once memory handling will work
-    assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)) && "missing input #0");
-
-    // Find the correct kernel type
-    auto kernelFunc = Registrar<SliceImplForward_cpu<2>>::create(
-            {std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType()});
-
-    // Call kernel
-    kernelFunc(dynamic_cast<const Slice_Op<2>&>(mOp).getStaticAttributes(),
-                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<2>(),
-                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-                std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr()
-            );
-
-    // each input is consumed by the minimum amount for a forward pass
-    mNbConsumedData[0] += getNbRequiredData(0);
-
-    mNbProducedData[0] += getRequiredMemory(0, {});
-}
-
-void Aidge::SliceImpl_cpu<2>::backward() { printf("Not implemented yet.\n"); }
-
-////////////////////////////////////////////////////////////////////////////
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<3>::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))->template dims<3>();
-
-    return std::accumulate(inputDims.begin(), inputDims.end(), static_cast<NbElts_t>(1),
-                            std::multiplies<NbElts_t>());
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<3>::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const { return 0; }
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<3>::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))->template dims<3>();
-    return std::accumulate(outputDims.begin(), outputDims.end(), static_cast<NbElts_t>(1),
-                            std::multiplies<NbElts_t>());
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<3>::getNbConsumedData(const Aidge::IOIndex_t /*inputIdx*/) const {
-    return mNbConsumedData[0];
-}
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<3>::getNbProducedData(const Aidge::IOIndex_t /*outputIdx*/) const {
-    return mNbProducedData[0];
-}
-
-void Aidge::SliceImpl_cpu<3>::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<3>::forward() {
-    // FIXME: uncomment the following code once memory handling will work
-    assert(std::static_pointer_cast<Tensor>(mOp.getRawInput(0)) && "missing input #0");
-
-    // Find the correct kernel type
-    auto kernelFunc = Registrar<SliceImplForward_cpu<3>>::create(
-            {std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType()});
-
-    // Call kernel
-    kernelFunc(dynamic_cast<const Slice_Op<3>&>(mOp).getStaticAttributes(),
-                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<3>(),
-                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-                std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr()
-            );
-
-    // each input is consumed by the minimum amount for a forward pass
-    mNbConsumedData[0] += getNbRequiredData(0);
-
-    mNbProducedData[0] += getRequiredMemory(0, {});
-}
-
-void Aidge::SliceImpl_cpu<3>::backward() { printf("Not implemented yet.\n"); }
-
-//////////////////////////////////////////////////////////////////////////////
-
-Aidge::NbElts_t Aidge::SliceImpl_cpu<4>::getNbRequiredData(const Aidge::IOIndex_t /*inputIdx*/) const {
+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))->template dims<4>();
+    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<4>::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const { return 0; }
+Aidge::NbElts_t Aidge::SliceImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const { return 0; }
 
-Aidge::NbElts_t Aidge::SliceImpl_cpu<4>::getRequiredMemory(const Aidge::IOIndex_t outputIdx,
-                               const std::vector<Aidge::DimSize_t>& inputsSize) const {
+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))->template dims<4>();
+    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<4>::getNbConsumedData(const Aidge::IOIndex_t /*inputIdx*/) const {
+Aidge::NbElts_t Aidge::SliceImpl_cpu::getNbConsumedData(const Aidge::IOIndex_t /*inputIdx*/) const {
     return mNbConsumedData[0];
 }
 
-Aidge::NbElts_t Aidge::SliceImpl_cpu<4>::getNbProducedData(const Aidge::IOIndex_t /*outputIdx*/) const {
+Aidge::NbElts_t Aidge::SliceImpl_cpu::getNbProducedData(const Aidge::IOIndex_t /*outputIdx*/) const {
     return mNbProducedData[0];
 }
 
-void Aidge::SliceImpl_cpu<4>::updateConsummerProducer() {
+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<4>::forward() {
+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");
 
     // Find the correct kernel type
-    auto kernelFunc = Registrar<SliceImplForward_cpu<4>>::create(
+    auto kernelFunc = Registrar<SliceImplForward_cpu>::create(
             {std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dataType()});
 
     // Call kernel
-    kernelFunc(dynamic_cast<const Slice_Op<4>&>(mOp).getStaticAttributes(),
-                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->template dims<4>(),
-                std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-                std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr()
+    kernelFunc(dynamic_cast<const Slice_Op&>(mOp).getStaticAttributes(),
+            std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->dims(),
+            std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
+            std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr()
             );
 
     // each input is consumed by the minimum amount for a forward pass
@@ -255,4 +79,4 @@ void Aidge::SliceImpl_cpu<4>::forward() {
     mNbProducedData[0] += getRequiredMemory(0, {});
 }
 
-void Aidge::SliceImpl_cpu<4>::backward() { printf("Not implemented yet.\n"); }
\ No newline at end of file
+void Aidge::SliceImpl_cpu::backward() { printf("Not implemented yet.\n"); }
\ No newline at end of file
diff --git a/src/operator/SoftmaxImpl.cpp b/src/operator/SoftmaxImpl.cpp
index 1ce9564a..428d32fc 100644
--- a/src/operator/SoftmaxImpl.cpp
+++ b/src/operator/SoftmaxImpl.cpp
@@ -17,6 +17,7 @@
 
 #include "aidge/operator/Softmax.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/SoftmaxImpl.hpp"
 #include "aidge/backend/cpu/operator/SoftmaxImpl_forward_kernels.hpp"
@@ -42,6 +43,6 @@ void Aidge::SoftmaxImpl_cpu::forward() {
     kernelFunc(batchSize,
                channelSize,
                featureSize,
-               std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-               std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+               getCPUPtr(mOp.getRawInput(0)),
+               getCPUPtr(mOp.getRawOutput(0)));
 }
diff --git a/src/operator/SqrtImpl.cpp b/src/operator/SqrtImpl.cpp
index b9a01ff9..2766e8ae 100644
--- a/src/operator/SqrtImpl.cpp
+++ b/src/operator/SqrtImpl.cpp
@@ -17,6 +17,7 @@
 
 #include "aidge/operator/Sqrt.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/SqrtImpl.hpp"
 #include "aidge/backend/cpu/operator/SqrtImpl_forward_kernels.hpp"
@@ -36,6 +37,6 @@ void Aidge::SqrtImpl_cpu::forward() {
 
     // Call kernel
     kernelFunc(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+        getCPUPtr(mOp.getRawInput(0)),
+        getCPUPtr(mOp.getRawOutput(0)));
 }
\ No newline at end of file
diff --git a/src/operator/SubImpl.cpp b/src/operator/SubImpl.cpp
index 7d33d935..038a1154 100644
--- a/src/operator/SubImpl.cpp
+++ b/src/operator/SubImpl.cpp
@@ -17,6 +17,7 @@
 
 #include "aidge/operator/Sub.hpp"
 #include "aidge/utils/Types.h"
+#include "aidge/backend/cpu/data/GetCPUPtr.h"
 
 #include "aidge/backend/cpu/operator/SubImpl.hpp"
 #include "aidge/backend/cpu/operator/SubImpl_forward_kernels.hpp"
@@ -37,7 +38,7 @@ void Aidge::SubImpl_cpu::forward() {
     // Call kernel
     kernelFunc(std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->size(),
         std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->size(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(0))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawInput(1))->getImpl()->rawPtr(),
-        std::static_pointer_cast<Tensor>(mOp.getRawOutput(0))->getImpl()->rawPtr());
+        getCPUPtr(mOp.getRawInput(0)),
+        getCPUPtr(mOp.getRawInput(1)),
+        getCPUPtr(mOp.getRawOutput(0)));
 }
-- 
GitLab