inference-engine/src/gna_plugin/gna_graph_patterns.hpp
/**
 * @brief returns rotation information for a layer based on the previous convolution or pooling dimensions order
 * @param layer layer from which rotation info search must be started
 * @return bool value which identifies if rotation info is found and rotation information
 */
@brief returns rotation information for a layer based on the previous convolution or pooling dimensions order
@param layer layer from which rotation info search must be started
@return bool value which identifies if rotation info is found and rotation information
@brief returns rotation information for a layer based on the previous convolution or pooling dimensions order @param layer layer from which rotation info search must be started @return bool value which identifies if rotation info is found and rotation information
inline std::vector<TranspositionInfo> FindTranspositionInfoFromPrevLayers(InferenceEngine::CNNLayerPtr layer) {
    std::function<std::vector<TranspositionInfo>(InferenceEngine::CNNLayerPtr)> findTranspositionInfoRecursive =
        [&findTranspositionInfoRecursive](InferenceEngine::CNNLayerPtr layer) -> std::vector<TranspositionInfo> {
        if (LayerInfo(layer).isConvolution() || LayerInfo(layer).isPooling()) {
            auto out_dims = layer->outData[0]->getDims();
            return {{true, out_dims[1], out_dims[2] * out_dims[3]}};
        }
        if (LayerInfo(layer).isFullyConnected() || LayerInfo(layer).isInput()) {
            auto out_dims = layer->outData[0]->getDims();
            return {{false, 1, InferenceEngine::details::product(std::begin(out_dims), std::end(out_dims))}};
        }
        if (LayerInfo(layer).isEltwise()) {
            auto input1 = InferenceEngine::CNNNetPrevLayer(layer, 0);
            auto input2 = InferenceEngine::CNNNetPrevLayer(layer, 1);
            if (LayerInfo(input1).isConst()) return findTranspositionInfoRecursive(input2);
            return findTranspositionInfoRecursive(input1);
        }
        std::vector<TranspositionInfo> transpositionInfo;
        for (int idx = 0; idx < layer->insData.size(); ++idx) {
            if (!InferenceEngine::CNNNetHasPrevLayer(layer.get(), idx)) continue;
            auto inputLayer = InferenceEngine::CNNNetPrevLayer(layer, idx);
            if (LayerInfo(inputLayer).isSplit()) {
                auto in_dims = layer->insData[idx].lock()->getDims();
                transpositionInfo.push_back({false, 1, InferenceEngine::details::product(std::begin(in_dims), std::end(in_dims))});
            } else if (LayerInfo(layer).isConcat() && LayerInfo(inputLayer).isConst()) {
                auto in_dims = layer->insData[idx].lock()->getDims();
                auto data_size = InferenceEngine::details::product(std::begin(in_dims), std::end(in_dims));
                transpositionInfo.push_back({false, 1, data_size});
            } else {
                std::vector<TranspositionInfo> results = findTranspositionInfoRecursive(inputLayer);
                transpositionInfo.insert(std::end(transpositionInfo), std::begin(results), std::end(results));
            }
        }
        return transpositionInfo;
    };
    return findTranspositionInfoRecursive(layer);
}
inline std :: vector < TranspositionInfo > FindTranspositionInfoFromPrevLayers ( InferenceEngine :: CNNLayerPtr layer ) { std :: function < std :: vector < TranspositionInfo > ( InferenceEngine :: CNNLayerPtr ) > findTranspositionInfoRecursive = [ & findTranspositionInfoRecursive ] ( InferenceEngine :: CNNLayerPtr layer ) -> std :: vector < TranspositionInfo > { if ( LayerInfo ( layer ) . isConvolution ( ) || LayerInfo ( layer ) . isPooling ( ) ) { auto out_dims = layer -> outData [ 0 ] -> getDims ( ) ; return { { true , out_dims [ 1 ] , out_dims [ 2 ] * out_dims [ 3 ] } } ; } if ( LayerInfo ( layer ) . isFullyConnected ( ) || LayerInfo ( layer ) . isInput ( ) ) { auto out_dims = layer -> outData [ 0 ] -> getDims ( ) ; return { { false , 1 , InferenceEngine :: details :: product ( std :: begin ( out_dims ) , std :: end ( out_dims ) ) } } ; } if ( LayerInfo ( layer ) . isEltwise ( ) ) { auto input1 = InferenceEngine :: CNNNetPrevLayer ( layer , 0 ) ; auto input2 = InferenceEngine :: CNNNetPrevLayer ( layer , 1 ) ; if ( LayerInfo ( input1 ) . isConst ( ) ) return findTranspositionInfoRecursive ( input2 ) ; return findTranspositionInfoRecursive ( input1 ) ; } std :: vector < TranspositionInfo > transpositionInfo ; for ( int idx = 0 ; idx < layer -> insData . size ( ) ; ++ idx ) { if ( ! InferenceEngine :: CNNNetHasPrevLayer ( layer . get ( ) , idx ) ) continue ; auto inputLayer = InferenceEngine :: CNNNetPrevLayer ( layer , idx ) ; if ( LayerInfo ( inputLayer ) . isSplit ( ) ) { auto in_dims = layer -> insData [ idx ] . lock ( ) -> getDims ( ) ; transpositionInfo . push_back ( { false , 1 , InferenceEngine :: details :: product ( std :: begin ( in_dims ) , std :: end ( in_dims ) ) } ) ; } else if ( LayerInfo ( layer ) . isConcat ( ) && LayerInfo ( inputLayer ) . isConst ( ) ) { auto in_dims = layer -> insData [ idx ] . lock ( ) -> getDims ( ) ; auto data_size = InferenceEngine :: details :: product ( std :: begin ( in_dims ) , std :: end ( in_dims ) ) ; transpositionInfo . push_back ( { false , 1 , data_size } ) ; } else { std :: vector < TranspositionInfo > results = findTranspositionInfoRecursive ( inputLayer ) ; transpositionInfo . insert ( std :: end ( transpositionInfo ) , std :: begin ( results ) , std :: end ( results ) ) ; } } return transpositionInfo ; } ; return findTranspositionInfoRecursive ( layer ) ; }
@brief returns rotation information for a layer based on the previous convolution or pooling dimensions order
 @param layer layer from which rotation info search must be started
 @return bool value which identifies if rotation info is found and rotation information
@brief returns rotation information for a layer based on the previous convolution or pooling dimensions order @param layer layer from which rotation info search must be started @return bool value which identifies if rotation info is found and rotation information
/* If a fullyconnected or input layers are reached, it means that transposition isn't needed, but we should keep
         * its output size to skip this part during transposition if transposed layer is a result of concatination */ // If an eltwise is reached we should follow only one not-const direction // If we found split it's not possible to rotate data // If a concat input is a const we should keep its size to skip this part during transposition