umd/core/src/compiler/engine-ast/ScaleOp.cpp
NvDlaError engine_ast::SDPScaleOpNode::rescaleScaleDataForNoFusedConv()
{
    NvDlaError e = NvDlaSuccess;

    std::vector<NvF32> trnsFp32Scale;

    std::vector<NvF32> inTensorScales = inputEdges().at(0)->originalTensor()->getChannelScales();
    std::vector<NvF32> outTensorScales = outputEdges().at(0)->originalTensor()->getChannelScales();
    NvF32 perTensorInTensorScale = inTensorScales.at(0);
    NvF32 perTensorOutTensorScale = outTensorScales.at(0);

    Weights origScaleBlob = params().rawScaleData();
    Dims4 origScaleDims = params().scaleDims();

    Weights trnsScaleBlob = Weights(nvdla::DataType::FLOAT, NULL, 0);
    NvF32 *trnsScaleData = NULL;
    NvU32 trnsCnt = 0;

    // Preliminary checks
    ASSERT(inTensorScales.size() == (size_t)inputEdges().at(0)->tensorSurfaceDesc()->dimensions().c);
    for (NvF32 its = 1; its < inTensorScales.size(); ++its)
    {
        if ( perTensorInTensorScale != inTensorScales[its] )
        {
            ORIGINATE_ERROR_FAIL(NvDlaError_BadValue, "Channel scales should be same for input of %s when PER_TENSOR "
                                    "scaling is ON", name().c_str());
        }
    }

    ASSERT(outTensorScales.size() == (size_t)outputEdges().at(0)->tensorSurfaceDesc()->dimensions().c);
    for (NvF32 ots = 1; ots < outTensorScales.size(); ++ots)
    {
        if ( perTensorOutTensorScale != outTensorScales[ots] )
        {
            ORIGINATE_ERROR_FAIL(NvDlaError_BadValue, "Channel scales should be same for output of %s when PER_TENSOR "
                                    "scaling is ON", name().c_str());
        }
    }

    // Convert scale data into float and get it as vector
    trnsFp32Scale.clear();
    PROPAGATE_ERROR_FAIL(getFp32ScaleData(origScaleBlob, trnsFp32Scale));
    ASSERT(trnsFp32Scale.size() == (NvU32)origScaleBlob.count);

    trnsScaleData =
        reinterpret_cast<NvF32*>(
            engine_ast::MemoryCollector::getInstance()->allocateMemory(origScaleBlob.count * sizeof(NvF32))
        );

    for (NvS32 cc = 0; cc < origScaleDims.c; cc++)
    {
        for (NvS32 hh = 0; hh < origScaleDims.h; hh++)
        {
            for (NvS32 ww = 0; ww < origScaleDims.w; ww++)
            {
                NvU32 offset =  ww +
                                origScaleDims.w * ( hh +
                                origScaleDims.h * (cc) );
                trnsScaleData[offset] = ((trnsFp32Scale.at(offset) * perTensorInTensorScale) / perTensorOutTensorScale);
                trnsCnt++;
                if (graph()->debugQuantization())
                {
                    gLogInfo << name() << " rawScl * Si / So: " << trnsFp32Scale.at(offset)
                             << " * " << perTensorInTensorScale << " / "
                             << perTensorOutTensorScale << " = " << trnsScaleData[offset] << endl;
                }
            }
        }
    }

    trnsScaleBlob.type = nvdla::DataType::FLOAT;
    trnsScaleBlob.count = trnsCnt;
    trnsScaleBlob.values = trnsScaleData;

    params().setRawScaleData(trnsScaleBlob);

fail:
    return e;
}
/**
 * Converts raw scale data to NvF32 and rescales.
 * Rescaling applicable when sdp exists as standalone.
 *
 * Usecase
 * -------
 *         B = A op C
 * S_B * Q_B = (S_A * Q_A) op C
 *       Q_B = (Q_A * Q_W) * ((S_A op C) /S_B)
 *       Q_B = (Q_A * Q_W) * (2 ^ -m * n_i16[k'])
 *
 * Where Q_A, quantized int8 input to SDP
 *       Q_B, rescaled int8 output from SDP
 *       C,   actual scale data - PER_LAYER, PER_CHANNEL, PER_ELEMENT
 *
 * rescaleScaleDataForNoFusedConv computes (S_A op C)/S_B in fp32 precision
 * and overwrites existing raw scale data with it.
 **/
Converts raw scale data to NvF32 and rescales.
Rescaling applicable when sdp exists as standalone.

Usecase





rescaleScaleDataForNoFusedConv computes (S_A op C)/S_B in fp32 precision
and overwrites existing raw scale data with it.
Converts raw scale data to NvF32 and rescales . Rescaling applicable when sdp exists as standalone . Usecase rescaleScaleDataForNoFusedConv computes ( S_A op C ) / S_B in fp32 precision and overwrites existing raw scale data with it .
NvDlaError engine_ast::SDPScaleOpNode::rescaleScaleDataForNoFusedConv()
{
    NvDlaError e = NvDlaSuccess;
    std::vector<NvF32> trnsFp32Scale;
    std::vector<NvF32> inTensorScales = inputEdges().at(0)->originalTensor()->getChannelScales();
    std::vector<NvF32> outTensorScales = outputEdges().at(0)->originalTensor()->getChannelScales();
    NvF32 perTensorInTensorScale = inTensorScales.at(0);
    NvF32 perTensorOutTensorScale = outTensorScales.at(0);
    Weights origScaleBlob = params().rawScaleData();
    Dims4 origScaleDims = params().scaleDims();
    Weights trnsScaleBlob = Weights(nvdla::DataType::FLOAT, NULL, 0);
    NvF32 *trnsScaleData = NULL;
    NvU32 trnsCnt = 0;
    ASSERT(inTensorScales.size() == (size_t)inputEdges().at(0)->tensorSurfaceDesc()->dimensions().c);
    for (NvF32 its = 1; its < inTensorScales.size(); ++its)
    {
        if ( perTensorInTensorScale != inTensorScales[its] )
        {
            ORIGINATE_ERROR_FAIL(NvDlaError_BadValue, "Channel scales should be same for input of %s when PER_TENSOR "
                                    "scaling is ON", name().c_str());
        }
    }
    ASSERT(outTensorScales.size() == (size_t)outputEdges().at(0)->tensorSurfaceDesc()->dimensions().c);
    for (NvF32 ots = 1; ots < outTensorScales.size(); ++ots)
    {
        if ( perTensorOutTensorScale != outTensorScales[ots] )
        {
            ORIGINATE_ERROR_FAIL(NvDlaError_BadValue, "Channel scales should be same for output of %s when PER_TENSOR "
                                    "scaling is ON", name().c_str());
        }
    }
    trnsFp32Scale.clear();
    PROPAGATE_ERROR_FAIL(getFp32ScaleData(origScaleBlob, trnsFp32Scale));
    ASSERT(trnsFp32Scale.size() == (NvU32)origScaleBlob.count);
    trnsScaleData =
        reinterpret_cast<NvF32*>(
            engine_ast::MemoryCollector::getInstance()->allocateMemory(origScaleBlob.count * sizeof(NvF32))
        );
    for (NvS32 cc = 0; cc < origScaleDims.c; cc++)
    {
        for (NvS32 hh = 0; hh < origScaleDims.h; hh++)
        {
            for (NvS32 ww = 0; ww < origScaleDims.w; ww++)
            {
                NvU32 offset =  ww +
                                origScaleDims.w * ( hh +
                                origScaleDims.h * (cc) );
                trnsScaleData[offset] = ((trnsFp32Scale.at(offset) * perTensorInTensorScale) / perTensorOutTensorScale);
                trnsCnt++;
                if (graph()->debugQuantization())
                {
                    gLogInfo << name() << " rawScl * Si / So: " << trnsFp32Scale.at(offset)
                             << " * " << perTensorInTensorScale << " / "
                             << perTensorOutTensorScale << " = " << trnsScaleData[offset] << endl;
                }
            }
        }
    }
    trnsScaleBlob.type = nvdla::DataType::FLOAT;
    trnsScaleBlob.count = trnsCnt;
    trnsScaleBlob.values = trnsScaleData;
    params().setRawScaleData(trnsScaleBlob);
fail:
    return e;
}
NvDlaError engine_ast :: SDPScaleOpNode :: rescaleScaleDataForNoFusedConv ( ) { NvDlaError e = NvDlaSuccess ; std :: vector < NvF32 > trnsFp32Scale ; std :: vector < NvF32 > inTensorScales = inputEdges ( ) . at ( 0 ) -> originalTensor ( ) -> getChannelScales ( ) ; std :: vector < NvF32 > outTensorScales = outputEdges ( ) . at ( 0 ) -> originalTensor ( ) -> getChannelScales ( ) ; NvF32 perTensorInTensorScale = inTensorScales . at ( 0 ) ; NvF32 perTensorOutTensorScale = outTensorScales . at ( 0 ) ; Weights origScaleBlob = params ( ) . rawScaleData ( ) ; Dims4 origScaleDims = params ( ) . scaleDims ( ) ; Weights trnsScaleBlob = Weights ( nvdla :: DataType :: FLOAT , NULL , 0 ) ; NvF32 * trnsScaleData = NULL ; NvU32 trnsCnt = 0 ; ASSERT ( inTensorScales . size ( ) == ( size_t ) inputEdges ( ) . at ( 0 ) -> tensorSurfaceDesc ( ) -> dimensions ( ) . c ) ; for ( NvF32 its = 1 ; its < inTensorScales . size ( ) ; ++ its ) { if ( perTensorInTensorScale != inTensorScales [ its ] ) { ORIGINATE_ERROR_FAIL ( NvDlaError_BadValue , " " " " , name ( ) . c_str ( ) ) ; } } ASSERT ( outTensorScales . size ( ) == ( size_t ) outputEdges ( ) . at ( 0 ) -> tensorSurfaceDesc ( ) -> dimensions ( ) . c ) ; for ( NvF32 ots = 1 ; ots < outTensorScales . size ( ) ; ++ ots ) { if ( perTensorOutTensorScale != outTensorScales [ ots ] ) { ORIGINATE_ERROR_FAIL ( NvDlaError_BadValue , " " " " , name ( ) . c_str ( ) ) ; } } trnsFp32Scale . clear ( ) ; PROPAGATE_ERROR_FAIL ( getFp32ScaleData ( origScaleBlob , trnsFp32Scale ) ) ; ASSERT ( trnsFp32Scale . size ( ) == ( NvU32 ) origScaleBlob . count ) ; trnsScaleData = reinterpret_cast < NvF32 * > ( engine_ast :: MemoryCollector :: getInstance ( ) -> allocateMemory ( origScaleBlob . count * sizeof ( NvF32 ) ) ) ; for ( NvS32 cc = 0 ; cc < origScaleDims . c ; cc ++ ) { for ( NvS32 hh = 0 ; hh < origScaleDims . h ; hh ++ ) { for ( NvS32 ww = 0 ; ww < origScaleDims . w ; ww ++ ) { NvU32 offset = ww + origScaleDims . w * ( hh + origScaleDims . h * ( cc ) ) ; trnsScaleData [ offset ] = ( ( trnsFp32Scale . at ( offset ) * perTensorInTensorScale ) / perTensorOutTensorScale ) ; trnsCnt ++ ; if ( graph ( ) -> debugQuantization ( ) ) { gLogInfo << name ( ) << " " << trnsFp32Scale . at ( offset ) << " " << perTensorInTensorScale << " " << perTensorOutTensorScale << " " << trnsScaleData [ offset ] << endl ; } } } } trnsScaleBlob . type = nvdla :: DataType :: FLOAT ; trnsScaleBlob . count = trnsCnt ; trnsScaleBlob . values = trnsScaleData ; params ( ) . setRawScaleData ( trnsScaleBlob ) ; fail : return e ; }
Converts raw scale data to NvF32 and rescales.
Converts raw scale data to NvF32 and rescales .
// Preliminary checks // Convert scale data into float and get it as vector