diff --git a/include/aidge/operator/Fold.hpp b/include/aidge/operator/Fold.hpp index 4fa16305a20910969cfa2d33f35d6bdc422f6564..28127f9efe437531a64d228f7ed9c168edc39eb6 100644 --- a/include/aidge/operator/Fold.hpp +++ b/include/aidge/operator/Fold.hpp @@ -34,35 +34,33 @@ enum class FoldAttr { OutputDims, StrideDims, DilationDims, KernelDims }; template <DimIdx_t DIM> class Fold_Op : public OperatorTensor, - public Registrable<Fold_Op<DIM>, std::string, std::shared_ptr<OperatorImpl>(const Fold_Op<DIM> &)>, - public StaticAttributes<FoldAttr, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>> { + public Registrable<Fold_Op<DIM>, std::string, std::shared_ptr<OperatorImpl>(const Fold_Op<DIM> &)> { public: static const std::string Type; - Fold_Op() = delete; - +private: using Attributes_ = StaticAttributes<FoldAttr, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>>; - template <FoldAttr e> - using attr = typename Attributes_::template attr<e>; + template <FoldAttr e> using attr = typename Attributes_::template attr<e>; + const std::shared_ptr<Attributes_> mAttributes; + +public: + Fold_Op() = delete; constexpr Fold_Op(const std::array<DimSize_t, DIM> &outputDims, const std::array<DimSize_t, DIM> &kernelDims, const std::array<DimSize_t, DIM> &strideDims = create_array<DimSize_t,DIM>(1), const std::array<DimSize_t, DIM> &dilationDims = create_array<DimSize_t,DIM>(1)) : OperatorTensor(Type, {InputCategory::Data}, 1), - Attributes_(attr<FoldAttr::OutputDims>(outputDims), - attr<FoldAttr::StrideDims>(strideDims), - attr<FoldAttr::DilationDims>(dilationDims), - attr<FoldAttr::KernelDims>(kernelDims)) {} + mAttributes(std::make_shared<Attributes_>( + attr<FoldAttr::OutputDims>(outputDims), + attr<FoldAttr::StrideDims>(strideDims), + attr<FoldAttr::DilationDims>(dilationDims), + attr<FoldAttr::KernelDims>(kernelDims))) {} /** * @brief Copy-constructor. Copy the operator attributes and its output tensor(s), but not its @@ -71,7 +69,7 @@ public: */ Fold_Op(const Fold_Op<DIM> &op) : OperatorTensor(op), - Attributes_(op) + mAttributes(op.mAttributes) { if (!op.backend().empty()) { SET_IMPL_MACRO(Fold_Op<DIM>, *this, op.backend()); @@ -93,6 +91,12 @@ public: void setBackend(const std::string &name, DeviceIdx_t device = 0) override; + inline std::shared_ptr<Attributes> attributes() const override { return mAttributes; } + inline std::array<DimSize_t, DIM>& outputDims() const { return mAttributes->template getAttr<FoldAttr::OutputDims>(); } + inline std::array<DimSize_t, DIM>& strideDims() const { return mAttributes->template getAttr<FoldAttr::StrideDims>(); } + inline std::array<DimSize_t, DIM>& dilationDims() const { return mAttributes->template getAttr<FoldAttr::DilationDims>(); } + inline std::array<DimSize_t, DIM>& kernelDims() const { return mAttributes->template getAttr<FoldAttr::KernelDims>(); } + static const std::vector<std::string> getInputsName(){ return {"data_input"}; } diff --git a/include/aidge/operator/Unfold.hpp b/include/aidge/operator/Unfold.hpp index 778c78da28044e1b6262decb903a8562ad0e5ee1..169fbb05ebeff0e5d38eb9606133d6279cc31cd8 100644 --- a/include/aidge/operator/Unfold.hpp +++ b/include/aidge/operator/Unfold.hpp @@ -41,31 +41,30 @@ enum class UnfoldAttr { StrideDims, DilationDims, KernelDims }; template <DimIdx_t DIM> class Unfold_Op : public OperatorTensor, - public Registrable<Unfold_Op<DIM>, std::string, std::shared_ptr<OperatorImpl>(const Unfold_Op<DIM> &)>, - public StaticAttributes<UnfoldAttr, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>, - std::array<DimSize_t, DIM>> { + public Registrable<Unfold_Op<DIM>, std::string, std::shared_ptr<OperatorImpl>(const Unfold_Op<DIM> &)> { public: static const std::string Type; - Unfold_Op() = delete; - +private: using Attributes_ = StaticAttributes<UnfoldAttr, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>, std::array<DimSize_t, DIM>>; - template <UnfoldAttr e> - using attr = typename Attributes_::template attr<e>; + template <UnfoldAttr e> using attr = typename Attributes_::template attr<e>; + const std::shared_ptr<Attributes_> mAttributes; + +public: + Unfold_Op() = delete; constexpr Unfold_Op(const std::array<DimSize_t, DIM> &kernelDims, const std::array<DimSize_t, DIM> &strideDims = create_array<DimSize_t,DIM>(1), const std::array<DimSize_t, DIM> &dilationDims = create_array<DimSize_t,DIM>(1)) : OperatorTensor(Type, {InputCategory::Data}, 1), - Attributes_(attr<UnfoldAttr::StrideDims>(strideDims), - attr<UnfoldAttr::DilationDims>(dilationDims), - attr<UnfoldAttr::KernelDims>(kernelDims)) + mAttributes(std::make_shared<Attributes_>( + attr<UnfoldAttr::StrideDims>(strideDims), + attr<UnfoldAttr::DilationDims>(dilationDims), + attr<UnfoldAttr::KernelDims>(kernelDims))) { mImpl = std::make_shared<Unfold_OpImpl<DIM>>(*this); } @@ -77,7 +76,7 @@ public: */ Unfold_Op(const Unfold_Op<DIM> &op) : OperatorTensor(op), - Attributes_(op) + mAttributes(op.mAttributes) { if (!op.backend().empty()) { SET_IMPL_MACRO(Unfold_Op<DIM>, *this, op.backend()); @@ -99,6 +98,11 @@ public: void setBackend(const std::string &name, DeviceIdx_t device = 0) override; + inline std::shared_ptr<Attributes> attributes() const override { return mAttributes; } + inline std::array<DimSize_t, DIM>& strideDims() const { return mAttributes->template getAttr<UnfoldAttr::StrideDims>(); } + inline std::array<DimSize_t, DIM>& dilationDims() const { return mAttributes->template getAttr<UnfoldAttr::DilationDims>(); } + inline std::array<DimSize_t, DIM>& kernelDims() const { return mAttributes->template getAttr<UnfoldAttr::KernelDims>(); } + static const std::vector<std::string> getInputsName(){ return {"data_input"}; } diff --git a/src/operator/Fold.cpp b/src/operator/Fold.cpp index a57e117ad00d623c57d057fad9772e620c279b1b..abe73e54ede0611cb14e24332302c35afa91c2a9 100644 --- a/src/operator/Fold.cpp +++ b/src/operator/Fold.cpp @@ -33,14 +33,14 @@ bool Aidge::Fold_Op<DIM>::forwardDims(bool /*allowDataDependency*/) { DimSize_t k = 1; DimSize_t l = 1; - for (std::size_t dim = 0; dim < this->template getAttr<FoldAttr::KernelDims>().size() ; ++dim) { - const DimSize_t kernelExtent = this->template getAttr<FoldAttr::DilationDims>()[dim] * - (this->template getAttr<FoldAttr::KernelDims>()[dim] - 1) + 1; + for (std::size_t dim = 0; dim < this->kernelDims().size() ; ++dim) { + const DimSize_t kernelExtent = this->dilationDims()[dim] * + (this->kernelDims()[dim] - 1) + 1; - k *= this->template getAttr<FoldAttr::KernelDims>()[dim]; + k *= this->kernelDims()[dim]; l *= 1 + static_cast<DimSize_t>( - floor(static_cast<float>(this->template getAttr<FoldAttr::OutputDims>()[dim] - kernelExtent) / - static_cast<float>(this->template getAttr<FoldAttr::StrideDims>()[dim]))); + floor(static_cast<float>(this->outputDims()[dim] - kernelExtent) / + static_cast<float>(this->strideDims()[dim]))); } AIDGE_ASSERT(dims[dims.size() - 2] % k == 0 , "Fold: input number of channels ({}) is not divisible by the product of provided kernel dims ({})!", @@ -50,7 +50,7 @@ bool Aidge::Fold_Op<DIM>::forwardDims(bool /*allowDataDependency*/) { dims[dims.size() - 2] /= k; dims.pop_back(); - dims.insert(dims.end(), this->template getAttr<FoldAttr::OutputDims>().begin(), this->template getAttr<FoldAttr::OutputDims>().end()); + dims.insert(dims.end(), this->outputDims().begin(), this->outputDims().end()); mOutputs[0]->resize(dims); return true; } diff --git a/src/operator/Unfold.cpp b/src/operator/Unfold.cpp index f15bdd799cb5c75404dc8b9b94dbfee6474b147a..94c970fd3a246f0d9e1237e7cce0c15dd8e24526 100644 --- a/src/operator/Unfold.cpp +++ b/src/operator/Unfold.cpp @@ -26,23 +26,23 @@ template <Aidge::DimIdx_t DIM> void Aidge::Unfold_OpImpl<DIM>::forward() { const Unfold_Op<DIM>& op = dynamic_cast<const Unfold_Op<DIM>&>(mOp); - const auto kernelDims = op.template getAttr<UnfoldAttr::KernelDims>(); - const auto dilationDims = op.template getAttr<UnfoldAttr::DilationDims>(); - const auto strideDims = op.template getAttr<UnfoldAttr::StrideDims>(); + const auto kernelDims = op.kernelDims(); + const auto dilationDims = op.dilationDims(); + const auto strideDims = op.strideDims(); const DimSize_t inHeight = op.getInput(0)->dims()[2]; const DimSize_t inWidth = op.getInput(0)->dims()[3]; const DimSize_t inChannels = op.getInput(0)->dims()[1]; - const DimSize_t kernelExtentHeight = op.template getAttr<UnfoldAttr::DilationDims>()[0] * - (op.template getAttr<UnfoldAttr::KernelDims>()[0] - 1) + 1; + const DimSize_t kernelExtentHeight = op.dilationDims()[0] * + (op.kernelDims()[0] - 1) + 1; const DimSize_t outHeight = 1 + static_cast<DimSize_t>( floor(static_cast<float>(inHeight - kernelExtentHeight) / - static_cast<float>(op.template getAttr<UnfoldAttr::StrideDims>()[0]))); - const DimSize_t kernelExtentWidth = op.template getAttr<UnfoldAttr::DilationDims>()[1] * - (op.template getAttr<UnfoldAttr::KernelDims>()[1] - 1) + 1; + static_cast<float>(op.strideDims()[0]))); + const DimSize_t kernelExtentWidth = op.dilationDims()[1] * + (op.kernelDims()[1] - 1) + 1; const DimSize_t outWidth = 1 + static_cast<DimSize_t>( floor(static_cast<float>(inWidth - kernelExtentWidth) / - static_cast<float>(op.template getAttr<UnfoldAttr::StrideDims>()[1]))); + static_cast<float>(op.strideDims()[1]))); const DimSize_t outChannels = op.getOutput(0)->dims()[1]; for (DimSize_t n = 0; n < op.getOutput(0)->dims()[0]; ++n) { @@ -75,14 +75,14 @@ bool Aidge::Unfold_Op<DIM>::forwardDims(bool /*allowDataDependency*/) { DimSize_t k = 1; DimSize_t l = 1; - for (std::size_t dim = 0; dim < this->template getAttr<UnfoldAttr::KernelDims>().size() ; ++dim) { - const DimSize_t kernelExtent = this->template getAttr<UnfoldAttr::DilationDims>()[dim] * - (this->template getAttr<UnfoldAttr::KernelDims>()[dim] - 1) + 1; + for (std::size_t dim = 0; dim < this->kernelDims().size() ; ++dim) { + const DimSize_t kernelExtent = this->dilationDims()[dim] * + (this->kernelDims()[dim] - 1) + 1; - k *= this->template getAttr<UnfoldAttr::KernelDims>()[dim]; + k *= this->kernelDims()[dim]; l *= 1 + static_cast<DimSize_t>( floor(static_cast<float>(inputDims[dim+2] - kernelExtent) / - static_cast<float>(this->template getAttr<UnfoldAttr::StrideDims>()[dim]))); + static_cast<float>(this->strideDims()[dim]))); } mOutputs[0]->resize({inputDims[0], inputDims[1] * k, l}); diff --git a/src/recipes/ConvToMatMul.cpp b/src/recipes/ConvToMatMul.cpp index 75080e90ddc9dff96ceb3b2f1be66f0fc659e4b4..9b88ffc73204b44cf857213d1fdfff49b3191f73 100644 --- a/src/recipes/ConvToMatMul.cpp +++ b/src/recipes/ConvToMatMul.cpp @@ -41,10 +41,10 @@ size_t Aidge::convToMatMul(std::shared_ptr<GraphView> graphView) { const auto wFlattenSize = std::accumulate(wShape.cbegin() + 1, wShape.cend(), DimSize_t(1), std::multiplies<DimSize_t>()); auto microGraph = std::make_shared<GraphView>(); - auto unfold = Unfold(convOp->getAttr<std::array<DimSize_t, 2>>("KernelDims"), + auto unfold = Unfold(convOp->kernelDims(), (!convNode->name().empty()) ? convNode->name() + "_unfold" : "", - convOp->getAttr<std::array<DimSize_t, 2>>("StrideDims"), - convOp->getAttr<std::array<DimSize_t, 2>>("DilationDims")); + convOp->strideDims(), + convOp->dilationDims()); auto wReshapeProd = Producer(std::make_shared<Tensor>(Vector<int64_t>{{static_cast<int64_t>(convOp->getInput(1)->dims()[0]), static_cast<int64_t>(wFlattenSize)}}), (!convNode->name().empty()) ? convNode->name() + "_w_reshape_shape_prod" : "", true); @@ -59,10 +59,10 @@ size_t Aidge::convToMatMul(std::shared_ptr<GraphView> graphView) { false, (!convNode->name().empty()) ? convNode->name() + "_reshape" : ""); //auto fold = Fold(outputDims, - // convOp->getAttr<std::array<DimSize_t, 2>>("KernelDims"), + // convOp->kernelDims(), // (!convNode->name().empty()) ? convNode->name() + "_unfold" : "", - // convOp->getAttr<std::array<DimSize_t, 2>>("StrideDims"), - // convOp->getAttr<std::array<DimSize_t, 2>>("DilationDims")); + // convOp->strideDims(), + // convOp->dilationDims()); wReshapeProd->addChild(wReshape, 0, 1); wReshape->addChild(matMul, 0, 0);