diff --git a/include/aidge/operator/Conv.hpp b/include/aidge/operator/Conv.hpp
index 5cce541087124496437a9c87895e7cf3b0ee838f..7fa99b08461593d0149e7cb472cb607025a3b6fd 100644
--- a/include/aidge/operator/Conv.hpp
+++ b/include/aidge/operator/Conv.hpp
@@ -157,11 +157,11 @@ std::vector<std::pair<std::vector<Aidge::DimSize_t>, std::vector<DimSize_t>>> co
                 weightDims.push_back(this->template getAttr<ConvAttr::KernelDims>()[i]);
             }
             std::vector<DimSize_t> weightIdxDims = std::vector<DimSize_t>(DIM+2, 0);
-            weightIdxDims[0] = outputIdxDims[1];
+            weightIdxDims[0] = firstEltDims[1];
 
             // Bias
             const std::vector<DimSize_t> biasDims{outputDims[1]}; // the number of output channel
-            const std::vector<DimSize_t> biasIdxDims{outputIdxDims[1]};
+            const std::vector<DimSize_t> biasIdxDims{firstEltDims[1]};
 
             // Result
             std::vector<std::pair<std::vector<Aidge::DimSize_t>, std::vector<DimSize_t>>> res;
diff --git a/include/aidge/operator/ConvDepthWise.hpp b/include/aidge/operator/ConvDepthWise.hpp
index 15110a1c75a1d4a6fdc03717bcde6b301771c9b9..cc687622916b0fd27fc2cb777bd50cbfbb7d3949 100644
--- a/include/aidge/operator/ConvDepthWise.hpp
+++ b/include/aidge/operator/ConvDepthWise.hpp
@@ -151,11 +151,11 @@ public:
                 weightDims.push_back(this->template getAttr<ConvDepthWiseAttr::KernelDims>()[i]);
             }
             std::vector<DimSize_t> weightIdxDims = std::vector<DimSize_t>(DIM+2, 0);
-            weightIdxDims[0] = outputIdxDims[1];
+            weightIdxDims[0] = firstEltDims[1];
 
             // Bias
             const std::vector<DimSize_t> biasDims{outputDims[1]}; // the number of output channel
-            const std::vector<DimSize_t> biasIdxDims{outputIdxDims[1]};
+            const std::vector<DimSize_t> biasIdxDims{firstEltDims[1]};
 
             // Result
             std::vector<std::pair<std::vector<Aidge::DimSize_t>, std::vector<DimSize_t>>> res;
diff --git a/include/aidge/operator/Slice.hpp b/include/aidge/operator/Slice.hpp
index 26abaf291aad352ce8cc13fd17e148f358b980eb..9b93b9448fb04be616497b6961c4692a5a846303 100644
--- a/include/aidge/operator/Slice.hpp
+++ b/include/aidge/operator/Slice.hpp
@@ -24,25 +24,26 @@
 #include "aidge/utils/Types.h"
 
 namespace Aidge {
-enum class SliceAttr { Beginning, SliceDims };
+enum class SliceAttr { Starts, Ends, Axes };
 
 class Slice_Op
     : public OperatorTensor,
       public Registrable<Slice_Op, std::string, std::unique_ptr<OperatorImpl>(const Slice_Op &)>,
-      public StaticAttributes<SliceAttr, std::vector<std::int32_t>, std::vector<std::int32_t>, std::vector<std::int32_t>> {
+      public StaticAttributes<SliceAttr, std::vector<std::size_t>, std::vector<std::size_t>, std::vector<std::size_t>> {
 public:
     static const std::string Type;
 
     Slice_Op() = delete;
 
-    using Attributes_ = StaticAttributes<SliceAttr, std::vector<std::int32_t>, std::vector<std::int32_t>, std::vector<std::int32_t>>;
+    using Attributes_ = StaticAttributes<SliceAttr, std::vector<std::size_t>, std::vector<std::size_t>, std::vector<std::size_t>>;
     template <SliceAttr e>
     using attr = typename Attributes_::template attr<e>;
 
-    Slice_Op(const std::vector<std::int32_t>& starts, const std::vector<std::int32_t>&  ends, const std::vector<std::int32_t>& axes)
+    Slice_Op(const std::vector<std::size_t>& starts, const std::vector<std::size_t>&  ends, const std::vector<std::size_t>& axes)
         : OperatorTensor(Type, 1, 0, 1),
-          Attributes_(attr<SliceAttr::Beginning>(beginningPos),
-                      attr<SliceAttr::SliceDims>(sliceDims))
+          Attributes_(attr<SliceAttr::Starts>(starts),
+                      attr<SliceAttr::Ends>(ends),
+                      attr<SliceAttr::Axes>(axes))
     {}
 
     /**
@@ -65,30 +66,7 @@ public:
      */
     std::shared_ptr<Operator> clone() const override { return std::make_shared<Slice_Op>(*this); }
 
-    void computeOutputDims() override final {
-        if (!getInput(0) || (getInput(0)->empty())) {
-            AIDGE_THROW_OR_ABORT(std::runtime_error, "Every input should be associated with a Tensor");
-        }
-        std::vector<DimSize_t> outputDims = std::vector<DimSize_t>(getInput(0)->nbDims());
-        const std::vector<DimSize_t> inputDims = getInput(0)->dims();
-
-        // Check that the sliced Tensor is actually part of the input Tensor
-        // For a 5*5 tensor ('x') and a 3*3 slice kernel ('o'):
-        // xxxxx               xxxxx
-        // xxxxx               xxxxx
-        // xxooo  --> ok       xxxoo --> out of bound
-        // xxooo               xxxoo
-        // xxooo               xxxoo
-        std::vector<std::size_t> beginningCoords = mInputs[0]->getCoord(this->template getAttr<SliceAttr::Beginning>());
-        for (std::size_t i = 0; i < getInput(0)->nbDims(); ++i) {
-            if (beginningCoords[i] + this->template getAttr<SliceAttr::SliceDims>()[i] > inputDims[i]) {
-                AIDGE_THROW_OR_ABORT(std::runtime_error, "ROI of Slice operator out of bounds");
-            } else {
-                outputDims[i] = this->template getAttr<SliceAttr::SliceDims>()[i];
-            }
-        }
-        mOutputs[0]->resize(outputDims);
-    }
+    void computeOutputDims() override final;
 
     void setBackend(const std::string &name) override {
         mImpl = Registrar<Slice_Op>::create(name)(*this);
@@ -107,18 +85,18 @@ public:
 };
 
 
-inline std::shared_ptr<Node> Slice(const std::vector<std::int32_t> starts,
-                                   const std::vector<std::int32_t> ends,
-                                   const std::vector<std::int32_t> axes,
+inline std::shared_ptr<Node> Slice(const std::vector<std::size_t> starts,
+                                   const std::vector<std::size_t> ends,
+                                   const std::vector<std::size_t> axes,
                                    const std::string &name = "") {
     // FIXME: properly handle default w&b initialization in every cases
-    return std::make_shared<Node>(std::make_shared<Slice_Op>(beginningPos, sliceDims), name);
+    return std::make_shared<Node>(std::make_shared<Slice_Op>(starts, ends, axes), name);
 }
 }  // namespace Aidge
 
 namespace {
 template <>
-const char *const EnumStrings<Aidge::SliceAttr>::data[] = { "Beginning", "SliceDims" };
+const char *const EnumStrings<Aidge::SliceAttr>::data[] = { "Starts", "Ends", "Axes" };
 }
 
 #endif /* AIDGE_CORE_OPERATOR_RELU_H_ */
diff --git a/src/operator/Slice.cpp b/src/operator/Slice.cpp
index 9ac6bd2c08fa8f77d995e852de6a5990dc73bd94..b9ba4fe36ff7b3e6c5a5d28da87eec691e933a12 100644
--- a/src/operator/Slice.cpp
+++ b/src/operator/Slice.cpp
@@ -8,12 +8,17 @@
  * SPDX-License-Identifier: EPL-2.0
  *
  ********************************************************************************/
+#include "aidge/operator/Slice.hpp"
 
+#include <cassert>
+#include <cstddef>
 #include <string>
+#include <utility>
+#include <vector>
 
-#include "aidge/operator/Slice.hpp"
-#include "aidge/utils/Types.h"
+#include "aidge/backend/OperatorImpl.hpp"
 #include "aidge/utils/ErrorHandling.hpp"
+#include "aidge/utils/Types.h"
 
 const std::string Aidge::Slice_Op::Type = "Slice";
 
@@ -25,14 +30,20 @@ void Aidge::Slice_Op::computeOutputDims() {
 
     DimSize_t nbAxes = this->template getAttr<SliceAttr::Axes>().size();
     std::vector<DimSize_t> outDims = getInput(0)->dims();
-    for(std::size_t i=0; i<nbAxes;++i)
-    {
+    for (std::size_t i = 0; i < nbAxes; ++i) {
         // For each slice operation get the params and cast them to size_t
         std::int64_t axis_ = this->template getAttr<SliceAttr::Axes>()[i];
         std::int64_t start_ = this->template getAttr<SliceAttr::Starts>()[i];
         std::int64_t end_ = this->template getAttr<SliceAttr::Ends>()[i];
-        std::size_t axis = axis_>=0?axis_:axis_+getInput(0)->nbDims();
-        std::size_t start = start_>=0?start_:start_+getInput(0)->dims()[axis];
-        std::size_t end = end_>=0?end_:end_+getInput(0)->dims()[axis];
+        std::size_t axis = axis_ >= 0 ? axis_ : axis_ + getInput(0)->nbDims();
+        std::size_t start = start_ >= 0 ? start_ : start_ + getInput(0)->dims()[axis];
+        std::size_t end = end_ >= 0 ? end_ : end_ + getInput(0)->dims()[axis];
+
+        std::size_t sliceLength = end - start + 1;
+        // Check if slice length is valid
+        if (sliceLength > getInput(0)->dims()[axis])
+            AIDGE_THROW_OR_ABORT(std::runtime_error, "ROI of Slice operator out of bounds");
+        outDims[axis] = sliceLength;
     }
+    mOutputs[0]->resize(outDims);
 }
diff --git a/src/recipies/HorizontalTiling.cpp b/src/recipies/HorizontalTiling.cpp
index f1d8d3bdd2acfddc26f664913b2fa6c3217b8919..48d8cfc0b9011e88dea0c1d605cb8c72bfe18d96 100644
--- a/src/recipies/HorizontalTiling.cpp
+++ b/src/recipies/HorizontalTiling.cpp
@@ -11,6 +11,7 @@
 
 #include <set>
 #include <memory>
+#include <numeric>   // std::iota
 #include <vector>
 #include <utility>
 
@@ -75,13 +76,19 @@ std::set<std::shared_ptr<Aidge::Node>> Aidge::getConvHorizontalTiling(const std:
     }
 
     for (IOIndex_t i = 0; currentFirstDims[axis] < outTensor->dims()[axis]; currentFirstDims[axis] += outputDims[axis], ++i) {
-        const auto inputDims = op->computeReceptiveField(outTensor->getIdx(currentFirstDims), outputDims, 0);
+        const auto inputDims = op->computeReceptiveField(currentFirstDims, outputDims, 0);
         auto newNode = node -> clone(); // no input associated to clones
         newNode -> setName(node->name() + "_" + std::to_string(currentFirstDims[axis]));
         clonedInputs[1] -> addChild(newNode, 0, 1);
         clonedInputs[2] -> addChild(newNode, 0, 2);
         // Slice for input and each parameter
-        auto slice = Slice(inputDims[0].first, inputDims[0].second, "Slice_" + std::to_string(currentFirstDims[axis]));
+        auto inputDimsEnd = inputDims[0].first;
+        for (std::size_t dim = 0; dim < inputDimsEnd.size(); ++dim) {
+            inputDimsEnd[dim] += inputDims[0].second[dim];
+        }
+        std::vector<std::size_t> usedDims(inputDimsEnd.size());
+        std::iota(usedDims.begin(), usedDims.end(), static_cast<std::size_t>(0));
+        auto slice = Slice(inputDims[0].first, inputDimsEnd, usedDims, "Slice_" + std::to_string(currentFirstDims[axis]));
         slice -> addChild(newNode, 0, 0);
         newNode -> addChild(concat, 0, i);
 
diff --git a/unit_tests/operator/Test_ConvDepthWise_Op.cpp b/unit_tests/operator/Test_ConvDepthWise_Op.cpp
index 14d4dc537f527b32414151ee7f93e601f5a4bd8a..6008e3bfac346725935d5d8ffe87f392c49a3409 100644
--- a/unit_tests/operator/Test_ConvDepthWise_Op.cpp
+++ b/unit_tests/operator/Test_ConvDepthWise_Op.cpp
@@ -45,20 +45,20 @@ TEST_CASE("[core/operator] ConvDepthWise_Op(computeReceptiveField)", "[Operator]
     auto op4 = std::dynamic_pointer_cast<OperatorTensor>(cdw4 -> getOperator());
 
     SECTION("Check individual receptive fields") {
-        auto res1 = op1->computeReceptiveField(0, {16,3,10,10});
-        auto res2 = op2->computeReceptiveField(op2->getOutput(0)->getIdx({3,1,100,28}), {4,2,30,40});
-        auto res3 = op3->computeReceptiveField(0, {1,1,109,109});
-        auto res4 = op4->computeReceptiveField(op4->getInput(0)->getIdx({5,0,108,108}), {10,1,1,1});
+        auto res1 = op1->computeReceptiveField({0,0,0,0}, {16,3,10,10});
+        auto res2 = op2->computeReceptiveField({3,1,100,28}, {4,2,30,40});
+        auto res3 = op3->computeReceptiveField({0,0,0,0}, {1,1,109,109});
+        auto res4 = op4->computeReceptiveField({5,0,108,108}, {10,1,1,1});
 
-        REQUIRE(((res1[0].first == 0) && (res1[0].second == std::vector<DimSize_t>({16, 3, 14, 14}))));
-        REQUIRE(((res2[0].first == op2->getInput(0)->getIdx({3,1,100,28})) && (res2[0].second == std::vector<DimSize_t>({4, 2, 32, 42}))));
-        REQUIRE(((res3[0].first == 0) && (res3[0].second == std::vector<DimSize_t>({1, 1, 218, 218}))));
-        REQUIRE(((res4[0].first == op4->getInput(0)->getIdx({5, 0, 108, 108})) && (res4[0].second == std::vector<DimSize_t>({10, 1, 1, 1}))));
+        REQUIRE(((res1[0].first == std::vector<DimSize_t>({0,0,0,0})) && (res1[0].second == std::vector<DimSize_t>({16, 3, 14, 14}))));
+        REQUIRE(((res2[0].first == std::vector<DimSize_t>({3,1,100,28})) && (res2[0].second == std::vector<DimSize_t>({4, 2, 32, 42}))));
+        REQUIRE(((res3[0].first == std::vector<DimSize_t>({0,0,0,0})) && (res3[0].second == std::vector<DimSize_t>({1, 1, 218, 218}))));
+        REQUIRE(((res4[0].first == std::vector<DimSize_t>({5,0,108,108})) && (res4[0].second == std::vector<DimSize_t>({10, 1, 1, 1}))));
     }
 
     SECTION("Check receptive field propagation") {
         // input:  first-{5, 0, 50, 50}  dims-{1, 1, 1, 1}
-        auto res4 = op4->computeReceptiveField(op4->getInput(0)->getIdx({5,0,50,50}), {1,1,1,1});
+        auto res4 = op4->computeReceptiveField({5,0,50,50}, {1,1,1,1});
         // cdw4 RF:  first-{5, 0, 50, 50}  dims-{1, 1, 1, 1}
         auto res3 = op3->computeReceptiveField(res4[0].first, res4[0].second);
         // cdw3 RF:  first-{5, 0, 100, 100} dims-{1, 1, 2, 2}
@@ -67,7 +67,7 @@ TEST_CASE("[core/operator] ConvDepthWise_Op(computeReceptiveField)", "[Operator]
         auto res1 = op1->computeReceptiveField(res2[0].first, res2[0].second);
         // cdw1 RF:  first-{5, 0, 100, 100} dims-{1, 1, 8, 8}
 
-        REQUIRE(((res1[0].first == op1->getInput(0)->getIdx({5, 0, 100, 100})) && (res1[0].second == std::vector<DimSize_t>({1, 1, 8, 8}))));
+        REQUIRE(((res1[0].first == std::vector<DimSize_t>({5, 0, 100, 100})) && (res1[0].second == std::vector<DimSize_t>({1, 1, 8, 8}))));
     }
 }
 }  // namespace Aidge
\ No newline at end of file
diff --git a/unit_tests/operator/Test_Conv_Op.cpp b/unit_tests/operator/Test_Conv_Op.cpp
index 859d1d964180673e1d35fdede6fdfd78f75cfdeb..bc24fc8081d78dedf853450ff648b6d91b47c1dc 100644
--- a/unit_tests/operator/Test_Conv_Op.cpp
+++ b/unit_tests/operator/Test_Conv_Op.cpp
@@ -50,12 +50,12 @@ TEST_CASE("[core/operator] Conv_Op(computeReceptiveField)", "[Operator][computeR
         auto res3 = op3 -> computeReceptiveField({0,0,0,0}, {1,1,109,109});
         auto res4 = op4 -> computeReceptiveField({5,0,108,108}, {10,10,1,1});
 
-        REQUIRE(((res1[0].first == 0) && (res1[0].second == std::vector<DimSize_t>({16, 3, 14, 14}))));
-        REQUIRE(((res1[1].first == 0) && (res1[1].second == std::vector<DimSize_t>({32, 3, 5, 5}))));
-        REQUIRE(((res1[2].first == 0) && (res1[2].second == std::vector<DimSize_t>({32}))));
-        REQUIRE(((res2[0].first == op2->getInput(0)->getIdx({3,0,100,28})) && (res2[0].second == std::vector<DimSize_t>({4, 32, 32, 42}))));
-        REQUIRE(((res3[0].first == 0) && (res3[0].second == std::vector<DimSize_t>({1, 64, 218, 218}))));
-        REQUIRE(((res4[0].first == op4->getInput(0)->getIdx({5, 0, 108, 108})) && (res4[0].second == std::vector<DimSize_t>({10, 10, 1, 1}))));
+        REQUIRE(((res1[0].first == std::vector<DimSize_t>({0,0,0,0})) && (res1[0].second == std::vector<DimSize_t>({16, 3, 14, 14}))));
+        REQUIRE(((res1[1].first == std::vector<DimSize_t>({0,0,0,0})) && (res1[1].second == std::vector<DimSize_t>({32, 3, 5, 5}))));
+        REQUIRE(((res1[2].first == std::vector<DimSize_t>({0})) && (res1[2].second == std::vector<DimSize_t>({32}))));
+        REQUIRE(((res2[0].first == std::vector<DimSize_t>({3,0,100,28})) && (res2[0].second == std::vector<DimSize_t>({4, 32, 32, 42}))));
+        REQUIRE(((res3[0].first == std::vector<DimSize_t>({0,0,0,0})) && (res3[0].second == std::vector<DimSize_t>({1, 64, 218, 218}))));
+        REQUIRE(((res4[0].first == std::vector<DimSize_t>({5, 0, 108, 108})) && (res4[0].second == std::vector<DimSize_t>({10, 10, 1, 1}))));
     }
 
     SECTION("Check receptive field propagation") {
@@ -69,7 +69,7 @@ TEST_CASE("[core/operator] Conv_Op(computeReceptiveField)", "[Operator][computeR
         auto res1 = op1->computeReceptiveField(res2[0].first, res2[0].second);
         // conv1 RF:  first-{5, 0, 100, 100} dims-{1, 3, 8, 8}
 
-        REQUIRE(((res1[0].first == op1->getInput(0)->getIdx({5, 0, 100, 100})) && (res1[0].second == std::vector<DimSize_t>({1, 3, 8, 8}))));
+        REQUIRE(((res1[0].first == std::vector<DimSize_t>({5, 0, 100, 100})) && (res1[0].second == std::vector<DimSize_t>({1, 3, 8, 8}))));
 
 
         // std::cout << "conv1: {";