umd/core/src/compiler/engine-ast/EngineAST.cpp
static NvDlaError prependScaleOpForRescaling
(
    engine_ast::Graph *engGraph,
    canonical_ast::Node *canNode,
    engine_ast::Graph::EdgeSequence engSrcEdges,
    engine_ast::Graph::EdgeSequence engSinkEdges,
    engine_ast::Graph::NodeSequence& transformedEngNodes
)
{
    NvDlaError e = NvDlaSuccess;

    engine_ast::SDPScaleOpNode* engSDPScaleNode = NULL;
    surface::SurfacePrecision computePrecision  = engGraph->profile()->computePrecision();
    engine_ast::Edge* engSrcEdge                = NULL;
    engine_ast::Edge* scaleSinkEdge             = NULL;

    Tensor* inTensor = NULL;
    Tensor* outTensor = NULL;

    Dims4 scaleDims;
    engine_ast::SDPMode scaleMode = engine_ast::SDPModeEnum::SDP_MODE_PER_CHANNEL; // Force it to per-channel

    if (engSrcEdges.size() != 1 || engSinkEdges.size() != 1)
    {
        ORIGINATE_ERROR_FAIL(NvDlaError_NotSupported, "Don't support Activation operation with input edges (%d) != 1 or "
                                                   "output edges (%d) != 1", engSrcEdges.size(), engSinkEdges.size());
    }

    if (computePrecision.v() != surface::SurfacePrecisionEnum::NVDLA_PRECISION_INT8)
    {
        /* Rescaling applicable for only int8 */
        goto fail;
    }

    /* Create a new sdp node */
    engSDPScaleNode = engine_ast::NodeFactory::newSDPScaleOpNode(NULL, engGraph);

    /* Create an output tensor for newscale node and uses the same as that next canNode */
    outTensor = canNode->outputEdges().at(0)->originalTensor()->clone();
    outTensor->setTensorType(TensorType::kIO);

    /* Determine the scaling dimension based on scale mode */
    inTensor = canNode->inputEdges().at(0)->originalTensor();
    scaleDims.n = 1;
    scaleDims.c = inTensor->getDimensions().c;
    scaleDims.h = 1;
    scaleDims.w = 1;

    /* Update the params of engScaleNode. */
    engSDPScaleNode->populateWithUnitScaleParams(scaleMode, scaleDims);

    /* create an new edge from output of scale to input of canNode */
    engSrcEdge  = engSrcEdges[0];
    scaleSinkEdge = engGraph->addDataEdge((engine_ast::Edge*)0,
                            (engine_ast::Node*)0,
                            (engine_ast::Node*)0,
                            outTensor);
    engGraph->appendNodeToEdge(engSrcEdge, ast::EdgeSideEnum::SECOND, engSDPScaleNode);
    engGraph->appendNodeToEdge(scaleSinkEdge, ast::EdgeSideEnum::FIRST, engSDPScaleNode);

    PROPAGATE_ERROR_FAIL(engSDPScaleNode->populateEdgePorts());
    transformedEngNodes.push_back(engSDPScaleNode);
fail:
    return e;
}
/**
 * Attaches unit scale op before given node to handle rescaling.
 *
 * This function is useful whenever a node doesn't want to do rescaling within itself
 *  (like ReLU).
 *
 * For instance say NodeA doesn't want to handle its rescaling (just to avoid complexity)
 *  input scaling factor NodeA (say ReLU)  = Si
 *  output scaling factor NodeA (say ReLU) = So
 *
 * Conversion:
 *  ReLU  = unit scale node(per-channel) + ReLU
 *  Where,
 *      input scaling factor of unit scale node  = Si
 *      output scaling factor of unit scale node/input scaling factor of ReLU  = So
 *      output scaling factor of ReLU = So
 *
 * This would introduce new unit scale node (per-channel) that handles rescaling and
 * NodeA is free from doing the same.
 *
 * CAUTION: This function does the rescaling before the actual operation (ReLU).
 *          Such rescaling is fine in cases like ReLU. To be used with care.
 *
 **/
Attaches unit scale op before given node to handle rescaling.
This function is useful whenever a node doesn't want to do rescaling within itself
(like ReLU).

For instance say NodeA doesn't want to handle its rescaling (just to avoid complexity)
input scaling factor NodeA (say ReLU)  = Si
output scaling factor NodeA (say ReLU) = So

ReLU  = unit scale node(per-channel) + ReLU
Where,
input scaling factor of unit scale node  = Si
output scaling factor of unit scale node/input scaling factor of ReLU  = So
output scaling factor of ReLU = So

This would introduce new unit scale node (per-channel) that handles rescaling and
NodeA is free from doing the same.

This function does the rescaling before the actual operation (ReLU).
Such rescaling is fine in cases like ReLU. To be used with care.
Attaches unit scale op before given node to handle rescaling . This function is useful whenever a node doesn ' t want to do rescaling within itself ( like ReLU ) . For instance say NodeA doesn ' t want to handle its rescaling ( just to avoid complexity ) input scaling factor NodeA ( say ReLU ) = Si output scaling factor NodeA ( say ReLU ) = So ReLU = unit scale node ( per - channel ) + ReLU Where input scaling factor of unit scale node = Si output scaling factor of unit scale node / input scaling factor of ReLU = So output scaling factor of ReLU = So This would introduce new unit scale node ( per - channel ) that handles rescaling and NodeA is free from doing the same . This function does the rescaling before the actual operation ( ReLU ) . Such rescaling is fine in cases like ReLU . To be used with care .
static NvDlaError prependScaleOpForRescaling
(
    engine_ast::Graph *engGraph,
    canonical_ast::Node *canNode,
    engine_ast::Graph::EdgeSequence engSrcEdges,
    engine_ast::Graph::EdgeSequence engSinkEdges,
    engine_ast::Graph::NodeSequence& transformedEngNodes
)
{
    NvDlaError e = NvDlaSuccess;
    engine_ast::SDPScaleOpNode* engSDPScaleNode = NULL;
    surface::SurfacePrecision computePrecision  = engGraph->profile()->computePrecision();
    engine_ast::Edge* engSrcEdge                = NULL;
    engine_ast::Edge* scaleSinkEdge             = NULL;
    Tensor* inTensor = NULL;
    Tensor* outTensor = NULL;
    Dims4 scaleDims;
    engine_ast::SDPMode scaleMode = engine_ast::SDPModeEnum::SDP_MODE_PER_CHANNEL; 
    if (engSrcEdges.size() != 1 || engSinkEdges.size() != 1)
    {
        ORIGINATE_ERROR_FAIL(NvDlaError_NotSupported, "Don't support Activation operation with input edges (%d) != 1 or "
                                                   "output edges (%d) != 1", engSrcEdges.size(), engSinkEdges.size());
    }
    if (computePrecision.v() != surface::SurfacePrecisionEnum::NVDLA_PRECISION_INT8)
    {
        goto fail;
    }
    engSDPScaleNode = engine_ast::NodeFactory::newSDPScaleOpNode(NULL, engGraph);
    outTensor = canNode->outputEdges().at(0)->originalTensor()->clone();
    outTensor->setTensorType(TensorType::kIO);
    inTensor = canNode->inputEdges().at(0)->originalTensor();
    scaleDims.n = 1;
    scaleDims.c = inTensor->getDimensions().c;
    scaleDims.h = 1;
    scaleDims.w = 1;
    engSDPScaleNode->populateWithUnitScaleParams(scaleMode, scaleDims);
    engSrcEdge  = engSrcEdges[0];
    scaleSinkEdge = engGraph->addDataEdge((engine_ast::Edge*)0,
                            (engine_ast::Node*)0,
                            (engine_ast::Node*)0,
                            outTensor);
    engGraph->appendNodeToEdge(engSrcEdge, ast::EdgeSideEnum::SECOND, engSDPScaleNode);
    engGraph->appendNodeToEdge(scaleSinkEdge, ast::EdgeSideEnum::FIRST, engSDPScaleNode);
    PROPAGATE_ERROR_FAIL(engSDPScaleNode->populateEdgePorts());
    transformedEngNodes.push_back(engSDPScaleNode);
fail:
    return e;
}
static NvDlaError prependScaleOpForRescaling ( engine_ast :: Graph * engGraph , canonical_ast :: Node * canNode , engine_ast :: Graph :: EdgeSequence engSrcEdges , engine_ast :: Graph :: EdgeSequence engSinkEdges , engine_ast :: Graph :: NodeSequence & transformedEngNodes ) { NvDlaError e = NvDlaSuccess ; engine_ast :: SDPScaleOpNode * engSDPScaleNode = NULL ; surface :: SurfacePrecision computePrecision = engGraph -> profile ( ) -> computePrecision ( ) ; engine_ast :: Edge * engSrcEdge = NULL ; engine_ast :: Edge * scaleSinkEdge = NULL ; Tensor * inTensor = NULL ; Tensor * outTensor = NULL ; Dims4 scaleDims ; engine_ast :: SDPMode scaleMode = engine_ast :: SDPModeEnum :: SDP_MODE_PER_CHANNEL ; if ( engSrcEdges . size ( ) != 1 || engSinkEdges . size ( ) != 1 ) { ORIGINATE_ERROR_FAIL ( NvDlaError_NotSupported , " " " " , engSrcEdges . size ( ) , engSinkEdges . size ( ) ) ; } if ( computePrecision . v ( ) != surface :: SurfacePrecisionEnum :: NVDLA_PRECISION_INT8 ) { goto fail ; } engSDPScaleNode = engine_ast :: NodeFactory :: newSDPScaleOpNode ( NULL , engGraph ) ; outTensor = canNode -> outputEdges ( ) . at ( 0 ) -> originalTensor ( ) -> clone ( ) ; outTensor -> setTensorType ( TensorType :: kIO ) ; inTensor = canNode -> inputEdges ( ) . at ( 0 ) -> originalTensor ( ) ; scaleDims . n = 1 ; scaleDims . c = inTensor -> getDimensions ( ) . c ; scaleDims . h = 1 ; scaleDims . w = 1 ; engSDPScaleNode -> populateWithUnitScaleParams ( scaleMode , scaleDims ) ; engSrcEdge = engSrcEdges [ 0 ] ; scaleSinkEdge = engGraph -> addDataEdge ( ( engine_ast :: Edge * ) 0 , ( engine_ast :: Node * ) 0 , ( engine_ast :: Node * ) 0 , outTensor ) ; engGraph -> appendNodeToEdge ( engSrcEdge , ast :: EdgeSideEnum :: SECOND , engSDPScaleNode ) ; engGraph -> appendNodeToEdge ( scaleSinkEdge , ast :: EdgeSideEnum :: FIRST , engSDPScaleNode ) ; PROPAGATE_ERROR_FAIL ( engSDPScaleNode -> populateEdgePorts ( ) ) ; transformedEngNodes . push_back ( engSDPScaleNode ) ; fail : return e ; }
Attaches unit scale op before given node to handle rescaling.
Attaches unit scale op before given node to handle rescaling .
// Force it to per-channel /* Rescaling applicable for only int8 */ /* Create a new sdp node */ /* Create an output tensor for newscale node and uses the same as that next canNode */ /* Determine the scaling dimension based on scale mode */ /* Update the params of engScaleNode. */ /* create an new edge from output of scale to input of canNode */