//
// Copyright © 2017 Arm Ltd. All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "RecordByRecordCaffeParser.hpp"

#include "armnn/Exceptions.hpp"
#include "armnn/Utils.hpp"


#include "GraphTopologicalSort.hpp"

#include <boost/numeric/conversion/cast.hpp>

// Caffe
#include <google/protobuf/wire_format.h>


//#include <stdio.h>
#include <limits.h>
#include <sstream>
//#include <iostream>
#include <fstream>

namespace armnnCaffeParser
{
// class which holds information on the absolute position in the stream
// of the data and the length of the data record.
class VarLenDataInfo
{
public:
    VarLenDataInfo(std::streamoff positionOfData, size_t sizeOfData) :
        m_PositionOfData(positionOfData), m_SizeOfData(sizeOfData) {}

    VarLenDataInfo(const VarLenDataInfo& x) :
        m_PositionOfData(x.PositionOfData()), m_SizeOfData (x.SizeOfData()) {}

    VarLenDataInfo& operator=(const VarLenDataInfo& x)
    {
        // handle self assignment
        if (this == &x) {
            return *this;
        }
        m_PositionOfData = x.PositionOfData(); m_SizeOfData = x.SizeOfData(); return *this;
    }

    std::streamoff PositionOfData() const {return m_PositionOfData;}
    size_t SizeOfData() const {return m_SizeOfData;}

private:
    std::streamoff m_PositionOfData;
    size_t m_SizeOfData;

};

// class which holds enough information on a LayerParameter in the Caffe protobuf
// format to allow it to be resolved for in place layering and sorted topologically
// prior to the entire record being parsed into memory.
//
// NOTE: function naming follows that of the protobuf classes these proxies are standing in for
class LayerParameterInfo : public VarLenDataInfo
{
public:
    static const std::string INPUT;
    LayerParameterInfo(const VarLenDataInfo& varLenDataInfo) :
        VarLenDataInfo(varLenDataInfo.PositionOfData(), varLenDataInfo.SizeOfData()),
        m_newTops(false), m_newBottoms(false) {}

    LayerParameterInfo(std::streamoff positionOfData, size_t sizeOfData) :
        VarLenDataInfo(positionOfData, sizeOfData), m_newTops(false), m_newBottoms(false) {}

    LayerParameterInfo(const LayerParameterInfo& x) :
        VarLenDataInfo(x.PositionOfData(), x.SizeOfData()),
        m_name(x.m_name),
        m_type(x.m_type),
        m_tops(x.m_tops),
        m_bottoms(x.m_bottoms),
        m_newTops(x.m_newTops),
        m_newBottoms(x.m_newBottoms) {}

    LayerParameterInfo& operator=(const LayerParameterInfo& x)
    {
        if (this == &x) {
            return *this;
        }
        VarLenDataInfo::operator=(x);
        m_name = x.m_name;
        m_type = x.m_type;
        m_tops = x.m_tops;
        m_bottoms = x.m_bottoms;
        m_newTops = x.m_newTops;
        m_newBottoms = x.m_newBottoms;
        return *this;
    }

    const std::string name() const {return m_name;}
    void set_name(const std::unique_ptr<char[]>& theName, size_t length)
    {
        m_name = std::string(theName.get(), length);
    }
    void set_name(const std::string& theName) {m_name = theName;}

    const std::string type() const {return m_type;}
    void set_type(const std::unique_ptr<char[]>& theType, size_t length)
    {
        m_type = std::string(theType.get(), length);
    }
    void set_type(const std::string& theType) {m_type = theType;}

    void add_top(const std::unique_ptr<char[]>& top, size_t length)
    {
        std::string topName(top.get(), length);
        m_tops.push_back(topName);
    }
    void add_top(const std::string& topName)
    {
        m_tops.push_back(topName);
    }
    const std::string top(unsigned long i) const {return m_tops[i];}
    unsigned long top_size() const {return m_tops.size();}
    void set_top(unsigned long i, const std::string& newName) {m_tops[i] = newName; m_newTops = true;}
    bool new_tops() const {return m_newTops;}

    void add_bottom(const std::unique_ptr<char[]>& bottom, size_t length)
    {
        std::string bottomName(bottom.get(), length);
        m_bottoms.push_back(bottomName);
    }
    unsigned long bottom_size() const {return m_bottoms.size();}
    const std::string bottom(unsigned long i) const {return m_bottoms[i];}
    void set_bottom(unsigned long i, const std::string& newName) {m_bottoms[i] = newName; m_newBottoms = true;}
    bool new_bottoms() const {return m_newBottoms;}

    // if the position and size of the data is zero and the type is "Input" then this is an 'Implicit Input Layer'
    // and needs to be handled differently from ordinary layers.
    bool isImplicitInputLayer() const
    {
        if ((PositionOfData() == 0) && (SizeOfData() == 0) && INPUT.compare(type()) == 0)
        {return true;} else {return false;}
    }

private:
    std::string m_name;
    std::string m_type;
    std::vector<std::string> m_tops;
    std::vector<std::string> m_bottoms;
    // mark the layers whose topology was changed
    // by the ResolveInPlaceLayers method.
    bool m_newTops;
    bool m_newBottoms;
};

// class which holds the field type (wire type) and field id (id from the .proto schema)
// read from the protobuf messages as per the binary encoding described in
// https://developers.google.com/protocol-buffers/docs/encoding
//
// NOTE: function naming follows that of the protobuf classes these proxies are standing in for
class ProtobufFieldInfo
{
public:
    ProtobufFieldInfo(int field_type, int field_id) :
        m_eof(false), m_field_type(field_type), m_field_id(field_id) {}
    ProtobufFieldInfo() : m_eof(true), m_field_type(0), m_field_id(0) {}

    bool eof() {return m_eof;}
    int field_type() {return m_field_type;}
    int field_id() {return m_field_id;}

private:
    bool m_eof;
    int m_field_type;
    int m_field_id;
};


// There are some NetParameter level data which are required
// to correctly processes some Caffe models. Specifically those which
// have 'implicit' input layers. Also it is nice to have the name of the model.
//
// NOTE: function naming follows that of the protobuf classes these proxies are standing in for
class NetParameterInfo
{
public:
    const std::string name() const {return m_name;}
    void set_name(const std::unique_ptr<char[]>&  theName, size_t length)
    {
        m_name = std::string(theName.get(), length);
    }

    void add_input(const std::unique_ptr<char[]>&  input, size_t length)
    {
        std::string inputName(input.get(), length);
        m_inputs.push_back(inputName);
    }
    const std::string input(unsigned long i) const {return m_inputs[i];}
    unsigned long input_size() const {return m_inputs.size();}

    void add_input_dimension(int input_dimension) {
        m_input_dimensions.push_back(input_dimension);
    }
    int input_dimension(unsigned long i) const {return m_input_dimensions[i];}
    unsigned long input_dimensions_size() const {return m_input_dimensions.size();}

    void add_blob_shape(caffe::BlobShape shape) {
        m_blob_shapes.push_back(shape);
    }
    const caffe::BlobShape blob_shape(unsigned long i) const {return m_blob_shapes[i];}
    unsigned long blob_shapes_size() const {return m_blob_shapes.size();}

private:
    std::string m_name;
    std::vector<std::string> m_inputs;
    std::vector<int> m_input_dimensions;
    std::vector<caffe::BlobShape> m_blob_shapes;

};

}; // namespace armnnCaffeParser

using namespace armnnCaffeParser;

// Initialise the class const
const std::string LayerParameterInfo::INPUT = "Input";

namespace
{

ProtobufFieldInfo readFieldInfo(std::ifstream& ifs)
{
    unsigned char first_byte = static_cast<unsigned char>(ifs.get());
    if (!ifs.good())
    {
        ProtobufFieldInfo eof;
        return eof;
    }
    int field_type = first_byte&7;
    int field_id = first_byte>>3;
    if ((field_id & 16) == 16)
    {
        unsigned char second_byte = static_cast<unsigned char>(ifs.get());
        if (!ifs.good())
        {
            ProtobufFieldInfo eof;
            return eof;
        }
        field_id = (field_id-16) + ((second_byte&127)<<4);
    }
    ProtobufFieldInfo fieldInfo(field_type, field_id);
    return fieldInfo;
}

const static int MAX_NUM_BYTES = 5;

int ReadBase128(std::ifstream& ifs)
{
    int result = 0;
    unsigned int shift_by = 0;
    int bytesRead = 0;
    while (true)
    {
        unsigned char a_byte = static_cast<unsigned char>(ifs.get());
        ++bytesRead;
        if (bytesRead > MAX_NUM_BYTES)
        {
            throw armnn::ParseException(
                "ReadBase128 exceeded the maximum number of bytes expected for an integer representation");
        }
        result += (a_byte & 127) << shift_by;
        shift_by += 7;
        if ((a_byte & 128) != 128)
        {
            break;
        }
    }
    return result;
}


std::unique_ptr<char[]> AllocateBuffer(std::ifstream& ifs, VarLenDataInfo& dataInfo)
{
    std::unique_ptr<char[]> ptr(new char[dataInfo.SizeOfData()]);
    ifs.clear();
    ifs.seekg(dataInfo.PositionOfData(), std::ios_base::beg);
    ifs.read(ptr.get(), boost::numeric_cast<std::streamsize>(dataInfo.SizeOfData()));
    return ptr;
}

VarLenDataInfo CreateVarLenDataInfo(std::streamoff bufferStart, std::streamoff endOfLayer) {
    std::streamoff sizeOfLayer = endOfLayer - bufferStart;
    if (sizeOfLayer < 0)
    {
        std::stringstream ss;
        ss << "error when determining buffer size, negative value [" << sizeOfLayer << "]";
        throw armnn::ParseException(ss.str());
    }
    // NOTE: as some of the data being read in will be translated into strings (names of layers etc)
    //       the maximum size we can deal with is the upper size limit of a string i.e. size_t
    // on the platform in which I am currently compiling std::streamoff is signed long int and
    // size_t is unsigned long int so there is no way this error condition can fire but this stuff
    // is supposed to be portable so the check remains in place
    if (boost::numeric_cast<size_t>(sizeOfLayer) > SIZE_MAX) {
        std::stringstream ss;
        ss << "layer is greater than " << SIZE_MAX << " in size cannot process. layer size = [" << sizeOfLayer << "]";
        throw armnn::ParseException(ss.str());
    }
    LayerParameterInfo info(bufferStart, boost::numeric_cast<size_t>(sizeOfLayer));
    return info;
}

void ReadTopologicalInfoForLayerParameter(LayerParameterInfo& layerInfo, std::ifstream& ifs)
{
    // position the file pointer to the start of the layer data
    ifs.clear();
    ifs.seekg(layerInfo.PositionOfData(), std::ios_base::beg);
    std::streamoff endOfLayer = layerInfo.PositionOfData() +
        boost::numeric_cast<std::streamoff>(layerInfo.SizeOfData());
    while(true)
    {
        // check to see if we have reached the end of the record
        std::streamoff currentPosition = ifs.tellg();
        if (currentPosition >= endOfLayer) {
            return;
        }
        // read the information for the next field.
        ProtobufFieldInfo fieldInfo = readFieldInfo(ifs);
        if (fieldInfo.eof())
        {
            return;
            // TODO: figure out whether this is an error condition or not...
            //throw armnn::ParseException("failed to read field from LayerParameter data");
        }
        // process the field
        switch (fieldInfo.field_type())
        {
            case 0:
            {
                ReadBase128(ifs);
                break;
            }
            case 2:
            {
                int size = ReadBase128(ifs);
                std::streamoff posStartOfData = ifs.tellg();
                VarLenDataInfo dataInfo(posStartOfData, boost::numeric_cast<size_t>(size));
                //optional string name = 1; // the layer name
                //optional string type = 2; // the layer type
                //repeated string bottom = 3; // the name of each bottom blob
                //repeated string top = 4; // the name of each top blob
                if (fieldInfo.field_id() == 1)
                {
                    // read and set the name of the layer
                    auto layerName = AllocateBuffer(ifs, dataInfo);
                    layerInfo.set_name(layerName, dataInfo.SizeOfData());
                }
                else if (fieldInfo.field_id() == 2)
                {
                    // read and set the type of the layer
                    auto layerType = AllocateBuffer(ifs, dataInfo);
                    layerInfo.set_type(layerType, dataInfo.SizeOfData());
                }
                else if (fieldInfo.field_id() == 3)
                {
                    // read and add a bottom to the layer
                    auto bottom = AllocateBuffer(ifs, dataInfo);
                    layerInfo.add_bottom(bottom, dataInfo.SizeOfData());
                }
                else if (fieldInfo.field_id() == 4)
                {
                    // read and add a top to the layer
                    auto top = AllocateBuffer(ifs, dataInfo);
                    layerInfo.add_top(top, dataInfo.SizeOfData());
                }
                else
                {
                    ifs.seekg(size, std::ios_base::cur);
                    if (!ifs.good())
                    {
                        // TODO: error out?
                        return;
                    }
                }
                break;
            }
            case 1:
            {
                // 64 bit
                // advance by eight bytes
                ifs.seekg(8, std::ios_base::cur);
                if (!ifs.good())
                {
                    // TODO: error out?
                    return;
                }
                break;
            }
            case 5:
            {
                // 32 bit
                // advance by four bytes
                ifs.seekg(4, std::ios_base::cur);
                if (!ifs.good())
                {
                    // TODO: error out?
                    return;
                }
                break;
            }
            default:
            {
                throw armnn::ParseException("Encounted an unknown field type");
                break;
            }
        }
    }
}

void ResolveInPlaceLayers(std::vector<LayerParameterInfo>& layerInfo)
{
    std::map<std::string, std::vector<LayerParameterInfo*>> layersByTop;
    for (auto& info : layerInfo)
    {
        for (unsigned long i = 0; i < info.top_size(); ++i)
        {
            layersByTop[info.top(i)].push_back(&info);
        }
    }
    // For each set of layers with the same top, resolve them to a linear chain rather than in-place layers.
    // Note that for 'regular' layers, there will be a single layer in each group and so this will be a no-op.
    for (auto& layersWithSameTopIterator : layersByTop)
    {
        const std::string& top = layersWithSameTopIterator.first;
        const std::vector<LayerParameterInfo*> layersWithSameTop = layersWithSameTopIterator.second;

        // Chain the layers together in the order that they are listed in the prototxt (hopefully this is correct).
        // Note that the last layer will not have its top modified so that other layers will continue to reference it.
        for (unsigned int layerIdx = 0; layerIdx < layersWithSameTop.size() - 1; ++layerIdx)
        {
            LayerParameterInfo* layer1 = layersWithSameTop[layerIdx];
            LayerParameterInfo* layer2 = layersWithSameTop[layerIdx + 1];
            if (layer1->top_size() != 1)
            {
                throw armnn::ParseException("Node '" + layer1->name() + "' is an in-place layer but "
                                                                        "doesn't have exactly one top.");
            }
            std::string newTop = layer1->name() + "_top";
            layer1->set_top(0, newTop);
            if (layer2->bottom_size() != 1 || layer2->bottom(0) != top)
            {
                throw armnn::ParseException("Node '" + layer2->name() + "' is an in-place layer but "
                    " doesn't have exactly one bottom, or it doesn't match its top.");
            }
            layer2->set_bottom(0, newTop);

        }
    }
}

} // anonymous namespace, can't be seen outside this source file

RecordByRecordCaffeParser::RecordByRecordCaffeParser() : CaffeParserBase()
{}

armnn::INetworkPtr RecordByRecordCaffeParser::CreateNetworkFromBinaryFile(
    const char* graphFile,
    const std::map<std::string, armnn::TensorShape>& inputShapes,
    const std::vector<std::string>& requestedOutputs)
{

    m_InputShapes = inputShapes;
    if (requestedOutputs.size() == 0)
    {
        throw armnn::ParseException("requestedOutputs must have at least one entry");
    }
    m_RequestedOutputs = requestedOutputs;

    //FILE * fp = fopen(graphFile, "rb");
    std::ifstream ifs(graphFile, std::ifstream::in|std::ifstream::binary);
    std::vector<LayerParameterInfo> layerInfo;
    NetParameterInfo netParameterInfo;
    while(true)
    {
        ProtobufFieldInfo fieldInfo = readFieldInfo(ifs);
        if (fieldInfo.eof())
        {
            break;
        }
        switch(fieldInfo.field_type())
        {
            case 0:
            {
                ReadBase128(ifs);
                break;
            }
            case 2:
            {
                // The values of interest from the caffe.proto schema are:
                // optional string name = 1; // consider giving the network a name
                // DEPRECATED. See InputParameter. The input blobs to the network.
                // repeated string input = 3;
                // DEPRECATED. See InputParameter. The shape of the input blobs.
                // repeated BlobShape input_shape = 8;

                // 4D input dimensions -- deprecated.  Use "input_shape" instead.
                // If specified, for each input blob there should be four
                // values specifying the num, channels, height and width of the input blob.
                // Thus, there should be a total of (4 * #input) numbers.
                // repeated int32 input_dim = 4;

                // The layers that make up the net.  Each of their configurations, including
                // connectivity and behavior, is specified as a LayerParameter.
                // repeated LayerParameter layer = 100;  // ID 100 so layers are printed last.

                // The first four will (if present) be read into the NetParameterInfo
                // the LayerParameters will be read into the LayerParameterInfo vector.

                int size = ReadBase128(ifs);
                std::streamoff posStartOfData = ifs.tellg();
                ifs.seekg(size, std::ios_base::cur);
                if(!ifs.good())
                {
                    throw armnn::ParseException("failed to seek ahead in binary caffe file");
                }
                std::streamoff endOfLayer = ifs.tellg();
                if (fieldInfo.field_id() == 1)
                {
                    VarLenDataInfo dataInfo = CreateVarLenDataInfo(posStartOfData, endOfLayer);
                    auto graphName = AllocateBuffer(ifs, dataInfo);
                    netParameterInfo.set_name(graphName, dataInfo.SizeOfData());
                }
                if (fieldInfo.field_id() == 3)
                {
                    VarLenDataInfo dataInfo = CreateVarLenDataInfo(posStartOfData, endOfLayer);
                    auto inputName = AllocateBuffer(ifs, dataInfo);
                    netParameterInfo.add_input(inputName, dataInfo.SizeOfData());
                }
                if (fieldInfo.field_id() == 8)
                {
                    VarLenDataInfo dataInfo = CreateVarLenDataInfo(posStartOfData, endOfLayer);
                    auto inputShape = AllocateBuffer(ifs, dataInfo);
                    caffe::BlobShape blobShape;
                    bool bRet = blobShape.ParseFromArray(inputShape.get(), static_cast<int>(dataInfo.SizeOfData()));
                    if (!bRet)
                    {
                        throw armnn::ParseException("Failed to parse input shape");
                    }
                    netParameterInfo.add_blob_shape(blobShape);
                }
                if (fieldInfo.field_id() == 4)
                {
                    int input_dim = ReadBase128(ifs);
                    netParameterInfo.add_input_dimension(input_dim);
                }
                if (fieldInfo.field_id() == 100)
                {
                    LayerParameterInfo info(CreateVarLenDataInfo(posStartOfData, endOfLayer));
                    ReadTopologicalInfoForLayerParameter(info, ifs);
                    layerInfo.push_back(info);
                }
                break;
            }
            default:
            {
                break;
            }
        }
    }
    std::vector<const LayerParameterInfo*> sortedNodes;
    ProcessLayers(netParameterInfo, layerInfo, m_RequestedOutputs, sortedNodes);
    armnn::INetworkPtr networkPtr = LoadLayers(ifs, sortedNodes, netParameterInfo);
    return networkPtr;

}

void RecordByRecordCaffeParser::ProcessLayers(
    const NetParameterInfo& netParameterInfo,
    std::vector<LayerParameterInfo>& layerInfo,
    const std::vector<std::string>& m_RequestedOutputs,
    std::vector<const LayerParameterInfo*>& sortedNodes)
{
    // if there is an implicit input layer add it to the layerInfo list
    if (netParameterInfo.input_size() > 0)
    {
        LayerParameterInfo implicitInputLayer(0, 0);
        implicitInputLayer.set_type(LayerParameterInfo::INPUT);
        implicitInputLayer.set_name(netParameterInfo.input(0));
        implicitInputLayer.add_top(netParameterInfo.input(0));
        layerInfo.push_back(implicitInputLayer);
    }
    ::ResolveInPlaceLayers(layerInfo);

    for (LayerParameterInfo& info : layerInfo)
    {
        for (unsigned long i = 0; i < info.top_size(); ++i)
        {
            m_CaffeLayersByTopName[info.top(i)] = &info;
        }
    }

    // Find the output layers the user requested
    std::vector<const LayerParameterInfo*> targetLayers;
    for (const std::string& requestedOutputName : m_RequestedOutputs)
    {
        auto nodeIt = m_CaffeLayersByTopName.find(requestedOutputName);
        if (nodeIt == m_CaffeLayersByTopName.end())
        {
            throw armnn::ParseException(
                "Couldn't find requested output layer '" + requestedOutputName + "' in graph");
        }
        targetLayers.push_back(nodeIt->second);
    }

    // Sort them into a linear ordering such that all inputs of a node are before the node itself
    if (!armnnUtils::GraphTopologicalSort<const LayerParameterInfo*>(
        targetLayers,
        [this](const LayerParameterInfo* node)
            {
                return GetInputs(*node);
            },
        sortedNodes))
    {
        throw armnn::ParseException("Cycle detected in graph");
    }
}


std::vector<const LayerParameterInfo*> RecordByRecordCaffeParser::GetInputs(
    const LayerParameterInfo& layerParam)
{
    std::vector<const LayerParameterInfo*> ret;
    ret.reserve(layerParam.bottom_size());
    for (unsigned long j = 0; j < layerParam.bottom_size(); ++j)
    {
        std::string inputName = layerParam.bottom(j);
        auto inputIt = m_CaffeLayersByTopName.find(inputName);
        if (inputIt == m_CaffeLayersByTopName.end())
        {
            throw armnn::ParseException(
                "Can't find Caffe layer with top called '" + inputName + "', which is listed as an input of '" +
                layerParam.name() + "'");
        }
        ret.push_back(inputIt->second);
    }

    return ret;
}

armnn::INetworkPtr RecordByRecordCaffeParser::LoadLayers(std::ifstream& ifs,
                                                         std::vector<const LayerParameterInfo *>& sortedNodes,
                                                         const NetParameterInfo& netParameterInfo)
{

    m_NetworkInputsBindingInfo.clear();
    m_NetworkOutputsBindingInfo.clear();

    m_Network = armnn::INetwork::Create();

    for (auto info : sortedNodes)
    {
        caffe::LayerParameter layer;
        if (info->isImplicitInputLayer())
        {
            // create the matching Layer Parameter programatically from the data in the
            // net parameter info which has been passed in...
            layer.set_type(LayerParameterInfo::INPUT);
            layer.set_name(netParameterInfo.input(0));
            layer.add_top(netParameterInfo.input(0));

            caffe::InputParameter* inputParam = layer.mutable_input_param();
            caffe::BlobShape* shape = inputParam->add_shape();

            long unsigned int dim_size = netParameterInfo.input_dimensions_size();
            for (long unsigned int i = 0; i < dim_size; ++i)
            {
                shape->add_dim(netParameterInfo.input_dimension(i));
            }
        }
        else
        {
            char *buffer = new char[info->SizeOfData()];
            ifs.clear();
            ifs.seekg(info->PositionOfData(), std::ios_base::beg);
            ifs.read(buffer, boost::numeric_cast<std::streamsize>(info->SizeOfData()));
            bool bRet = layer.ParseFromArray(buffer, static_cast<int>(info->SizeOfData()));
            delete[] buffer;
            if (!bRet)
            {
                throw armnn::ParseException("Failed to parse layer [" + info->name() + "]");
            }
        }

        if (info->new_tops())
        {
            //update the tops
            layer.set_top(0, info->top(0));
        }
        if (info->new_bottoms())
        {
            //update the bottoms
            layer.set_bottom(0, info->bottom(0));
        }

        auto it = ms_CaffeLayerNameToParsingFunctions.find(layer.type());
        if (it == ms_CaffeLayerNameToParsingFunctions.end())
        {
            throw armnn::ParseException("Unsupported layer type '" + layer.type() + "'");
        }
        auto func = it->second;
        (this->*func)(layer);
    }
    ifs.close();

    // Add ArmNN output layers connected to each requested output
    for (const std::string& requestedOutput : m_RequestedOutputs)
    {
        armnn::IOutputSlot& outputSlot = GetArmnnOutputSlotForCaffeTop(requestedOutput);

        const armnn::LayerBindingId outputId = boost::numeric_cast<armnn::LayerBindingId>(
            m_NetworkOutputsBindingInfo.size());
        armnn::IConnectableLayer* const outputLayer = m_Network->AddOutputLayer(outputId, requestedOutput.c_str());
        outputSlot.Connect(outputLayer->GetInputSlot(0));

        TrackOutputBinding(outputLayer, outputId, outputLayer->GetInputSlot(0).GetConnection()->GetTensorInfo());
    }

    Cleanup();

    return move(m_Network);
}



