diff --git a/include/aidge/backend/cpu/operator/SliceImpl.hpp b/include/aidge/backend/cpu/operator/SliceImpl.hpp index c7d5779130ff0c5950a19a89435d7acb02ec5cbf..6be835f04302c69c430084417334d3b9edb0eb63 100644 --- a/include/aidge/backend/cpu/operator/SliceImpl.hpp +++ b/include/aidge/backend/cpu/operator/SliceImpl.hpp @@ -13,7 +13,6 @@ #define AIDGE_CPU_OPERATOR_SLICEIMPL_H_ #include <memory> -#include <tuple> #include <vector> #include "aidge/backend/OperatorImpl.hpp" @@ -39,7 +38,6 @@ class SliceImplBackward_cpu const void*, void*)> {}; - class SliceImpl_cpu : public OperatorImpl { public: SliceImpl_cpu(const Slice_Op& op) : OperatorImpl(op) {} @@ -48,7 +46,6 @@ public: return std::make_unique<SliceImpl_cpu>(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, @@ -58,14 +55,12 @@ public: void updateConsummerProducer() override final; void forward() override; - void backward() override; }; - namespace { static Registrar<Slice_Op> registrarSliceImpl_cpu("cpu", Aidge::SliceImpl_cpu::create); -} // namespace +} } // namespace Aidge -#endif /* AIDGE_CPU_OPERATOR_LEAKYRELUIMPL_H_ */ \ No newline at end of file +#endif /* AIDGE_CPU_OPERATOR_SLICEIMPL_H_ */ diff --git a/include/aidge/backend/cpu/operator/SliceImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/SliceImpl_forward_kernels.hpp index 9b1c015908aaeca7938df3b0722ef3dd7e12649a..395f6d45a3962269131d75cb978fbe97db6aef20 100644 --- a/include/aidge/backend/cpu/operator/SliceImpl_forward_kernels.hpp +++ b/include/aidge/backend/cpu/operator/SliceImpl_forward_kernels.hpp @@ -12,57 +12,73 @@ #ifndef AIDGE_CPU_OPERATOR_SLICEIMPL_FORWARD_KERNEL_H_ #define AIDGE_CPU_OPERATOR_SLICEIMPL_FORWARD_KERNEL_H_ -#include "aidge/utils/Registrar.hpp" -#include "aidge/operator/Slice.hpp" -#include "aidge/backend/cpu/operator/SliceImpl.hpp" -#include <vector> #include <cstddef> +#include <vector> +#include "aidge/backend/cpu/operator/SliceImpl.hpp" #include "aidge/data/Data.hpp" +#include "aidge/operator/Slice.hpp" +#include "aidge/utils/Registrar.hpp" namespace Aidge { template <class I> void SliceImpl_cpu_forward_kernel(const typename Slice_Op::Attrs& attrs, - const std::vector<DimSize_t> inputDims, - const void* input_, - void* output_) { + const std::vector<DimSize_t> inputDims, + const void* input_, + void* output_) { + std::vector<DimSize_t> slicedDims = inputDims; + + std::size_t beginning = 0; + DimSize_t nbAxes = std::get<2>(attrs).size(); + for (std::size_t i = 0; i < nbAxes; ++i) { + // For each slice operation get the params and cast them to size_t + const std::int64_t axis_ = std::get<2>(attrs)[i]; + const std::int64_t start_ = std::get<0>(attrs)[i]; + const std::int64_t end_ = std::get<1>(attrs)[i]; + const std::size_t axis = axis_ >= 0 ? axis_ : static_cast<std::size_t>(axis_ + static_cast<std::int32_t>(inputDims.size())); + const std::size_t start = start_ >= 0 ? start_ : start_ + inputDims[axis]; + const std::size_t end = end_ >= 0 ? end_ : end_ + inputDims[axis]; + std::size_t stride = 1; + for (std::size_t j = inputDims.size() - 1; j > axis; --j) stride *= inputDims[j]; + beginning += start * stride; + const std::size_t sliceLength = end - start + 1; + slicedDims[axis] = sliceLength; + } - const I* input = static_cast<const I*>(input_) + std::get<0>(attrs); + const I* input = static_cast<const I*>(input_) + beginning; I* output = static_cast<I*>(output_); - const std::vector<Coord_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} + // for inputDims = {4,5,5,3} & slicedDims = {3,2,2,1}, substractDims = {1,5,5,3} 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} + // for slicedDims = {3,2,2,1}, prodSlicedDims = {12,4,2,1} 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::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++]; + std::size_t j = 0; + std::size_t i = 0; + for (; j < prodSlicedDims[0];) { + output[j] = input[i++]; ++j; - for (std::size_t idx = nbDims - 1; idx > 0; --idx) { - i += j % prodSlicedDims[idx] == 0 ? substractedDims[idx]*prodInputDims[idx+1] : 0; - } - } + for (std::size_t idx = nbDims - 1; idx > 0; --idx) { + i += j % prodSlicedDims[idx] == 0 ? substractedDims[idx] * prodInputDims[idx + 1] : 0; + } + } } namespace { -// DIM = 1 static Registrar<SliceImplForward_cpu> registrarSliceImplForward_cpu_Float32( {DataType::Float32}, Aidge::SliceImpl_cpu_forward_kernel<float>); static Registrar<SliceImplForward_cpu> registrarSliceImplForward_cpu_Int32( diff --git a/unit_tests/operator/Test_SliceImpl.cpp b/unit_tests/operator/Test_SliceImpl.cpp index 3e25c28f9caac61c64d38fa70879af79d20392bc..7a71f31e9850852cadd659c91683c30ddcbe9849 100644 --- a/unit_tests/operator/Test_SliceImpl.cpp +++ b/unit_tests/operator/Test_SliceImpl.cpp @@ -27,14 +27,14 @@ TEST_CASE("[cpu/operator] Slice(forward)", "[Slice][CPU]") { {0, 1, 2,-3} }); - std::shared_ptr<Node> mySlice = Slice(0, {4}); + std::shared_ptr<Node> mySlice = Slice({0}, {3}, {0}); auto op = std::static_pointer_cast<OperatorTensor>(mySlice -> getOperator()); mySlice->getOperator()->associateInput(0,input0); mySlice->getOperator()->setDataType(DataType::Int32); mySlice->getOperator()->setBackend("cpu"); op->computeOutputDims(); mySlice->forward(); - // mySlice->getOperator()->output(0).print(); + REQUIRE(*(op->getOutput(0)) == *expectedOutput); REQUIRE(op->getOutput(0)->dims() == expectedOutput->dims()); REQUIRE(op->getOutput(0)->dataType() == expectedOutput->dataType()); @@ -54,7 +54,7 @@ TEST_CASE("[cpu/operator] Slice(forward)", "[Slice][CPU]") { } }); - std::shared_ptr<Node> mySlice = Slice(5, {2,3}); + std::shared_ptr<Node> mySlice = Slice({0,5}, {1,7}, {0,1}); auto op = std::static_pointer_cast<OperatorTensor>(mySlice -> getOperator()); mySlice->getOperator()->associateInput(0,input0); mySlice->getOperator()->setDataType(DataType::Int32); @@ -88,7 +88,7 @@ TEST_CASE("[cpu/operator] Slice(forward)", "[Slice][CPU]") { } }); - std::shared_ptr<Node> mySlice = Slice(14, {1,1,3}); + std::shared_ptr<Node> mySlice = Slice({0,1,4}, {0,1,6}, {0,1,2}); auto op = std::static_pointer_cast<OperatorTensor>(mySlice -> getOperator()); mySlice->getOperator()->associateInput(0,input0); mySlice->getOperator()->setDataType(DataType::Int32); @@ -151,7 +151,7 @@ TEST_CASE("[cpu/operator] Slice(forward)", "[Slice][CPU]") { } }); - std::shared_ptr<Node> mySlice = Slice(0, {2,2,2,10}); + std::shared_ptr<Node> mySlice = Slice({0,0,0,0}, {1,1,1,9}, {0,1,2,3}); auto op = std::static_pointer_cast<OperatorTensor>(mySlice -> getOperator()); mySlice->getOperator()->associateInput(0,input0); mySlice->getOperator()->setDataType(DataType::Int32); diff --git a/unit_tests/operator/Test_SoftmaxImpl.cpp b/unit_tests/operator/Test_SoftmaxImpl.cpp index 4de62220cc95ded586101d94c7c3961332a31620..fce2ef971a8f1fd0471df589a90e3b4dc8560bfd 100644 --- a/unit_tests/operator/Test_SoftmaxImpl.cpp +++ b/unit_tests/operator/Test_SoftmaxImpl.cpp @@ -68,9 +68,9 @@ TEST_CASE("[cpu/operator] Softmax(forward)", "[Softmax][CPU]") 0.04469007, 0.16429459}}}); - std::shared_ptr<Node> mySoftmax = Softmax(); - auto op = std::static_pointer_cast<OperatorTensor>(mySoftmax->getOperator()); - mySoftmax->getOperator()->associateInput(0, input); + std::shared_ptr<Node> mySoftmax = Softmax(1); + auto op = std::static_pointer_cast<OperatorTensor>(mySoftmax -> getOperator()); + mySoftmax->getOperator()->associateInput(0,input); mySoftmax->getOperator()->setDataType(DataType::Float32); mySoftmax->getOperator()->setBackend("cpu"); op->computeOutputDims(); @@ -126,9 +126,9 @@ TEST_CASE("[cpu/operator] Softmax(forward)", "[Softmax][CPU]") {0.41033682, 0.37336978, 0.21872495}, {0.34566763, 0.32462072, 0.48979440}}}}}); - std::shared_ptr<Node> mySoftmax = Softmax(); - auto op = std::static_pointer_cast<OperatorTensor>(mySoftmax->getOperator()); - mySoftmax->getOperator()->associateInput(0, input); + std::shared_ptr<Node> mySoftmax = Softmax(1); + auto op = std::static_pointer_cast<OperatorTensor>(mySoftmax -> getOperator()); + mySoftmax->getOperator()->associateInput(0,input); mySoftmax->getOperator()->setDataType(DataType::Float32); mySoftmax->getOperator()->setBackend("cpu"); op->computeOutputDims(); diff --git a/unit_tests/recipies/Test_HorizontalTiling.cpp b/unit_tests/recipies/Test_HorizontalTiling.cpp index b71a01d130a783caf5c643dfb0c3757b1c524e5e..268d94cc55821c41f9c3d4a8451b5730ecaf1bd0 100644 --- a/unit_tests/recipies/Test_HorizontalTiling.cpp +++ b/unit_tests/recipies/Test_HorizontalTiling.cpp @@ -183,26 +183,4 @@ TEST_CASE("[core/recipies] Tiling(transformation)", "[Tiling][Recipies]") { } } } -} - // std::shared_ptr<GraphView> g = Sequential({ - // Conv(3, 16, {3,3}, "conv1"), - // ReLU("relu1"), - // Conv(16, 32, {1,1}, "conv2"), - // Conv(32, 16, {1,1}, "conv3"), - // Conv(16, 10, {3,3}, "conv4"), - // ReLU("relu2") - // }); - - // for (auto& individualConv : g->match("Conv")) { - // auto tiledConv = horizontalTiling(individualConv); - // g->replace(individualConv, tiledConv); - // } - // } - - // SECTION("Create the GraphView with tiled layers") { - // std::shared_ptr<GraphView> g; - // g->addChild(horizontalTiling(Conv())) - // } - -// } -// } // namespace Aidge \ No newline at end of file +} // namespace Aidge \ No newline at end of file