diff --git a/include/aidge/backend/cpu.hpp b/include/aidge/backend/cpu.hpp
index 1f45d700f6fc9f1d69682cb2de601979049c0af6..e3fa457c5cf557328a7fbf2049b9e577c44391f9 100644
--- a/include/aidge/backend/cpu.hpp
+++ b/include/aidge/backend/cpu.hpp
@@ -13,6 +13,7 @@
 #define AIDGE_CPU_IMPORTS_H_
 
 #include "aidge/backend/cpu/data/TensorImpl.hpp"
+
 #include "aidge/backend/cpu/operator/AddImpl.hpp"
 #include "aidge/backend/cpu/operator/AvgPoolingImpl.hpp"
 #include "aidge/backend/cpu/operator/MaxPoolingImpl.hpp"
@@ -24,7 +25,8 @@
 #include "aidge/backend/cpu/operator/MatMulImpl.hpp"
 #include "aidge/backend/cpu/operator/ProducerImpl.hpp"
 #include "aidge/backend/cpu/operator/ReLUImpl.hpp"
-#include "aidge/backend/cpu/operator/SoftmaxImpl.hpp"
 #include "aidge/backend/cpu/operator/ScalingImpl.hpp"
+#include "aidge/backend/cpu/operator/SliceImpl.hpp"
+#include "aidge/backend/cpu/operator/SoftmaxImpl.hpp"
 
 #endif /* AIDGE_CPU_IMPORTS_H_ */
\ No newline at end of file
diff --git a/include/aidge/backend/cpu/operator/SliceImpl.hpp b/include/aidge/backend/cpu/operator/SliceImpl.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c50049206f9fd9b70d6d724aa6d651998d1f1de1
--- /dev/null
+++ b/include/aidge/backend/cpu/operator/SliceImpl.hpp
@@ -0,0 +1,112 @@
+/********************************************************************************
+ * 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_OPERATOR_SLICEIMPL_H_
+#define AIDGE_CPU_OPERATOR_SLICEIMPL_H_
+
+#include "aidge/backend/OperatorImpl.hpp"
+#include "aidge/operator/Slice.hpp"
+#include "aidge/utils/Registrar.hpp"
+#include "aidge/utils/Types.h"
+#include <memory>
+#include <vector>
+
+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(std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, const void*, void*)> {
+};
+template <DimIdx_t DIM>
+class SliceImplBackward_cpu
+    : public Registrable<SliceImplBackward_cpu<DIM>, std::tuple<DataType>, void(std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, const void*, void*)> {
+};
+
+template <DimIdx_t DIM>
+class SliceImpl_cpu : public OperatorImpl {
+   private:
+    const Slice_Op<DIM>& mOp;
+    std::array<NbElts_t, 1> mNbConsumedData;
+    std::array<NbElts_t, 1> mNbProducedData;
+
+   public:
+    SliceImpl_cpu(const Slice_Op<DIM>& op) : mOp(op), mNbConsumedData({0}), mNbProducedData({0}) {}
+
+    static std::unique_ptr<SliceImpl_cpu> create(const Slice_Op<DIM>& op) {
+        return std::make_unique<SliceImpl_cpu>(op);
+    }
+
+   public:
+    NbElts_t getNbRequiredData(const IOIndex_t /*inputIdx*/) const override final {
+        assert(mOp.getInput(0) && "requires valid input");
+
+        // Requires the whole tensors
+        const auto& inputDims = mOp.getInput(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 = mOp.getOutput(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 {
+        mNbConsumedData[0]+= getNbRequiredData(0); // each input is consumed by the minimum amount for a forward pass
+
+        mNbProducedData[0]+= getRequiredMemory(0, {});
+    }
+
+    void forward() {
+        // FIXME: uncomment the following code once memory handling will work
+        assert(mOp.getInput(0) && "missing input #0");
+
+        // Find the correct kernel type
+        auto kernelFunc = Registrar<SliceImplForward_cpu<DIM>>::create({
+            mOp.getInput(0)->dataType(),
+            mOp.getOutput(0)->dataType()});
+
+        // Call kernel
+        kernelFunc(mOp->getInput(0)->dims(),
+            mOp->template getAttr<SliceAttr::SliceDims>(),
+            mOp.getInput(0)->getImpl()->rawPtr(),
+            mOp.getOutput(0)->getImpl()->rawPtr());
+
+        mNbConsumedData[0]+= getNbRequiredData(0); // each input is consumed by the minimum amount for a forward pass
+
+        mNbProducedData[0]+= getRequiredMemory(0, {});
+    }
+
+    void backward() {
+        printf("Not implemented yet.\n");
+    }
+};
+
+namespace {
+template <DimIdx_t DIM>
+static Registrar<Slice_Op<DIM>> registrarSliceImpl_cpu("cpu", Aidge::SliceImpl_cpu<DIM>::create);
+}
+}  // namespace Aidge
+
+#endif /* AIDGE_CPU_OPERATOR_LEAKYRELUIMPL_H_ */
diff --git a/include/aidge/backend/cpu/operator/SliceImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/SliceImpl_forward_kernels.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..18e599880a91fd881525977c1d37591944565c8c
--- /dev/null
+++ b/include/aidge/backend/cpu/operator/SliceImpl_forward_kernels.hpp
@@ -0,0 +1,71 @@
+/********************************************************************************
+ * 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_OPERATOR_SLICEIMPL_FORWARD_KERNEL_H_
+#define AIDGE_CPU_OPERATOR_SLICEIMPL_FORWARD_KERNEL_H_
+
+#include "aidge/utils/Registrar.hpp"
+#include <array>
+#include <cstddef>
+
+#include "aidge/backend/cpu/operator/SliceImpl.hpp"
+
+namespace Aidge {
+template <class I, class O, std::size_t DIM>
+void SliceImpl_cpu_forward_kernel(const std::array<std::size_t, DIM> inputDims,
+                                     const std::array<std::size_t, DIM> slicedDims,
+                                     const void* input_,
+                                     void* output_) {
+
+    const I* input = static_cast<const I*>(input_);
+    O* output = static_cast<O*>(output_);
+
+	// 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) {
+        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::size_t j = 0;
+	std::size_t i = 0;
+	for (std::size_t = 0; j < prodSlicedDims[0]; ++j) {
+		output[j] = input[i++];
+		for (std::size_t idx = DIM - 1; idx > 0; --idx) {
+			i += j % prodSlicedDims[idx] == 0 ? substractedDims[idx]*prodInputDims[idx+1] : 0;
+		}
+	}
+}
+
+namespace {
+template <std::size_t DIM>
+static Registrar<SliceImplForward_cpu<DIM>> registrarSliceImplForward_cpu_Float32(
+        {DataType::Float32, DataType::Float32}, Aidge::SliceImpl_cpu_forward_kernel<float, float, DIM>);
+template <std::size_t DIM>
+static Registrar<SliceImplForward_cpu<DIM>> registrarSliceImplForward_cpu_Int32(
+        {DataType::Int32, DataType::Int32}, Aidge::SliceImpl_cpu_forward_kernel<int, int, DIM>);
+template <std::size_t DIM>
+static Registrar<SliceImplForward_cpu<DIM>> registrarSliceImplForward_cpu_Float64(
+        {DataType::Float64, DataType::Float64}, Aidge::SliceImpl_cpu_forward_kernel<double, double, DIM>);
+}  // namespace
+}  // namespace Aidge
+
+#endif /* AIDGE_CPU_OPERATOR_LEAKYRELUIMPL_FORWARD_KERNEL_H_ */
diff --git a/unit_tests/operator/Test_SliceImpl.cpp b/unit_tests/operator/Test_SliceImpl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..486f6edec006d3505cabe2d66b3820862cde3b69
--- /dev/null
+++ b/unit_tests/operator/Test_SliceImpl.cpp
@@ -0,0 +1,150 @@
+/********************************************************************************
+ * 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
+ *
+ ********************************************************************************/
+
+#include <catch2/catch_test_macros.hpp>
+
+#include "aidge/data/Tensor.hpp"
+#include "aidge/operator/Slice.hpp"
+
+#include "aidge/backend/cpu.hpp"
+
+using namespace Aidge;
+
+TEST_CASE("[cpu/operator] Slice(forward)") {
+    SECTION("1D Tensor") {
+        std::shared_ptr<Tensor> input0 = std::make_shared<Tensor>(Array1D<int,10> {
+            {0, 1, 2,-3, 4,-5,-6, 7, 8, 9}
+        });
+        std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array1D<int,4> {
+            {0, 1, 2,-3}
+        });
+
+        std::shared_ptr<Node> mySlice = Slice(0, {4});
+        mySlice->getOperator()->setDatatype(DataType::Int32);
+        mySlice->getOperator()->setBackend("cpu");
+        mySlice->getOperator()->associateInput(0,input0);
+        mySlice->getOperator()->computeOutputDims();
+        mySlice->forward();
+        REQUIRE(mySlice->getOperator()->output(0) == *expectedOutput);
+    }
+
+    SECTION("2D Tensor") {
+        std::shared_ptr<Tensor> input0 = std::make_shared<Tensor>(Array2D<int,2,10> {
+            {
+                { 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
+                {-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
+            }
+        });
+        std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array2D<int,2,3> {
+            {
+                {-5,-6, 7},
+                {-5,-6, 7}
+            }
+        });
+
+        std::shared_ptr<Node> mySlice = Slice(5, {2,3});
+        mySlice->getOperator()->setDatatype(DataType::Int32);
+        mySlice->getOperator()->setBackend("cpu");
+        mySlice->getOperator()->associateInput(0,input0);
+        mySlice->getOperator()->computeOutputDims();
+        mySlice->forward();
+        REQUIRE(*mySlice->getOperator()->getOutput(0) == *expectedOutput);
+    }
+
+    SECTION("3D Tensor") {
+        std::shared_ptr<Tensor> input0 = std::make_shared<Tensor>(Array3D<int,2,2,10> {
+            {
+                {
+                    { 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
+                    {-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
+                },
+                {
+                    { 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
+                    {-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
+                }
+            }
+        });
+        std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array3D<int,1,1,3> {
+            {
+                {
+                    { 4,-5,-6}
+                }
+            }
+        });
+
+        std::shared_ptr<Node> mySlice = Slice(14, {1,1,3});
+        mySlice->getOperator()->setDatatype(DataType::Int32);
+        mySlice->getOperator()->setBackend("cpu");
+        mySlice->getOperator()->associateInput(0,input0);
+        mySlice->getOperator()->computeOutputDims();
+        mySlice->forward();
+        REQUIRE(mySlice->getOperator()->output(0) == *expectedOutput);
+    }
+
+    SECTION("4D Tensor") {
+        std::shared_ptr<Tensor> input0 = std::make_shared<Tensor>(Array4D<int,2,2,2,10> {
+            {
+                {
+                    {
+                        { 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
+                        {-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
+                    },
+                    {
+                        { 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
+                        {-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
+                    }
+                },
+                {
+                    {
+                        { 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
+                        {-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
+                    },
+                    {
+                        { 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
+                        {-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
+                    }
+                }
+            }
+        });
+        std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array4D<int,2,2,2,10> {
+            {
+                {
+                    {
+                        { 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
+                        {-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
+                    },
+                    {
+                        { 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
+                        {-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
+                    }
+                },
+                {
+                    {
+                        { 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
+                        {-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
+                    },
+                    {
+                        { 0, 1, 2,-3, 4,-5,-6, 7, 8, 9},
+                        {-5, 4, 2,-3, 4,-5,-6, 7,-1,10}
+                    }
+                }
+            }
+        });
+
+        std::shared_ptr<Node> mySlice = Slice(0, {2,2,2,10});
+        mySlice->getOperator()->setDatatype(DataType::Int32);
+        mySlice->getOperator()->setBackend("cpu");
+        mySlice->getOperator()->associateInput(0,input0);
+        mySlice->getOperator()->computeOutputDims();
+        mySlice->forward();
+        REQUIRE(mySlice->getOperator()->output(0) == *expectedOutput);
+    }
+}
\ No newline at end of file