diff --git a/include/aidge/operator/MetaOperatorDefs.hpp b/include/aidge/operator/MetaOperatorDefs.hpp index 2da9348de6ef2c4b3c0657c5b91765ece7dd4977..b046e6e8bce05296c6d0e897535b8c5028bea4e1 100644 --- a/include/aidge/operator/MetaOperatorDefs.hpp +++ b/include/aidge/operator/MetaOperatorDefs.hpp @@ -15,6 +15,7 @@ #include <array> #include <memory> #include <string> +#include <utility> #include "aidge/graph/GraphView.hpp" #include "aidge/graph/Node.hpp" @@ -165,16 +166,18 @@ std::shared_ptr<Node> LSTM(DimSize_t in_channels, std::shared_ptr<MetaOperator_Op> LSTM_Op(DimSize_t seq_length); //////////////////////////////////////////////////////////////////////////////// -bool UpdateMulPTQ_SF(std::shared_ptr<Aidge::Node> MulPTQNode,float newScalingFactor); -float GetMulPTQ_SF(std::shared_ptr<Aidge::Node> MulPTQNode); -std::shared_ptr<Node> ScalingMeta(float scalingFactor, std::size_t nbBits, bool isOutputUnsigned,const std::string& name = ""); +//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); -std::shared_ptr<MetaOperator_Op> ScalingMeta_Op(float scalingFactor, std::size_t nbBits, bool isOutputUnsigned); +std::shared_ptr<Aidge::Node> ScalingMeta(float scalingFactor, float clip_min,float clip_max,const std::string& name); std::shared_ptr<Aidge::Node> MulPTQ(float scalingFactor,const std::string& name = ""); -std::shared_ptr<Aidge::MetaOperator_Op> MulPTQ_Op(float scalingFactor); } // namespace Aidge diff --git a/src/operator/MetaOperatorDefs/Scaling.cpp b/src/operator/MetaOperatorDefs/Scaling.cpp index c829dd81990935f1141c0ea3a61e494193583d16..d4e1ad179ca32167c389ccc1d433cbb3bdffea1a 100644 --- a/src/operator/MetaOperatorDefs/Scaling.cpp +++ b/src/operator/MetaOperatorDefs/Scaling.cpp @@ -13,6 +13,7 @@ #include <array> #include <memory> +#include <utility> //Operator #include "aidge/operator/Clip.hpp" @@ -27,92 +28,123 @@ #include "aidge/utils/ArrayHelpers.hpp" #include "aidge/utils/Types.h" #include "aidge/operator/Identity.hpp" +//Legacy Functions getter/set for Scaling Factor -bool Aidge::UpdateMulPTQ_SF(std::shared_ptr<Aidge::Node> MulPTQNode, float newScalingFactor) +bool Aidge::UpdateScalingNode_ScalingFactor(std::shared_ptr<Aidge::Node> Node, float newScalingFactor) { - if(MulPTQNode->type() != "MulPTQ") + if(Node->type() != "MulPTQ" && Node->type() != "ScalingMeta") { - Log::notice("Cannot use UpdateMulPTQ_SF on Node of type {}",MulPTQNode->type()); - return false; + AIDGE_ASSERT("Cannot use UpdateMulPTQ_SF on Node of type {}", Node->type()); } - std::shared_ptr<Tensor> newScalingFactorTensorAttached = std::make_shared<Tensor>(Array1D<float, 1>{newScalingFactor}); - MulPTQNode->input(1).first->getOperator()->setOutput(0, newScalingFactorTensorAttached); - return true; + 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 + for(std::shared_ptr<Aidge::Node> node : Meta_Op_Node_List) + { + if(node->type() == "Mul") + { + node->input(1).first->getOperator()->setOutput(0, newScalingFactorTensorAttached); + return true; + } + } + AIDGE_ASSERT("Invalid MetaOperator MulPTQ, no Mul node found inside node of type {}",Node->type()); + return false; } -float Aidge::GetMulPTQ_SF(std::shared_ptr<Aidge::Node> MulPTQNode) + +float Aidge::GetScalingNode_Scaling_Factor(std::shared_ptr<Aidge::Node> Node) { - if(MulPTQNode->type() != "MulPTQ") + if(Node->type() != "MulPTQ" && Node->type() != "ScalingMeta") { - Log::notice("Cannot use GetMulPTQ_SF on Node of type {}",MulPTQNode->type()); + AIDGE_ASSERT("Cannot use GetScalingNode_Scaling_Factor on Node of type {}",Node->type()); return -1; } - auto t = MulPTQNode->input(1).first->getOperator()->getRawOutput(0); - auto v = std::static_pointer_cast<Tensor>(t)->getImpl()->rawPtr(); - return *(static_cast<float*>(v)); + 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 + for(std::shared_ptr<Aidge::Node> node : Meta_Op_Node_List) + { + if(node->type() == "Mul") + { + std::shared_ptr<Aidge::Data> MulInput1Data = node->input(1).first->getOperator()->getRawOutput(0); + void* RawInputScalingFactor = std::static_pointer_cast<Tensor>(MulInput1Data)->getImpl()->rawPtr(); + return (*(static_cast<float*>(RawInputScalingFactor))); + } + } + AIDGE_ASSERT("Invalid MetaOperator Node, no Mul node found inside node of type {}",Node->type()); + return -1; } - -std::shared_ptr<Aidge::Node> Aidge::ScalingMeta(float scalingFactor, std::size_t nbBits, bool isOutputUnsigned,const std::string& name) +/* +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()); +}*/ - std::shared_ptr<Tensor> ScalingFactorTensorAttached = std::make_shared<Tensor>(Array1D<float, 1>{scalingFactor}); - - float minv = isOutputUnsigned ? 0 : - -(1ll << (nbBits - 1ll)); - float maxv = isOutputUnsigned ? (1ll << nbBits) - 1ll : - (1ll << (nbBits - 1ll)) - 1ll; - auto mul_node = Mul((!name.empty()) ? name + "_MulPTQ" : ""); - addProducer(mul_node,1,{1},"ScalingFactor"); - mul_node->input(1).first->getOperator()->setOutput(0, ScalingFactorTensorAttached); - std::shared_ptr<Aidge::GraphView> graph = Sequential({ - mul_node, - Clip((!name.empty()) ? name + "_ClipPTQ" : "",minv,maxv), - Round((!name.empty()) ? name + "_RoundPTQ" : "")}); - auto connectedGV = getConnectedGraphView(mul_node); - std::shared_ptr<Aidge::Node> metaopNode = MetaOperator("ScalingMeta",connectedGV); - return metaopNode; +bool Aidge::setScalingMetaClipRange(std::shared_ptr<Aidge::Node> ScalingMetaNode,float min, float max) +{ + if(ScalingMetaNode->type() != "ScalingMeta") + { + AIDGE_ASSERT("Cannot use setScalingMetaClipRange on Node of type {}",ScalingMetaNode->type()); + return false; + } + 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()); + Clip_Node_Op->max() = max; + Clip_Node_Op->min() = min; + return true; + } + } + AIDGE_ASSERT("Invalid MetaOperator MulPTQ, no Mul node found inside Node of type {}",ScalingMetaNode->type()); + return false; } -std::shared_ptr<Aidge::MetaOperator_Op> Aidge::ScalingMeta_Op(float scalingFactor, std::size_t nbBits, bool isOutputUnsigned) +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" : ""); - float minv = isOutputUnsigned ? 0 : - -(1ll << (nbBits - 1ll)); - float maxv = isOutputUnsigned ? (1ll << nbBits) - 1ll : - (1ll << (nbBits - 1ll)) - 1ll; + 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::Node> mul = Mul(); - mul->getOperator()->associateInput(1,ScalingFactorTensorAttached); - std::shared_ptr<Aidge::GraphView> graph = Sequential({ - mul, - Clip("",minv,maxv), - Round()}); - return std::make_shared<MetaOperator_Op>("ScalingMeta",graph); + 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); + 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}); - auto mul_node = Mul((!name.empty()) ? name + "_MulPTQ" : ""); - addProducer(mul_node,1,{1},"ScalingFactor"); - mul_node->input(1).first->getOperator()->setOutput(0, ScalingFactorTensorAttached); + + 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}); - auto connectedGV = getConnectedGraphView(mul_node); + std::shared_ptr<Aidge::GraphView> connectedGV = getConnectedGraphView(mul_node); Aidge::NodePtr metaopNode = MetaOperator("MulPTQ",connectedGV); return metaopNode; } - -std::shared_ptr<Aidge::MetaOperator_Op> Aidge::MulPTQ_Op(float scalingFactor) -{ - std::shared_ptr<Tensor> ScalingFactorTensorAttached = std::make_shared<Tensor>(Array1D<float, 1>{scalingFactor}); - auto mul_node = Mul(""); - addProducer(mul_node,1,{1},"ScalingFactor"); - mul_node->input(1).first->getOperator()->setOutput(0, ScalingFactorTensorAttached); - std::shared_ptr<Aidge::GraphView> graph = Sequential({mul_node}); - auto connectedGV = getConnectedGraphView(mul_node); - return std::make_shared<MetaOperator_Op>("MulPTQ_OP",connectedGV); -}