diff --git a/src/operator/Gather.cpp b/src/operator/Gather.cpp
index 9bcf3d6b4efe9ae588b76d2defee16df8b17d190..8b931667adf0a21a025aaf6ffb023a32c89b4970 100644
--- a/src/operator/Gather.cpp
+++ b/src/operator/Gather.cpp
@@ -22,11 +22,9 @@
 
 void Aidge::Gather_OpImpl::forward() {
     const Gather_Op& op = dynamic_cast<const Gather_Op&>(mOp);
-    const auto axis = op.template getAttr<std::int64_t>("Axis");
+    const auto axis = op.template getAttr<std::int8_t>("Axis");
 
-    const std::size_t axisIdx = axis>=0 ?
-                                axis :
-                                static_cast<std::size_t>(axis) + op.getInput(0)->dims().size();
+    const std::size_t axisIdx = static_cast<std::size_t>(axis) + (axis >= 0 ? 0 : op.getInput(0)->dims().size());
 
     std::size_t postAxisElems = 1;
     for (std::size_t i = axisIdx + 1; i < op.getInput(0)->dims().size(); ++i) {
@@ -37,13 +35,15 @@ void Aidge::Gather_OpImpl::forward() {
         preAxisElems *= op.getInput(0)->dims()[i];
     }
 
-    const auto indices = op.template getAttr<std::vector<std::int64_t>>("Indices");
+    const auto indices = static_cast<const int*>(op.getInput(1)->getImpl()->rawPtr());
     std::size_t outputOffset = 0;
     for (std::size_t i=0; i<preAxisElems; ++i)
     {
-        for(std::size_t j=0; j<indices.size(); ++j)
+        for(std::size_t j=0; j<op.getInput(1)->size(); ++j)
         {
-            const std::size_t idx = indices[j] >= 0 ? indices[j] : static_cast<std::size_t>(indices[j]) + op.getInput(0)->dims()[axisIdx];
+            const std::size_t idx = indices[j] >= 0 ?
+                                        static_cast<std::size_t>(indices[j]) :
+                                        static_cast<std::size_t>(indices[j] + static_cast<int>(op.getInput(0)->dims()[axisIdx]));
             op.getOutput(0)->getImpl()->copy(op.getInput(0)->getImpl()->rawPtr(i * postAxisElems * op.getInput(0)->dims()[axisIdx] + idx * postAxisElems), postAxisElems, outputOffset);
             outputOffset += postAxisElems;
         }
@@ -69,7 +69,7 @@ bool Aidge::Gather_Op::forwardDims(bool /*allowDataDependency*/) {
                               this->template getAttr<GatherAttr::Axis>():
                               this->template getAttr<GatherAttr::Axis>()+outDims.size();
         outDims.erase(outDims.begin() + static_cast<std::size_t>(axisIdx));
-        if( indicesDims[0]>0 ) // In case indices is a scalar indicesDims is a 0 
+        if( indicesDims[0]>0 ) // In case indices is a scalar indicesDims is a 0
         {
             outDims.insert(outDims.begin() + static_cast<std::size_t>(axisIdx), indicesDims.begin(),indicesDims.end());
         }
diff --git a/src/recipes/HorizontalTiling.cpp b/src/recipes/HorizontalTiling.cpp
index d5a8648292f48f70271cc5a7fb8364db02ba8f2c..762ecad59338dfc8ecb0dc141aef7595a8459557 100644
--- a/src/recipes/HorizontalTiling.cpp
+++ b/src/recipes/HorizontalTiling.cpp
@@ -34,32 +34,35 @@ std::set<std::shared_ptr<Aidge::Node>> Aidge::getConvHorizontalTiling(const std:
                                                             const Aidge::DimIdx_t axis,
                                                             const std::size_t nbSlices)
 {
+    // for now, Tiling works only with Conv Operators
     if (node->getOperator()->type() != "Conv") {
         AIDGE_INTERNAL_ASSERT("Operator should be a Convolution.");
     }
-    AIDGE_ASSERT(node->getOperator()->operatorType() == OperatorType::Tensor, "Operator must be of Tensor type.");
+    // TODO: back when tiling works with other Operators
+    // AIDGE_ASSERT(node->getOperator()->operatorType() == OperatorType::Tensor, "Operator must be of Tensor type.");
     const auto& op = std::static_pointer_cast<OperatorTensor>(node->getOperator());
-    if (op->nbOutputs() != 1 || op->nbData() > 1) {
-        AIDGE_INTERNAL_ASSERT("Only slice Operators with one output and at most one input for now.");
-    }
+    // TODO: back when tiling works with other Operators
+    // if (op->nbOutputs() != 1 || op->nbData() > 1) {
+    //     AIDGE_INTERNAL_ASSERT("Only slice Operators with one output and at most one input for now.");
+    // }
     if (!op->dimsForwarded()) {
         AIDGE_INTERNAL_ASSERT("Dimensions must be forwarded before any tiling");
     }
+
+    const std::shared_ptr<Tensor>& outTensor = op->getOutput(0);
+    std::vector<DimSize_t> outputDims = outTensor->dims();
+
     // start by doing a tiling with strict dimensions division
-    const auto& outTensor = op->getOutput(0);
-    if (op->getOutput(0)->dims()[axis] % nbSlices != 0) {
+    if (outputDims[axis] % nbSlices != 0) {
         AIDGE_INTERNAL_ASSERT("axis should be a multiple of nbSlices");
     }
 
     // dimensions of a Slice
-    std::vector<DimSize_t> outputDims = outTensor->dims();
     outputDims[axis] /= nbSlices;
 
-    std::vector<DimSize_t> currentFirstDims = std::vector<DimSize_t>(outTensor->nbDims(), 0);
 
-    std::set<std::shared_ptr<Aidge::Node>> res;
     auto concat = Concat(nbSlices, axis);
-    res.insert(concat);
+    std::set<std::shared_ptr<Aidge::Node>> tiledOperator{concat};
 
     // check slice sizes
     // const auto inputDims = op->computeReceptiveField(currentFirstDims[axis], outputDims, 0);
@@ -73,10 +76,13 @@ std::set<std::shared_ptr<Aidge::Node>> Aidge::getConvHorizontalTiling(const std:
     std::vector<std::shared_ptr<Node>> clonedInputs = std::vector<std::shared_ptr<Node>>(node->nbInputs(), nullptr);
     for (std::size_t i = node->nbData(); i < node ->nbInputs(); ++i) {
         clonedInputs[i] = node -> getParent(i) -> cloneSharedOperators();
-        clonedInputs[i] -> setName(node -> name() + "_0");
-        res.insert(clonedInputs[i]);
+        clonedInputs[i] -> setName(node -> getParent(i) -> name() + "_0");
+        tiledOperator.insert(clonedInputs[i]);
     }
 
+    const std::vector<std::string> sliceInputsNames = Slice_Op::getInputsName();
+    // coordinates of the first value of the current output slice
+    std::vector<DimSize_t> currentFirstDims = std::vector<DimSize_t>(outTensor->nbDims(), 0);
     for (IOIndex_t i = 0; currentFirstDims[axis] < outTensor->dims()[axis]; currentFirstDims[axis] += outputDims[axis], ++i) {
         const auto inputDims = op->computeReceptiveField(currentFirstDims, outputDims, 0);
         auto newNode = node -> clone(); // no input associated to clones
@@ -86,7 +92,6 @@ std::set<std::shared_ptr<Aidge::Node>> Aidge::getConvHorizontalTiling(const std:
 
         auto backend = outTensor->getImpl()->backend();
         auto slice = Slice("Slice_" + std::to_string(currentFirstDims[axis]));
-        auto sliceInputsNames = slice->getOperator()->getInputsName();
         // Create Slice's Starts producer node
         std::vector<std::int64_t> inputDimsStart(inputDims[0].first.size());
         for (std::size_t dim = 0; dim < inputDimsStart.size(); ++dim) {
@@ -96,8 +101,8 @@ std::set<std::shared_ptr<Aidge::Node>> Aidge::getConvHorizontalTiling(const std:
         starts -> setDataType(DataType::Int64);
         starts -> setBackend(backend);
         starts -> resize(std::vector<std::size_t>({inputDimsStart.size()}));
-        starts -> getImpl() -> setRawPtr(inputDimsStart.data(), inputDimsStart.size());
-        auto startsNode = Producer(starts, sliceInputsNames[1]);
+        starts -> getImpl() -> copyFromHost(inputDimsStart.data(), inputDimsStart.size());
+        auto startsNode = Producer(starts, slice->name() + sliceInputsNames[1]);
         startsNode -> addChild(slice, 0, 1);
 
         std::vector<std::int64_t> inputDimsEnd(inputDims[0].first.size());
@@ -108,8 +113,8 @@ std::set<std::shared_ptr<Aidge::Node>> Aidge::getConvHorizontalTiling(const std:
         ends -> setDataType(DataType::Int64);
         ends -> setBackend(backend);
         ends -> resize(std::vector<std::size_t>({inputDimsEnd.size()}));
-        ends -> getImpl() -> setRawPtr(inputDimsEnd.data(), inputDimsEnd.size());
-        auto endsNode = Producer(ends, sliceInputsNames[2]);
+        ends -> getImpl() -> copyFromHost(inputDimsEnd.data(), inputDimsEnd.size());
+        auto endsNode = Producer(ends, slice->name() + sliceInputsNames[2]);
         endsNode -> addChild(slice, 0, 2);
 
         // Create Slice's Axes producer node
@@ -120,16 +125,15 @@ std::set<std::shared_ptr<Aidge::Node>> Aidge::getConvHorizontalTiling(const std:
         axes -> setDataType(DataType::Int64);
         axes -> setBackend(backend);
         axes -> resize(std::vector<std::size_t>({usedDims.size()}));
-        axes -> getImpl() -> setRawPtr(usedDims.data(), usedDims.size());
-        auto axesNode = Producer(axes, sliceInputsNames[3]);
+        axes -> getImpl() -> copyFromHost(usedDims.data(), usedDims.size());
+        auto axesNode = Producer(axes, slice->name() + sliceInputsNames[3]);
         axesNode -> addChild(slice, 0, 3);
 
         slice -> addChild(newNode, 0, 0);
         newNode -> addChild(concat, 0, i);
 
-        res.insert(slice);
-        res.insert(newNode);
+        tiledOperator.insert({slice, newNode, startsNode, endsNode, axesNode});
     }
 
-    return res;
+    return tiledOperator;
 }
\ No newline at end of file
diff --git a/unit_tests/operator/Test_GatherImpl.cpp b/unit_tests/operator/Test_GatherImpl.cpp
index 2995963a35cda5b0c5794b1d15e4064438b58ece..bd77c774a890fc63c5517263a2d413a63ee37926 100644
--- a/unit_tests/operator/Test_GatherImpl.cpp
+++ b/unit_tests/operator/Test_GatherImpl.cpp
@@ -14,12 +14,13 @@
 #include "aidge/data/Tensor.hpp"
 #include "aidge/operator/Gather.hpp"
 
+#include <cstdint>
 #include <memory>
 
 
 using namespace Aidge;
 
-TEST_CASE("[cpu/operator] Gather(forward)") {
+TEST_CASE("[cpu/operator] Gather(forward)", "[Gather][CPU]") {
     SECTION("2D Tensor axis 0") {
         std::shared_ptr<Tensor> input = std::make_shared<Tensor>(Array2D<int,3,3> {
             {
@@ -42,10 +43,10 @@ TEST_CASE("[cpu/operator] Gather(forward)") {
             }
         });
 
-        std::shared_ptr<Node> myGather = Gather({1, 2}, {1, 2}, 0);
+        std::shared_ptr<Node> myGather = Gather(std::int8_t(0));
         auto op = std::static_pointer_cast<OperatorTensor>(myGather -> getOperator());
         op->associateInput(0,input);
-        // op->associateInput(1,indexes);
+        op->associateInput(1,indexes);
         op->setDataType(DataType::Int32);
         op->setBackend("cpu");
         myGather->forward();
@@ -82,10 +83,10 @@ TEST_CASE("[cpu/operator] Gather(forward)") {
             }
         });
 
-        std::shared_ptr<Node> myGather = Gather({0, 2}, {1, 2}, 1);
+        std::shared_ptr<Node> myGather = Gather(1);
         auto op = std::static_pointer_cast<OperatorTensor>(myGather -> getOperator());
         op->associateInput(0,input);
-        // op->associateInput(1,indexes);
+        op->associateInput(1,indexes);
         op->setDataType(DataType::Int32);
         op->setBackend("cpu");
         myGather->forward();
diff --git a/unit_tests/operator/Test_SliceImpl.cpp b/unit_tests/operator/Test_SliceImpl.cpp
index 91ae92848b552a6038a4cb5f8dd3848b20ac2168..54cf0ade66901e57e753f2723038f77d7174a1be 100644
--- a/unit_tests/operator/Test_SliceImpl.cpp
+++ b/unit_tests/operator/Test_SliceImpl.cpp
@@ -19,15 +19,21 @@ using namespace Aidge;
 TEST_CASE("[cpu/operator] Slice(forward)", "[Slice][CPU]") {
     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}
+            {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<Tensor> expectedOutput = std::make_shared<Tensor>(Array1D<int,3> {
+            {0, 1, -2}
         });
+        std::shared_ptr<Tensor> starts = std::make_shared<Tensor>(Array1D<int,1>{{0}});
+        std::shared_ptr<Tensor> ends = std::make_shared<Tensor>(Array1D<int,1>{{3}});
+        std::shared_ptr<Tensor> axes = std::make_shared<Tensor>(Array1D<int,1>{{0}});
 
-        std::shared_ptr<Node> mySlice = Slice({0}, {3}, {0});
+        std::shared_ptr<Node> mySlice = Slice();
         auto op = std::static_pointer_cast<OperatorTensor>(mySlice -> getOperator());
         mySlice->getOperator()->associateInput(0,input0);
+        mySlice->getOperator()->associateInput(1,starts);
+        mySlice->getOperator()->associateInput(2,ends);
+        mySlice->getOperator()->associateInput(3,axes);
         mySlice->getOperator()->setDataType(DataType::Int32);
         mySlice->getOperator()->setBackend("cpu");
         mySlice->forward();
@@ -50,10 +56,16 @@ TEST_CASE("[cpu/operator] Slice(forward)", "[Slice][CPU]") {
                 {-5,-6, 7}
             }
         });
+        std::shared_ptr<Tensor> starts = std::make_shared<Tensor>(Array1D<int,2>{{0,5}});
+        std::shared_ptr<Tensor> ends = std::make_shared<Tensor>(Array1D<int,2>{{2,8}});
+        std::shared_ptr<Tensor> axes = std::make_shared<Tensor>(Array1D<int,2>{{0,1}});
 
-        std::shared_ptr<Node> mySlice = Slice({0,5}, {1,7}, {0,1});
+        std::shared_ptr<Node> mySlice = Slice();
         auto op = std::static_pointer_cast<OperatorTensor>(mySlice -> getOperator());
         mySlice->getOperator()->associateInput(0,input0);
+        mySlice->getOperator()->associateInput(1,starts);
+        mySlice->getOperator()->associateInput(2,ends);
+        mySlice->getOperator()->associateInput(3,axes);
         mySlice->getOperator()->setDataType(DataType::Int32);
         mySlice->getOperator()->setBackend("cpu");
         mySlice->forward();
@@ -83,10 +95,16 @@ TEST_CASE("[cpu/operator] Slice(forward)", "[Slice][CPU]") {
                 }
             }
         });
+        std::shared_ptr<Tensor> starts = std::make_shared<Tensor>(Array1D<int,3>{{0,1,4}});
+        std::shared_ptr<Tensor> ends = std::make_shared<Tensor>(Array1D<int,3>{{1,2,7}});
+        std::shared_ptr<Tensor> axes = std::make_shared<Tensor>(Array1D<int,3>{{0,1,2}});
 
-        std::shared_ptr<Node> mySlice = Slice({0,1,4}, {0,1,6}, {0,1,2});
+        std::shared_ptr<Node> mySlice = Slice();
         auto op = std::static_pointer_cast<OperatorTensor>(mySlice -> getOperator());
         mySlice->getOperator()->associateInput(0,input0);
+        mySlice->getOperator()->associateInput(1,starts);
+        mySlice->getOperator()->associateInput(2,ends);
+        mySlice->getOperator()->associateInput(3,axes);
         mySlice->getOperator()->setDataType(DataType::Int32);
         mySlice->getOperator()->setBackend("cpu");
         mySlice->forward();
@@ -145,10 +163,16 @@ TEST_CASE("[cpu/operator] Slice(forward)", "[Slice][CPU]") {
                 }
             }
         });
+        std::shared_ptr<Tensor> starts = std::make_shared<Tensor>(Array1D<int,4>{{0,0,0,0}});
+        std::shared_ptr<Tensor> ends = std::make_shared<Tensor>(Array1D<int,4>{{2,2,2,10}});
+        std::shared_ptr<Tensor> axes = std::make_shared<Tensor>(Array1D<int,4>{{0,1,2,3}});
 
-        std::shared_ptr<Node> mySlice = Slice({0,0,0,0}, {1,1,1,9}, {0,1,2,3});
+        std::shared_ptr<Node> mySlice = Slice();
         auto op = std::static_pointer_cast<OperatorTensor>(mySlice -> getOperator());
         mySlice->getOperator()->associateInput(0,input0);
+        mySlice->getOperator()->associateInput(1,starts);
+        mySlice->getOperator()->associateInput(2,ends);
+        mySlice->getOperator()->associateInput(3,axes);
         mySlice->getOperator()->setDataType(DataType::Int32);
         mySlice->getOperator()->setBackend("cpu");
         mySlice->forward();