From a9476614b7994b874afcb029c858be7fdeda3ab9 Mon Sep 17 00:00:00 2001 From: Noam ZERAH <noam.zerah@cea.fr> Date: Wed, 13 Nov 2024 09:33:47 +0000 Subject: [PATCH] refact: refactoring MetaOperators Declaration and file name (scaling.cpp -> PTQMetaOps.cpp --- include/aidge/aidge.hpp | 1 - include/aidge/operator/MetaOperatorDefs.hpp | 48 ++++++-- include/aidge/operator/Scaling.hpp | 92 -------------- python_binding/operator/pybind_Scaling.cpp | 33 ----- python_binding/pybind_core.cpp | 2 - .../{Scaling.cpp => PTQMetaOps.cpp} | 114 +++++++----------- src/operator/Scaling.cpp | 63 ---------- 7 files changed, 87 insertions(+), 266 deletions(-) delete mode 100644 include/aidge/operator/Scaling.hpp delete mode 100644 python_binding/operator/pybind_Scaling.cpp rename src/operator/MetaOperatorDefs/{Scaling.cpp => PTQMetaOps.cpp} (69%) delete mode 100644 src/operator/Scaling.cpp diff --git a/include/aidge/aidge.hpp b/include/aidge/aidge.hpp index 6088cf31c..e062fd2e2 100644 --- a/include/aidge/aidge.hpp +++ b/include/aidge/aidge.hpp @@ -69,7 +69,6 @@ #include "aidge/operator/Resize.hpp" #include "aidge/operator/Round.hpp" #include "aidge/operator/Shape.hpp" -#include "aidge/operator/Scaling.hpp" #include "aidge/operator/Slice.hpp" #include "aidge/operator/Softmax.hpp" #include "aidge/operator/Split.hpp" diff --git a/include/aidge/operator/MetaOperatorDefs.hpp b/include/aidge/operator/MetaOperatorDefs.hpp index b046e6e8b..bc5c6739c 100644 --- a/include/aidge/operator/MetaOperatorDefs.hpp +++ b/include/aidge/operator/MetaOperatorDefs.hpp @@ -167,17 +167,51 @@ std::shared_ptr<Node> LSTM(DimSize_t in_channels, std::shared_ptr<MetaOperator_Op> LSTM_Op(DimSize_t seq_length); //////////////////////////////////////////////////////////////////////////////// -//Helper Function to retrieve and update SF from MulPTQ node -//May be useful to -bool UpdateScalingNode_ScalingFactor(std::shared_ptr<Aidge::Node> Node, float newScalingFactor); -float GetScalingNode_Scaling_Factor(std::shared_ptr<Aidge::Node> Node); -bool setScalingMetaClipRange(std::shared_ptr<Aidge::Node> ScalingMetaNode,float min, float max); -std::pair<float&,float&> getMinMaxRefClip(std::shared_ptr<Aidge::Node> ScalingMetaNode); - +/// @brief ScalingMeta acts as a meta-operator to handle scaling operations in the PTQ, replacing the Scaling Operator. +/// This operator is composed of a sequence of [Mul] -> [Clip] -> [Round] operations. +/// +/// @param scalingFactor The scaling factor to apply to the input (essentially a scalar to multiply the input with). +/// @param clip_min The minimum value for the clip operation. +/// @param clip_max The maximum value for the clip operation. +/// @param name The name of the meta-operator node created. +/// @return A shared pointer to an instance of the meta-operator node. std::shared_ptr<Aidge::Node> ScalingMeta(float scalingFactor, float clip_min,float clip_max,const std::string& name); +/// @brief The purpose of MulPTQ is to encapsulate the Mul operator and tag it as a PTQ node rather than a regular Mul operator. +/// Therefore, this meta-operator consists solely of a [Mul] operation. +/// +/// @param scalingFactor The scaling factor to apply to the input (a scalar to multiply the input with). +/// @param name The name of the meta-operator node created. +/// @return A shared pointer to an instance of the MulPTQ node. std::shared_ptr<Aidge::Node> MulPTQ(float scalingFactor,const std::string& name = ""); +/// @brief Updates the scaling factor of a PTQ meta-operator node, allowing for dynamic adjustment of the scaling parameter. +/// This function sets a new scaling factor for a specified meta-operator node, modifying the scalar applied in the [Mul] operation. +/// The meta-operator node must be a PTQ-specific operator, such as a ScalingMeta or MulPTQ node. +/// +/// @param MetaOpNode A shared pointer to the PTQ meta-operator node whose scaling factor will be updated. +/// @param newScalingFactor The new scaling factor to apply to the meta-operator node. +/// @return True if the scaling factor was successfully updated, false if the operation failed (e.g., if MetaOpNode is null or incompatible). +bool updatePTQMetaOpsScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode, float newScalingFactor); + +/// @brief Retrieves the current scaling factor of a PTQ meta-operator node. +/// This function returns the scaling factor associated with the specified PTQ meta-operator node, +/// allowing inspection of the current scalar applied in the [Mul] operation. +/// +/// @param MetaOpNode A shared pointer to the PTQ meta-operator node whose scaling factor is being queried. +/// @return The scaling factor currently applied to the meta-operator node, or -1 if the operation fails (e.g., if MetaOpNode is null or incompatible). +float getPTQMetaOpsScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode); + +/// @brief Sets the clip range for an existing ScalingMeta node by specifying minimum and maximum clipping values. +/// This function modifies the clip range of a ScalingMeta node, allowing adjustment of the range within which values are clipped +/// in the [Clip] operation of the ScalingMeta sequence. +/// +/// @param ScalingMetaNode A shared pointer to the ScalingMeta node whose clip range is being set. +/// This node should have been created using the ScalingMeta function. +/// @param min The minimum value for the clip range. Values below this will be clipped to this minimum. +/// @param max The maximum value for the clip range. Values above this will be clipped to this maximum. +/// @return True if the clip range was successfully set, false if the operation failed (e.g., if ScalingMetaNode is null). +bool setScalingMetaClipRange(std::shared_ptr<Aidge::Node> ScalingMetaNode, float min, float max); } // namespace Aidge diff --git a/include/aidge/operator/Scaling.hpp b/include/aidge/operator/Scaling.hpp deleted file mode 100644 index 4ef39f63a..000000000 --- a/include/aidge/operator/Scaling.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 CEA-List - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - ********************************************************************************/ - -#ifndef AIDGE_CORE_OPERATOR_SCALING_H_ -#define AIDGE_CORE_OPERATOR_SCALING_H_ - -#include <cstddef> // std::size_t -#include <vector> -#include <memory> - -#include "aidge/backend/OperatorImpl.hpp" -#include "aidge/graph/Node.hpp" -#include "aidge/operator/OperatorTensor.hpp" -#include "aidge/utils/Registrar.hpp" -#include "aidge/utils/StaticAttributes.hpp" -#include "aidge/utils/Types.h" - -namespace Aidge { -enum class ScalingAttr { - ScalingFactor, QuantizedNbBits, IsOutputUnsigned -}; - -class Scaling_Op - : public OperatorTensor, - public Registrable<Scaling_Op, std::string, std::function<std::shared_ptr<OperatorImpl>(const Scaling_Op&)>> { -public: - static const std::string Type; - -private: - using Attributes_ = StaticAttributes<ScalingAttr, float, std::size_t, bool>; - template <ScalingAttr e> using attr = typename Attributes_::template attr<e>; - const std::shared_ptr<Attributes_> mAttributes; - -public: - Scaling_Op() = delete; - - Scaling_Op(float scalingFactor, std::size_t nbBits, bool isOutputUnsigned); - - /** - * @brief Copy-constructor. Copy the operator attributes and its output tensor(s), but not its input tensors (the new operator has no input associated). - * @param op Operator to copy. - */ - Scaling_Op(const Scaling_Op& op); - - /** - * @brief Clone the operator using its copy-constructor. - * @see Operator::Scaling_Op - */ - std::shared_ptr<Operator> clone() const override; - - void setBackend(const std::string& name, DeviceIdx_t device = 0) override final; - std::set<std::string> getAvailableBackends() const override; - - inline std::shared_ptr<Attributes> attributes() const override { return mAttributes; } - inline float& scalingFactor() const noexcept { return mAttributes -> getAttr<ScalingAttr::ScalingFactor>(); } - inline std::size_t& quantizedNbBits() const noexcept { return mAttributes -> getAttr<ScalingAttr::QuantizedNbBits>(); } - inline bool& isOutputUnsigned() const noexcept { return mAttributes -> getAttr<ScalingAttr::IsOutputUnsigned>(); } - - static const std::vector<std::string> getInputsName() { - return {"data_input"}; - } - static const std::vector<std::string> getOutputsName() { - return {"data_output"}; - } -}; - -/* -inline std::shared_ptr<Node> Scaling(float scalingFactor = 1.0f, const std::string& name = "") { - return std::make_shared<Node>(std::make_shared<Scaling_Op>(scalingFactor), name); -} -*/ -std::shared_ptr<Node> Scaling(float scalingFactor = 1.0f, - std::size_t quantizedNbBits=8, - bool isOutputUnsigned=true, - const std::string& name = ""); -} // namespace Aidge - -namespace { -template <> -const char* const EnumStrings<Aidge::ScalingAttr>::data[] - = {"scaling_factor", "quantized_nb_bits", "is_output_unsigned"}; -} - -#endif /* AIDGE_CORE_OPERATOR_SCALING_H_ */ diff --git a/python_binding/operator/pybind_Scaling.cpp b/python_binding/operator/pybind_Scaling.cpp deleted file mode 100644 index 22e8011a9..000000000 --- a/python_binding/operator/pybind_Scaling.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2024 CEA-List - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - ********************************************************************************/ - -#include <pybind11/pybind11.h> - -#include "aidge/data/Tensor.hpp" -#include "aidge/operator/Scaling.hpp" -#include "aidge/operator/OperatorTensor.hpp" - -namespace py = pybind11; - -namespace Aidge { - -void init_Scaling(py::module& m) -{ - py::class_<Scaling_Op, std::shared_ptr<Scaling_Op>, OperatorTensor>(m, "ScalingOp", py::multiple_inheritance()) - .def(py::init<float, size_t, bool>(), py::arg("scaling_factor"), py::arg("nb_bits"), py::arg("is_output_unsigned")) - .def_static("get_inputs_name", &Scaling_Op::getInputsName) - .def_static("get_outputs_name", &Scaling_Op::getOutputsName) - .def_readonly_static("Type", &Scaling_Op::Type); - declare_registrable<Scaling_Op>(m, "ScalingOp"); - m.def("Scaling", &Scaling, py::arg("scaling_factor") = 1.0f, py::arg("nb_bits") = 8, py::arg("is_output_unsigned") = true, py::arg("name") = ""); -} - -} // namespace Aidge diff --git a/python_binding/pybind_core.cpp b/python_binding/pybind_core.cpp index 02f4b732c..e8b9ac44f 100644 --- a/python_binding/pybind_core.cpp +++ b/python_binding/pybind_core.cpp @@ -66,7 +66,6 @@ void init_ReduceSum(py::module&); void init_Reshape(py::module&); void init_Resize(py::module&); void init_Round(py::module&); -void init_Scaling(py::module&); void init_Shape(py::module&); void init_Sigmoid(py::module&); void init_Slice(py::module&); @@ -155,7 +154,6 @@ void init_Aidge(py::module& m) { init_Reshape(m); init_Resize(m); init_Round(m); - init_Scaling(m); init_Shape(m); init_Sigmoid(m); init_Slice(m); diff --git a/src/operator/MetaOperatorDefs/Scaling.cpp b/src/operator/MetaOperatorDefs/PTQMetaOps.cpp similarity index 69% rename from src/operator/MetaOperatorDefs/Scaling.cpp rename to src/operator/MetaOperatorDefs/PTQMetaOps.cpp index d4dab5d3b..c5ab039ac 100644 --- a/src/operator/MetaOperatorDefs/Scaling.cpp +++ b/src/operator/MetaOperatorDefs/PTQMetaOps.cpp @@ -18,7 +18,6 @@ //Operator #include "aidge/operator/Clip.hpp" #include "aidge/operator/Mul.hpp" -#include "aidge/operator/BitShift.hpp" #include "aidge/operator/Round.hpp" #include "aidge/graph/Node.hpp" @@ -28,17 +27,49 @@ #include "aidge/utils/ArrayHelpers.hpp" #include "aidge/utils/Types.h" #include "aidge/operator/Identity.hpp" -//Legacy Functions getter/set for Scaling Factor +#include "aidge/data/Tensor.hpp" -bool Aidge::UpdateScalingNode_ScalingFactor(std::shared_ptr<Aidge::Node> Node, float newScalingFactor) +std::shared_ptr<Aidge::Node> Aidge::ScalingMeta(float scalingFactor, float clip_min,float clip_max,const std::string& name) { - if(Node->type() != "MulPTQ" && Node->type() != "ScalingMeta") + std::shared_ptr<Tensor> ScalingFactorTensorAttached = std::make_shared<Tensor>(Array1D<float, 1>{scalingFactor}); + std::shared_ptr<Aidge::Node> mul_node = Mul((!name.empty()) ? name + "_MulPTQ" : ""); + + std::shared_ptr<Aidge::Node> producer_scaling_factor = addProducer(mul_node,1,{1},"ScalingFactor"); + producer_scaling_factor ->getOperator()->setOutput(0,ScalingFactorTensorAttached); + + std::shared_ptr<Aidge::GraphView> graph = Sequential({ + mul_node, + Clip((!name.empty()) ? name + "_ClipPTQ" : "",clip_min,clip_max), + Round((!name.empty()) ? name + "_RoundPTQ" : "")}); + + std::shared_ptr<Aidge::GraphView> connectedGV = getConnectedGraphView(mul_node); + std::shared_ptr<Aidge::Node> metaopNode = MetaOperator("ScalingMeta",connectedGV,{},name); + return metaopNode; +} + +std::shared_ptr<Aidge::Node> Aidge::MulPTQ(float scalingFactor,const std::string& name) +{ + std::shared_ptr<Tensor> ScalingFactorTensorAttached = std::make_shared<Tensor>(Array1D<float, 1>{scalingFactor}); + + std::shared_ptr<Aidge::Node> mul_node = Mul((!name.empty()) ? name + "_MulPTQ" : ""); + + std::shared_ptr<Aidge::Node> producer_scaling_factor = addProducer(mul_node,1,{1},"ScalingFactor"); + producer_scaling_factor->getOperator()->setOutput(0, ScalingFactorTensorAttached); + std::shared_ptr<Aidge::GraphView> graph = Sequential({mul_node}); + std::shared_ptr<Aidge::GraphView> connectedGV = getConnectedGraphView(mul_node); + Aidge::NodePtr metaopNode = MetaOperator("MulPTQ",connectedGV,{},name); + return metaopNode; +} + +bool Aidge::updatePTQMetaOpsScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode, float newScalingFactor) +{ + if(MetaOpNode->type() != "MulPTQ" && MetaOpNode->type() != "ScalingMeta") { - AIDGE_ASSERT("Cannot use UpdateMulPTQ_SF on Node of type {}", Node->type()); + AIDGE_ASSERT("Cannot use updatePTQMetaOpsScalingFactor on Node of type {}", MetaOpNode->type()); } std::shared_ptr<Tensor> newScalingFactorTensorAttached = std::make_shared<Tensor>(Array1D<float, 1>{newScalingFactor}); - std::shared_ptr<Aidge::MetaOperator_Op> MetaOp = std::static_pointer_cast<MetaOperator_Op>(Node->getOperator()); - std::set<Aidge::NodePtr> Meta_Op_Node_List = MetaOp->getMicroGraph()->getNodes(); //List of Node inside MulPTQ Metaop Node + std::shared_ptr<Aidge::MetaOperator_Op> MetaOp = std::static_pointer_cast<MetaOperator_Op>(MetaOpNode->getOperator()); + std::set<Aidge::NodePtr> Meta_Op_Node_List = MetaOp->getMicroGraph()->getNodes(); //List of Nodes inside PTQ Metaop Node for(std::shared_ptr<Aidge::Node> node : Meta_Op_Node_List) { if(node->type() == "Mul") @@ -47,19 +78,19 @@ bool Aidge::UpdateScalingNode_ScalingFactor(std::shared_ptr<Aidge::Node> Node, f return true; } } - AIDGE_ASSERT("Invalid MetaOperator MulPTQ, no Mul node found inside node of type {}",Node->type()); + AIDGE_ASSERT("Invalid PTQ MetaOperator, no Mul node found inside node of type {}",MetaOpNode->type()); return false; } -float Aidge::GetScalingNode_Scaling_Factor(std::shared_ptr<Aidge::Node> Node) +float Aidge::getPTQMetaOpsScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode) { - if(Node->type() != "MulPTQ" && Node->type() != "ScalingMeta") + if(MetaOpNode->type() != "MulPTQ" && MetaOpNode->type() != "ScalingMeta") { - AIDGE_ASSERT("Cannot use GetScalingNode_Scaling_Factor on Node of type {}",Node->type()); + AIDGE_ASSERT("Cannot use getPTQMetaOpsScalingFactor on Node of type {}",MetaOpNode->type()); return -1; } - std::shared_ptr<Aidge::MetaOperator_Op> MetaOp = std::static_pointer_cast<MetaOperator_Op>(Node->getOperator()); - std::set<Aidge::NodePtr> Meta_Op_Node_List = MetaOp->getMicroGraph()->getNodes(); //List of Node inside MulPTQ Metaop Node + std::shared_ptr<Aidge::MetaOperator_Op> MetaOp = std::static_pointer_cast<MetaOperator_Op>(MetaOpNode->getOperator()); + std::set<Aidge::NodePtr> Meta_Op_Node_List = MetaOp->getMicroGraph()->getNodes(); //List of Nodes inside PTQ Metaop Node for(std::shared_ptr<Aidge::Node> node : Meta_Op_Node_List) { if(node->type() == "Mul") @@ -69,29 +100,9 @@ float Aidge::GetScalingNode_Scaling_Factor(std::shared_ptr<Aidge::Node> Node) return (*(static_cast<float*>(RawInputScalingFactor))); } } - AIDGE_ASSERT("Invalid MetaOperator Node, no Mul node found inside node of type {}",Node->type()); + AIDGE_ASSERT("Invalid PTQ MetaOperator, no Mul node found inside node of type {}",MetaOpNode->type()); return -1; } -/* -std::pair<float&,float&> Aidge::getMinMaxRefClip(std::shared_ptr<Aidge::Node> ScalingMetaNode) -{ - if(ScalingMetaNode->type() != "ScalingMeta") - { - AIDGE_ASSERT("Cannot use getMinMaxRefClip on Node of type {}",ScalingMetaNode->type()); - } - std::shared_ptr<Aidge::MetaOperator_Op> MetaOp = std::static_pointer_cast<MetaOperator_Op>(ScalingMetaNode->getOperator()); - std::set<Aidge::NodePtr> Meta_Op_Node_List = MetaOp->getMicroGraph()->getNodes(); //List of Node inside MulPTQ Metaop Node - for(std::shared_ptr<Aidge::Node> node : Meta_Op_Node_List) - { - if(node->type() == "Clip") - { - std::shared_ptr<Clip_Op> Clip_Node_Op = std::static_pointer_cast<Clip_Op>(node->getOperator()); - return std::make_pair(std::ref(Clip_Node_Op->min()),std::ref(Clip_Node_Op->max())); - } - } - AIDGE_ASSERT("Invalid MetaOperator ScalingMeta, no Clip node found inside Node of type {}",ScalingMetaNode->type()); -}*/ - bool Aidge::setScalingMetaClipRange(std::shared_ptr<Aidge::Node> ScalingMetaNode,float min, float max) { @@ -114,37 +125,4 @@ bool Aidge::setScalingMetaClipRange(std::shared_ptr<Aidge::Node> ScalingMetaNode } AIDGE_ASSERT("Invalid MetaOperator MulPTQ, no Mul node found inside Node of type {}",ScalingMetaNode->type()); return false; -} - -std::shared_ptr<Aidge::Node> Aidge::ScalingMeta(float scalingFactor, float clip_min,float clip_max,const std::string& name) -{ - std::shared_ptr<Tensor> ScalingFactorTensorAttached = std::make_shared<Tensor>(Array1D<float, 1>{scalingFactor}); - std::shared_ptr<Aidge::Node> mul_node = Mul((!name.empty()) ? name + "_MulPTQ" : ""); - - std::shared_ptr<Aidge::Node> producer_scaling_factor = addProducer(mul_node,1,{1},"ScalingFactor"); - producer_scaling_factor ->getOperator()->setOutput(0,ScalingFactorTensorAttached); - - std::shared_ptr<Aidge::GraphView> graph = Sequential({ - mul_node, - Clip((!name.empty()) ? name + "_ClipPTQ" : "",clip_min,clip_max), - Round((!name.empty()) ? name + "_RoundPTQ" : "")}); - - std::shared_ptr<Aidge::GraphView> connectedGV = getConnectedGraphView(mul_node); - std::shared_ptr<Aidge::Node> metaopNode = MetaOperator("ScalingMeta",connectedGV,{},name); - return metaopNode; -} - -// The only purpose of MulPTQ is to encapsulate the Mul operator in order to tag it (as a PTQ node and not an ordinary Mul). -std::shared_ptr<Aidge::Node> Aidge::MulPTQ(float scalingFactor,const std::string& name) -{ - std::shared_ptr<Tensor> ScalingFactorTensorAttached = std::make_shared<Tensor>(Array1D<float, 1>{scalingFactor}); - - std::shared_ptr<Aidge::Node> mul_node = Mul((!name.empty()) ? name + "_MulPTQ" : ""); - - std::shared_ptr<Aidge::Node> producer_scaling_factor = addProducer(mul_node,1,{1},"ScalingFactor"); - producer_scaling_factor->getOperator()->setOutput(0, ScalingFactorTensorAttached); - std::shared_ptr<Aidge::GraphView> graph = Sequential({mul_node}); - std::shared_ptr<Aidge::GraphView> connectedGV = getConnectedGraphView(mul_node); - Aidge::NodePtr metaopNode = MetaOperator("MulPTQ",connectedGV,{},name); - return metaopNode; -} +} \ No newline at end of file diff --git a/src/operator/Scaling.cpp b/src/operator/Scaling.cpp deleted file mode 100644 index 5ac08cd22..000000000 --- a/src/operator/Scaling.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 CEA-List - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - ********************************************************************************/ - -#include "aidge/operator/Scaling.hpp" - -#include <memory> -#include <string> - -#include "aidge/data/Tensor.hpp" -#include "aidge/utils/Registrar.hpp" -#include "aidge/utils/Types.h" - -const std::string Aidge::Scaling_Op::Type = "Scaling"; - -Aidge::Scaling_Op::Scaling_Op(float scalingFactor, std::size_t nbBits, bool isOutputUnsigned) - : OperatorTensor(Type, {InputCategory::Data}, 1), - mAttributes(std::make_shared<Attributes_>( - attr<ScalingAttr::ScalingFactor>(scalingFactor), - attr<ScalingAttr::QuantizedNbBits>(nbBits), - attr<ScalingAttr::IsOutputUnsigned>(isOutputUnsigned))) -{} - -Aidge::Scaling_Op::Scaling_Op(const Aidge::Scaling_Op& op) - : OperatorTensor(op), - mAttributes(op.mAttributes) -{ - if (op.mImpl){ - SET_IMPL_MACRO(Scaling_Op, *this, op.backend()); - } else { - mImpl = nullptr; - } -} - -std::shared_ptr<Aidge::Operator> Aidge::Scaling_Op::clone() const { - return std::make_shared<Scaling_Op>(*this); -} - -void Aidge::Scaling_Op::setBackend(const std::string& name, Aidge::DeviceIdx_t device) { - SET_IMPL_MACRO(Scaling_Op, *this, name); - mOutputs[0]->setBackend(name, device); -} - -std::set<std::string> Aidge::Scaling_Op::getAvailableBackends() const { - return Registrar<Scaling_Op>::getKeys(); -} - -//////////////////////////////////////////////// - -std::shared_ptr<Aidge::Node> Aidge::Scaling(float scalingFactor, - std::size_t quantizedNbBits, - bool isOutputUnsigned, - const std::string& name) -{ - return std::make_shared<Node>(std::make_shared<Scaling_Op>(scalingFactor,quantizedNbBits, isOutputUnsigned), name); -} \ No newline at end of file -- GitLab