From ac47be4adf2753eda267608c426ef5ac6311b34e Mon Sep 17 00:00:00 2001 From: NAUD Maxence <maxence.naud@cea.fr> Date: Thu, 14 Dec 2023 14:25:00 +0000 Subject: [PATCH] update slice and add some documentation to conv --- include/aidge/operator/Conv.hpp | 12 ++++++++++++ include/aidge/operator/Slice.hpp | 26 +++++++++++++++++++------- src/operator/Slice.cpp | 14 +++++++------- src/recipies/HorizontalTiling.cpp | 14 +++++++++----- 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/include/aidge/operator/Conv.hpp b/include/aidge/operator/Conv.hpp index 7fa99b084..08c642ab5 100644 --- a/include/aidge/operator/Conv.hpp +++ b/include/aidge/operator/Conv.hpp @@ -193,6 +193,18 @@ std::vector<std::pair<std::vector<Aidge::DimSize_t>, std::vector<DimSize_t>>> co template <DimIdx_t DIM> const std::string Conv_Op<DIM>::Type = "Conv"; +/** + * @brief Perform a convolution on the input Tensor. + * + * @tparam DIM Number of dimensions for the feature map. + * @param inChannels Number of input channels. + * @param outChannels Number of output channels. + * @param kernelDims Dimensions of the kernel. Must be the same number of dimensions as the feature map. + * @param name Name of the operator. + * @param strideDims Dimensions of the stride attribute. Must be the same number of dimensions as the feature map. + * @param dilationDims Dimensions of the dilation attribute. Must be the same number of dimensions as the feature map. + * @return std::shared_ptr<Node> A Node containing the operator. + */ template <std::array<DimSize_t, 1>::size_type DIM> inline std::shared_ptr<Node> Conv(DimSize_t inChannels, DimSize_t outChannels, diff --git a/include/aidge/operator/Slice.hpp b/include/aidge/operator/Slice.hpp index 9b93b9448..a56e63508 100644 --- a/include/aidge/operator/Slice.hpp +++ b/include/aidge/operator/Slice.hpp @@ -29,17 +29,17 @@ 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::size_t>, std::vector<std::size_t>, std::vector<std::size_t>> { + public StaticAttributes<SliceAttr, std::vector<std::int32_t>, std::vector<std::int32_t>, std::vector<std::int32_t>> { public: static const std::string Type; Slice_Op() = delete; - using Attributes_ = StaticAttributes<SliceAttr, std::vector<std::size_t>, std::vector<std::size_t>, std::vector<std::size_t>>; + using Attributes_ = StaticAttributes<SliceAttr, std::vector<std::int32_t>, std::vector<std::int32_t>, std::vector<std::int32_t>>; template <SliceAttr e> using attr = typename Attributes_::template attr<e>; - Slice_Op(const std::vector<std::size_t>& starts, const std::vector<std::size_t>& ends, const std::vector<std::size_t>& axes) + Slice_Op(const std::vector<std::int32_t>& starts, const std::vector<std::int32_t>& ends, const std::vector<std::int32_t>& axes) : OperatorTensor(Type, 1, 0, 1), Attributes_(attr<SliceAttr::Starts>(starts), attr<SliceAttr::Ends>(ends), @@ -84,10 +84,22 @@ public: } }; - -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, +/** + * @brief Exract a sub-Tensor from a bigger original Tensor. + * @param starts Indexes for each dimension of the first element. + * Can be a negative value. Negative values start their reference from the last index. + * ``-1`` referes to the last index of a dimension. + * @param ends Indexes for each dimension of the last element. + * Can be a negative value. Negative values start their reference from the last index. + * ``-1`` referes to the last index of a dimension. + * @param axes Dimensions for which start/end indexes apply. Not specifying a dimensions + * means the whole dimensions is extracted. + * @param name Name of the Operator. + * @return std::shared_ptr<Node> A Node containing the Operator. + */ +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, const std::string &name = "") { // FIXME: properly handle default w&b initialization in every cases return std::make_shared<Node>(std::make_shared<Slice_Op>(starts, ends, axes), name); diff --git a/src/operator/Slice.cpp b/src/operator/Slice.cpp index b9ba4fe36..bccb0b8b4 100644 --- a/src/operator/Slice.cpp +++ b/src/operator/Slice.cpp @@ -32,14 +32,14 @@ void Aidge::Slice_Op::computeOutputDims() { std::vector<DimSize_t> outDims = getInput(0)->dims(); 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]; + const std::int64_t axis_ = this->template getAttr<SliceAttr::Axes>()[i]; + const std::int64_t start_ = this->template getAttr<SliceAttr::Starts>()[i]; + const std::int64_t end_ = this->template getAttr<SliceAttr::Ends>()[i]; + const std::size_t axis = axis_ >= 0 ? static_cast<std::size_t>(axis_) : axis_ + getInput(0)->nbDims(); + const std::size_t start = start_ >= 0 ? static_cast<std::size_t>(start_) : start_ + getInput(0)->dims()[axis]; + const std::size_t end = end_ >= 0 ? static_cast<std::size_t>(end_) : end_ + getInput(0)->dims()[axis]; - std::size_t sliceLength = end - start + 1; + const 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"); diff --git a/src/recipies/HorizontalTiling.cpp b/src/recipies/HorizontalTiling.cpp index 48d8cfc0b..6cc34eba0 100644 --- a/src/recipies/HorizontalTiling.cpp +++ b/src/recipies/HorizontalTiling.cpp @@ -82,13 +82,17 @@ std::set<std::shared_ptr<Aidge::Node>> Aidge::getConvHorizontalTiling(const std: clonedInputs[1] -> addChild(newNode, 0, 1); clonedInputs[2] -> addChild(newNode, 0, 2); // Slice for input and each parameter - auto inputDimsEnd = inputDims[0].first; + std::vector<std::int32_t> inputDimsEnd(inputDims[0].first.size()); for (std::size_t dim = 0; dim < inputDimsEnd.size(); ++dim) { - inputDimsEnd[dim] += inputDims[0].second[dim]; + inputDimsEnd[dim] = static_cast<std::int32_t>(inputDims[0].first[dim] + inputDims[0].second[dim]) - 1; } - 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])); + std::vector<std::int32_t> inputDimsStart(inputDims[0].first.size()); + for (std::size_t dim = 0; dim < inputDimsStart.size(); ++dim) { + inputDimsStart[dim] = static_cast<std::int32_t>(inputDims[0].first[dim]); + } + std::vector<std::int32_t> usedDims(inputDimsEnd.size()); + std::iota(usedDims.begin(), usedDims.end(), static_cast<std::int32_t>(0)); + auto slice = Slice(inputDimsStart, inputDimsEnd, usedDims, "Slice_" + std::to_string(currentFirstDims[axis])); slice -> addChild(newNode, 0, 0); newNode -> addChild(concat, 0, i); -- GitLab