diff --git a/include/aidge/data/Tensor.hpp b/include/aidge/data/Tensor.hpp index 3ee64cecaf9b139ec0a7ef9a0fa4acc5b06f57c7..89d7a3a7b0c4d164473869a9d6372c3bf48cd308 100644 --- a/include/aidge/data/Tensor.hpp +++ b/include/aidge/data/Tensor.hpp @@ -449,12 +449,16 @@ public: */ constexpr inline const std::vector<DimSize_t>& dims() const noexcept { return mDims; } + inline DimSize_t dim(DimIdx_t idx) const { return mDims[idx]; } + /** * @brief Get strides of the Tensor object. * @return constexpr const std::vector<DimSize_t>& */ constexpr inline const std::vector<DimSize_t>& strides() const noexcept { return mStrides; } + inline DimSize_t stride(DimIdx_t idx) const { return mStrides[idx]; } + /** * @brief Return true if Tensor is contiguous in memory. * @return bool diff --git a/include/aidge/operator/GridSample.hpp b/include/aidge/operator/GridSample.hpp index af44a5df5de6908d58951b93921d49ec8e7df708..81900824ed0d26572e593982fa21ed900eda88ee 100644 --- a/include/aidge/operator/GridSample.hpp +++ b/include/aidge/operator/GridSample.hpp @@ -27,15 +27,14 @@ namespace Aidge { enum class GridSampleAttr { Mode, PaddingMode, AlignCorners }; -template <DimIdx_t DIM> class GridSample_Op : public OperatorTensor, - public Registrable<GridSample_Op<DIM>, std::string, std::shared_ptr<OperatorImpl>(const GridSample_Op<DIM>&)> { + public Registrable<GridSample_Op, std::string, std::shared_ptr<OperatorImpl>(const GridSample_Op&)> { public: static const std::string Type; enum class Mode { Linear, Nearest, Cubic }; - enum class PaddingMode { Zeros, Border, Reflexion }; + enum class PaddingMode { Zeros, Border, Reflection }; private: using Attributes_ = StaticAttributes<GridSampleAttr, Mode, PaddingMode, bool>; @@ -49,7 +48,7 @@ public: PaddingMode paddingMode = PaddingMode::Zeros, bool alignCorners = false); - GridSample_Op(const GridSample_Op<DIM>& other); + GridSample_Op(const GridSample_Op& other); ~GridSample_Op() noexcept; public: @@ -63,7 +62,7 @@ public: inline std::shared_ptr<Attributes> attributes() const override { return mAttributes; } inline Mode mode() const { return mAttributes->template getAttr<GridSampleAttr::Mode>(); } inline PaddingMode paddingMode() const { return mAttributes->template getAttr<GridSampleAttr::PaddingMode>(); } - inline bool alignBorders() const { return mAttributes->template getAttr<GridSampleAttr::AlignCorners>(); } + inline bool alignCorners() const { return mAttributes->template getAttr<GridSampleAttr::AlignCorners>(); } static const std::vector<std::string> getInputsName() { return {"data_input", "grid_field"}; @@ -73,13 +72,9 @@ public: } }; -extern template class GridSample_Op<1>; -extern template class GridSample_Op<2>; - -template <DimIdx_t DIM> std::shared_ptr<Node> GridSample( - typename GridSample_Op<DIM>::Mode mode = GridSample_Op<DIM>::Mode::Linear, - typename GridSample_Op<DIM>::PaddingMode paddingMode = GridSample_Op<DIM>::PaddingMode::Zeros, + typename GridSample_Op::Mode mode = GridSample_Op::Mode::Linear, + typename GridSample_Op::PaddingMode paddingMode = GridSample_Op::PaddingMode::Zeros, bool alignCorners = false, const std::string& name = ""); diff --git a/python_binding/operator/pybind_GridSample.cpp b/python_binding/operator/pybind_GridSample.cpp index 34d1ff295093dd35fe5e71cdf335e6147d08194e..49e74f4cbab90f141af5e76df7fbdef6e3794146 100644 --- a/python_binding/operator/pybind_GridSample.cpp +++ b/python_binding/operator/pybind_GridSample.cpp @@ -22,58 +22,51 @@ #include "aidge/utils/Types.h" #include "aidge/utils/Registrar.hpp" // declare_registrable -template <std::size_t DIM> -static typename Aidge::GridSample_Op<DIM>::Mode stringToInterpolationMode(const std::string& mode) { - static std::unordered_map<std::string, typename Aidge::GridSample_Op<DIM>::Mode> map = { - {"linear", Aidge::GridSample_Op<DIM>::Mode::Linear}, - {"nearest", Aidge::GridSample_Op<DIM>::Mode::Nearest}, - {"cubic", Aidge::GridSample_Op<DIM>::Mode::Cubic} + +static typename Aidge::GridSample_Op::Mode stringToInterpolationMode(const std::string& mode) { + static std::unordered_map<std::string, typename Aidge::GridSample_Op::Mode> map = { + {"linear", Aidge::GridSample_Op::Mode::Linear}, + {"nearest", Aidge::GridSample_Op::Mode::Nearest}, + {"cubic", Aidge::GridSample_Op::Mode::Cubic} }; return map[mode]; } -template Aidge::GridSample_Op<1>::Mode stringToInterpolationMode<1>(const std::string&); -template Aidge::GridSample_Op<2>::Mode stringToInterpolationMode<2>(const std::string&); - -template <std::size_t DIM> -static typename Aidge::GridSample_Op<DIM>::PaddingMode stringToPaddingMode(const std::string& mode) { - static std::unordered_map<std::string, typename Aidge::GridSample_Op<DIM>::PaddingMode> map = { - {"zeros", Aidge::GridSample_Op<DIM>::PaddingMode::Zeros}, - {"border", Aidge::GridSample_Op<DIM>::PaddingMode::Border}, - {"reflexion", Aidge::GridSample_Op<DIM>::PaddingMode::Reflexion} +static typename Aidge::GridSample_Op::PaddingMode stringToPaddingMode(const std::string& mode) { + static std::unordered_map<std::string, typename Aidge::GridSample_Op::PaddingMode> map = { + {"zeros", Aidge::GridSample_Op::PaddingMode::Zeros}, + {"border", Aidge::GridSample_Op::PaddingMode::Border}, + {"reflection", Aidge::GridSample_Op::PaddingMode::Reflection} }; return map[mode]; } -template Aidge::GridSample_Op<1>::PaddingMode stringToPaddingMode<1>(const std::string&); -template Aidge::GridSample_Op<2>::PaddingMode stringToPaddingMode<2>(const std::string&); - namespace py = pybind11; namespace Aidge { -template <DimIdx_t DIM> void declare_GridSampleOp(py::module &m) { - const std::string pyClassName("GridSampleOp" + std::to_string(DIM) + "D"); - py::class_<GridSample_Op<DIM>, std::shared_ptr<GridSample_Op<DIM>>, OperatorTensor>( +void declare_GridSampleOp(py::module &m) { + const std::string pyClassName("GridSampleOp"); + py::class_<GridSample_Op, std::shared_ptr<GridSample_Op>, OperatorTensor>( m, pyClassName.c_str(), py::multiple_inheritance()) .def(py::init([](const std::string& mode, const std::string& padding_mode, bool align_corners) { - return new GridSample_Op<DIM>(stringToInterpolationMode<DIM>(mode), stringToPaddingMode<DIM>(padding_mode), align_corners); + return new GridSample_Op(stringToInterpolationMode(mode), stringToPaddingMode(padding_mode), align_corners); }), py::arg("mode") = "linear", py::arg("padding_mode") = "zeros", py::arg("alogn_corners") = false) - .def_static("get_inputs_name", &GridSample_Op<DIM>::getInputsName) - .def_static("get_outputs_name", &GridSample_Op<DIM>::getOutputsName) + .def_static("get_inputs_name", &GridSample_Op::getInputsName) + .def_static("get_outputs_name", &GridSample_Op::getOutputsName) ; - declare_registrable<GridSample_Op<DIM>>(m, pyClassName); + declare_registrable<GridSample_Op>(m, pyClassName); - m.def(("GridSample" + std::to_string(DIM) + "D").c_str(), [](const std::string& mode, - const std::string& padding_mode, - bool align_corners, - const std::string& name) { - return GridSample<DIM>(stringToInterpolationMode<DIM>(mode), stringToPaddingMode<DIM>(padding_mode), align_corners, name); + m.def("GridSample", [](const std::string& mode, + const std::string& padding_mode, + bool align_corners, + const std::string& name) { + return GridSample(stringToInterpolationMode(mode), stringToPaddingMode(padding_mode), align_corners, name); }, py::arg("mode"), py::arg("padding_mode"), py::arg("align_corners"), @@ -82,9 +75,7 @@ template <DimIdx_t DIM> void declare_GridSampleOp(py::module &m) { void init_GridSample(py::module &m) { - declare_GridSampleOp<1>(m); - declare_GridSampleOp<2>(m); -// declare_GridSampleOp<3>(m); + declare_GridSampleOp(m); } } // namespace Aidge diff --git a/src/operator/Fold.cpp b/src/operator/Fold.cpp index 997348d406db6ed4393362941099c93b03d5b9e8..1a2ec88bbfb2bfed134e779619a0a3f0604ce155 100644 --- a/src/operator/Fold.cpp +++ b/src/operator/Fold.cpp @@ -97,4 +97,4 @@ std::shared_ptr<Aidge::Node> Aidge::Fold(const std::array<Aidge::DimSize_t, DIM> return std::make_shared<Node>(std::make_shared<Fold_Op<static_cast<DimIdx_t>(DIM)>>(outputDims, kernelDims, strideDims, dilationDims), name); } -template std::shared_ptr<Aidge::Node> Aidge::Fold<2>(const std::array<Aidge::DimSize_t, 2> &outputDims, const std::array<Aidge::DimSize_t, 2> &kernelDims, const std::string& name, const std::array<Aidge::DimSize_t, 2> &strideDims, const std::array<Aidge::DimSize_t, 2> &dilationDims); +template std::shared_ptr<Aidge::Node> Aidge::Fold<2>(const std::array<Aidge::DimSize_t, 2>&, const std::array<Aidge::DimSize_t, 2>&, const std::string&, const std::array<Aidge::DimSize_t, 2>&, const std::array<Aidge::DimSize_t, 2>&); \ No newline at end of file diff --git a/src/operator/GridSample.cpp b/src/operator/GridSample.cpp index 6cc0ad7462886e5491ba697dbbe868a5f47e4dd4..fa1efc75a4c0a85717343ce4fcdea1a8adcfb4e7 100644 --- a/src/operator/GridSample.cpp +++ b/src/operator/GridSample.cpp @@ -21,13 +21,13 @@ #include "aidge/utils/Registrar.hpp" #include "aidge/utils/Types.h" -template <Aidge::DimIdx_t DIM> -const std::string Aidge::GridSample_Op<DIM>::Type = "GridSample"; -template <Aidge::DimIdx_t DIM> -Aidge::GridSample_Op<DIM>::GridSample_Op( - typename Aidge::GridSample_Op<DIM>::Mode mode, - typename Aidge::GridSample_Op<DIM>::PaddingMode paddingMode, +const std::string Aidge::GridSample_Op::Type = "GridSample"; + + +Aidge::GridSample_Op::GridSample_Op( + typename Aidge::GridSample_Op::Mode mode, + typename Aidge::GridSample_Op::PaddingMode paddingMode, bool alignCorners) : OperatorTensor(Type, {InputCategory::Data, InputCategory::Param}, 1), mAttributes(std::make_shared<Attributes_>( @@ -38,46 +38,47 @@ Aidge::GridSample_Op<DIM>::GridSample_Op( // ctor } -template <Aidge::DimIdx_t DIM> -Aidge::GridSample_Op<DIM>::GridSample_Op(const Aidge::GridSample_Op<DIM>& other) + +Aidge::GridSample_Op::GridSample_Op(const Aidge::GridSample_Op& other) : OperatorTensor(other), mAttributes(other.mAttributes) { if (other.mImpl) { - SET_IMPL_MACRO(GridSample_Op<DIM>, *this, other.backend()); + SET_IMPL_MACRO(GridSample_Op, *this, other.backend()); } else { mImpl = nullptr; } } -template <Aidge::DimIdx_t DIM> -Aidge::GridSample_Op<DIM>::~GridSample_Op() noexcept = default; -template <Aidge::DimIdx_t DIM> -std::shared_ptr<Aidge::Operator> Aidge::GridSample_Op<DIM>::clone() const { - return std::make_shared<GridSample_Op<DIM>>(*this); +Aidge::GridSample_Op::~GridSample_Op() noexcept = default; + + +std::shared_ptr<Aidge::Operator> Aidge::GridSample_Op::clone() const { + return std::make_shared<GridSample_Op>(*this); } -template <Aidge::DimIdx_t DIM> -bool Aidge::GridSample_Op<DIM>::forwardDims(bool /*allowDataDependency*/) { + +bool Aidge::GridSample_Op::forwardDims(bool /*allowDataDependency*/) { // TODO: adapt for other formats than NCHW if (inputsAssociated()) { // check data has batch and channel dimensions: (N, C, D0, D1, ..., DN) - AIDGE_ASSERT((getInput(0)->nbDims() == (DIM+2)), - "Wrong input size for {} operator.", type()); + AIDGE_ASSERT(getInput(0)->nbDims() > 2, "Input should have at least one spatial dimension."); + const std::size_t nbSpatialFeat = getInput(0)->nbDims() -2; // all except channels and batchs // check grid field // should be (N, D0_out, D1_out, ..., DN_out, N+1) - AIDGE_ASSERT(((getInput(1)->nbDims() == (DIM+2)) && - (getInput(1)->template dims<DIM+2>()[DIM+1] == DIM) && - (getInput(1)->template dims<DIM+2>()[0] == getInput(0)->template dims<DIM+2>()[0])), + AIDGE_ASSERT(((getInput(1)->nbDims() == nbSpatialFeat + 2) && + (getInput(1)->dims()[nbSpatialFeat+1] == nbSpatialFeat) && + (getInput(1)->dims()[0] == getInput(0)->dims()[0])), "Wrong grid size {} for {} operator.", getInput(1)->dims(), type()); - std::array<DimSize_t, DIM + 2> outputDims{}; + std::vector<DimSize_t> outputDims{}; + outputDims.reserve(nbSpatialFeat+2); const std::vector<DimSize_t>& inputDims(getInput(1)->dims()); - outputDims[1] = getInput(0)->template dims<DIM+2>()[1]; - outputDims[0] = inputDims[0]; - for (std::size_t i = 2; i < DIM+2; ++i) { - outputDims[i] = inputDims[i-1]; + outputDims.push_back(inputDims[0]); + outputDims.push_back(getInput(0)->dims()[1]); + for (std::size_t i = 2; i < nbSpatialFeat+2; ++i) { + outputDims.push_back(inputDims[i-1]); } mOutputs[0]->resize(outputDims); @@ -88,31 +89,26 @@ bool Aidge::GridSample_Op<DIM>::forwardDims(bool /*allowDataDependency*/) { } -template <Aidge::DimIdx_t DIM> -void Aidge::GridSample_Op<DIM>::setBackend(const std::string &name, Aidge::DeviceIdx_t device) { - SET_IMPL_MACRO(GridSample_Op<DIM>, *this, name); + +void Aidge::GridSample_Op::setBackend(const std::string &name, Aidge::DeviceIdx_t device) { + SET_IMPL_MACRO(GridSample_Op, *this, name); mOutputs[0]->setBackend(name, device); } -template class Aidge::GridSample_Op<1>; -template class Aidge::GridSample_Op<2>; //////////////////////////////////////////////// -template <Aidge::DimIdx_t DIM> + std::shared_ptr<Aidge::Node> Aidge::GridSample( - typename Aidge::GridSample_Op<DIM>::Mode mode, - typename Aidge::GridSample_Op<DIM>::PaddingMode paddingMode, + typename Aidge::GridSample_Op::Mode mode, + typename Aidge::GridSample_Op::PaddingMode paddingMode, bool alignCorners, const std::string& name) { return std::make_shared<Node>( - std::make_shared<GridSample_Op<DIM>>( + std::make_shared<GridSample_Op>( mode, paddingMode, alignCorners), name); } - -template std::shared_ptr<Aidge::Node> Aidge::GridSample<1>(typename Aidge::GridSample_Op<1>::Mode, typename Aidge::GridSample_Op<1>::PaddingMode, bool, const std::string&); -template std::shared_ptr<Aidge::Node> Aidge::GridSample<2>(typename Aidge::GridSample_Op<2>::Mode, typename Aidge::GridSample_Op<2>::PaddingMode, bool, const std::string&); diff --git a/unit_tests/operator/Test_GridSample_Op.cpp b/unit_tests/operator/Test_GridSample_Op.cpp index 754cdb705dcbc5115af32bb0994fbb08ba633c3f..ae38ec7083a0df49fb241509bf52895765ddb0e8 100644 --- a/unit_tests/operator/Test_GridSample_Op.cpp +++ b/unit_tests/operator/Test_GridSample_Op.cpp @@ -33,7 +33,7 @@ TEST_CASE("[core/operator] GridSample_Op(forwardDims)", "[GridSample][forwardDim std::uniform_int_distribution<std::size_t> nbDimsDist(1, 5); // Create GridSample Operator - std::shared_ptr<Node> myGridSample = GridSample<2>(GridSample_Op<2>::Mode::Cubic, GridSample_Op<2>::PaddingMode::Border, false); + std::shared_ptr<Node> myGridSample = GridSample(GridSample_Op::Mode::Cubic, GridSample_Op::PaddingMode::Border, false); auto op = std::static_pointer_cast<OperatorTensor>(myGridSample -> getOperator()); // input_0