
// Copyright (c) 2020-2023, ARM Limited.
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//         http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

#include "subgraph_traverser.h"
#include "arith_util.h"
#include "tosa_model_types.h"

#ifndef SUBGRAPH_ERROR_IF
#define SUBGRAPH_ERROR_IF(COND, fmt, ...)                                                                              \
    if ((COND))                                                                                                        \
    {                                                                                                                  \
        if (this->getGraphStatus() != GraphStatus::TOSA_UNPREDICTABLE)                                                 \
        {                                                                                                              \
            this->setGraphStatus(GraphStatus::TOSA_ERROR);                                                             \
        }                                                                                                              \
        fprintf(g_func_debug.func_debug_file, COL_FATAL("SUBGRAPH_ERROR_IF() fails AT %s:%d %s(): (%s)\n"), __FILE__,  \
                __LINE__, __func__, #COND);                                                                            \
        fprintf(g_func_debug.func_debug_file, COL_FATAL(fmt) "\n", ##__VA_ARGS__);                                     \
        func_print_backtrace(g_func_debug.func_debug_file);                                                            \
        return 1;                                                                                                      \
    }
#endif

using namespace TosaReference;
using namespace Eigen;
using namespace tosa;

SubgraphTraverser::SubgraphTraverser(TosaSerializationBasicBlock* _block,
                                     TosaSerializationHandler* _tsh,
                                     SubgraphTraverser* _parent_sgt)
{

    graph_status = GraphStatus::TOSA_VALID;
    block        = _block;

    tsh        = _tsh;
    parent_sgt = _parent_sgt;
    tensors.clear();
    nodes.clear();
    nextNodeList.clear();
}

SubgraphTraverser::~SubgraphTraverser()
{
    nextNodeList.clear();

    for (GraphNode* n : nodes)
    {
        delete n;
    }
    nodes.clear();

    for (TosaReference::Tensor* t : tensors)
    {
        if (t->getIsVariable() && parent_sgt)
        {
            // variable tensors are owned by top level sgt
            continue;
        }
        if (t->is_allocated())
        {
            t->deallocate();
        }
        delete t;
    }
    tensors.clear();
}

int SubgraphTraverser::getNumInputTensors() const
{
    return inputTensors.size();
}

TosaReference::Tensor* SubgraphTraverser::getInputTensor(const unsigned int idx) const
{
    return inputTensors[idx];
}

TosaReference::Tensor* SubgraphTraverser::getInputTensorByName(const std::string name) const
{
    for (auto t : inputTensors)
    {
        if (t->getName() == name)
        {
            return t;
        }
    }

    return nullptr;
}

int SubgraphTraverser::getNumOutputTensors() const
{
    return outputTensors.size();
}

TosaReference::Tensor* SubgraphTraverser::getOutputTensor(const unsigned int idx) const
{
    return outputTensors[idx];
}

TosaReference::Tensor* SubgraphTraverser::getOutputTensorByName(const std::string name) const
{
    for (auto t : outputTensors)
    {
        if (t->getName() == name)
        {
            return t;
        }
    }

    return nullptr;
}

int SubgraphTraverser::getNumVariableTensors() const
{
    return variableTensors.size();
}

TosaReference::Tensor* SubgraphTraverser::getVariableTensor(const unsigned int idx) const
{
    return variableTensors[idx];
}

// find variable tensor by name in top level sgt's @a variableTensors
TosaReference::Tensor* SubgraphTraverser::getVariableTensorByName(const std::string name) const
{
    // variable tensors are owned by top level sgt
    if (parent_sgt)
    {
        return parent_sgt->getVariableTensorByName(name);
    }

    for (auto t : variableTensors)
    {
        if (t->getName() == name)
        {
            return t;
        }
    }

    return nullptr;
}

// add variable tensor to top level sgt's @a variableTensors
int SubgraphTraverser::registerVariableTensor(Tensor* tensor)
{
    SUBGRAPH_ERROR_IF(!tensor->getIsVariable(),
                      "SubgraphTraverser::registerVariableTensor(): tensor %s is not a variable",
                      tensor->getName().c_str());
    // variable tensors are owned by top level sgt
    if (parent_sgt)
    {
        return parent_sgt->registerVariableTensor(tensor);
    }
    variableTensors.push_back(tensor);
    return 0;
}

int SubgraphTraverser::initializeGraph()
{
    int idx = 0;

    std::vector<TosaSerializationTensor*> ser_tensor_vec;
    // Get all the serialized tensors from TosaSerializationHandler.
    if (tsh)
    {
        for (auto region : tsh->GetRegions())
        {
            for (auto block : region->GetBlocks())
            {
                for (auto ser_tensor : block->GetTensors())
                {
                    ser_tensor_vec.push_back(ser_tensor);
                }
            }
        }
    }
    else
    {
        for (auto ser_tensor : block->GetTensors())
        {
            ser_tensor_vec.push_back(ser_tensor);
        }
    }

    std::vector<GraphNode*> non_const_node_vec;
    for (auto op : block->GetOperators())
    {
        // translated TosaSerializationOperator to GraphNode
        TOSA_REF_TYPE input_dtype  = TOSA_REF_TYPE_UNKNOWN;
        TOSA_REF_TYPE output_dtype = TOSA_REF_TYPE_UNKNOWN;
        TOSA_REF_TYPE weight_dtype = TOSA_REF_TYPE_UNKNOWN;
        uint32_t input_rank        = 0;
        uint32_t output_rank       = 0;
        uint32_t weight_rank       = 0;
        int32_t input_index        = -1;
        int32_t weight_index       = -1;

        switch (op->GetOp())
        {
            case Op_CONV2D:
            case Op_CONV3D:
            case Op_DEPTHWISE_CONV2D:
            case Op_TRANSPOSE_CONV2D:
            case Op_FULLY_CONNECTED:
                input_index  = 0;
                weight_index = 1;
                break;
            case Op_SELECT:
                input_index = 1;
                break;
            default:
                if (!op->GetInputTensorNames().empty())
                    input_index = 0;
                break;
        }

        if (input_index != -1)
        {
            SUBGRAPH_ERROR_IF(
                (size_t)input_index >= op->GetInputTensorNames().size(),
                "SubgraphTraverser::initializeGraph(): Op=%s, input_index %d must be within [0, num_input - 1]",
                EnumNamesOp()[op->GetOp()], input_index);

            std::string input_name                = op->GetInputTensorNames()[input_index];
            TosaSerializationTensor* input_tensor = nullptr;
            for (auto ser_tensor : ser_tensor_vec)
            {
                if (ser_tensor->GetName() == input_name)
                {
                    input_tensor = ser_tensor;
                }
            }

            SUBGRAPH_ERROR_IF(
                !input_tensor,
                "SubgraphTraverser::initializeGraph(): fail to get input tensor %s from TosaSerializationHandler",
                input_name.c_str());
            input_dtype = ConvertDType(input_tensor->GetDtype());
            input_rank  = input_tensor->GetShape().size();
        }

        if (weight_index != -1)
        {
            SUBGRAPH_ERROR_IF(
                (size_t)weight_index >= op->GetInputTensorNames().size(),
                "SubgraphTraverser::initializeGraph(): Op=%s, weight_index %d must be within [0, num_input - 1]",
                EnumNamesOp()[op->GetOp()], weight_index);
            std::string weight_name                = op->GetInputTensorNames()[weight_index];
            TosaSerializationTensor* weight_tensor = nullptr;
            for (auto ser_tensor : ser_tensor_vec)
            {
                if (ser_tensor->GetName() == weight_name)
                {
                    weight_tensor = ser_tensor;
                }
            }

            SUBGRAPH_ERROR_IF(
                !weight_tensor,
                "SubgraphTraverser::initializeGraph(): fail to get weight tensor %s from TosaSerializationHandler",
                weight_name.c_str());
            weight_dtype = ConvertDType(weight_tensor->GetDtype());
            weight_rank  = weight_tensor->GetShape().size();
        }

        SUBGRAPH_ERROR_IF(op->GetOutputTensorNames().size() == 0,
                          "SubgraphTraverser::initializeGraph(): Op=%s must have at least one output tensor.",
                          EnumNamesOp()[op->GetOp()]);
        std::string output_name                = op->GetOutputTensorNames()[0];
        TosaSerializationTensor* output_tensor = block->GetTensorByName(output_name);
        SUBGRAPH_ERROR_IF(
            !output_tensor,
            "SubgraphTraverser::initializeGraph(): fail to get output tensor %s from TosaSerializationHandler",
            output_name.c_str());
        output_dtype = ConvertDType(output_tensor->GetDtype());
        output_rank  = output_tensor->GetShape().size();

        DEBUG_INFO(GT, "Creating operator id_%03u, %8s, %lu input tensors, %lu output tensors", idx,
                   EnumNamesOp()[op->GetOp()], op->GetInputTensorNames().size(), op->GetOutputTensorNames().size());

        GraphNode* node = nullptr;
        if (this->parent_sgt)
        {
            node = OpFactory::newOp(this->parent_sgt, tsh, op->GetOp(), op->GetAttribute(), idx, input_dtype,
                                    input_rank, output_dtype, output_rank, weight_dtype, weight_rank);
            node->setInMainBlock(false);
        }
        else
        {
            node = OpFactory::newOp(this, tsh, op->GetOp(), op->GetAttribute(), idx, input_dtype, input_rank,
                                    output_dtype, output_rank, weight_dtype, weight_rank);
            if (node)
            {
                node->setInMainBlock(true);
            }
        }

        if (!node)
        {
            if (weight_index == -1)
            {
                fprintf(g_func_debug.func_debug_file,
                        "SubgraphTraverser::initializeGraph(): OpFactory could not allocate op %8s input=(%s rank %d) "
                        "-> (%s rank %d)",
                        EnumNamesOp()[op->GetOp()], EnumNameTOSAREFTYPE(input_dtype), input_rank,
                        EnumNameTOSAREFTYPE(output_dtype), output_rank);
            }
            else
            {
                fprintf(g_func_debug.func_debug_file,
                        "SubgraphTraverser::initializeGraph(): OpFactory could not allocate op %8s input=(%s rank %d), "
                        "weight=(%s rank %d) -> (%s rank %d)",
                        EnumNamesOp()[op->GetOp()], EnumNameTOSAREFTYPE(input_dtype), input_rank,
                        EnumNameTOSAREFTYPE(weight_dtype), weight_rank, EnumNameTOSAREFTYPE(output_dtype), output_rank);
            }

            for (auto& ts : op->GetInputTensorNames())
            {
                fprintf(g_func_debug.func_debug_file, "SubgraphTraverser::initializeGraph(): Input: %s\n", ts.c_str());
            }

            for (auto& ts : op->GetOutputTensorNames())
            {
                fprintf(g_func_debug.func_debug_file, "SubgraphTraverser::initializeGraph(): Output: %s\n", ts.c_str());
            }
            SUBGRAPH_ERROR_IF(true, "SubgraphTraverser::initializeGraph(): Unsupported operation type or rank.");
        }

        // Elementwise operator might set TOSA_ERROR when registering lambda function when creating the op.
        // Check graph status after the op being constructed.
        SUBGRAPH_ERROR_IF(getGraphStatus() == GraphStatus::TOSA_ERROR,
                          "SubgraphTraverser::initializeGraph(): Op %8s triggered ERROR_IF() when constructing the op.",
                          EnumNamesOp()[op->GetOp()]);

        for (auto& name : op->GetInputTensorNames())
        {
            node->addInputName(name);
            used_tensor_name_set.insert(name);
        }

        for (auto name : op->GetOutputTensorNames())
        {
            node->addOutputName(name);
            used_tensor_name_set.insert(name);
        }

        addNode(node);

        // if node doesn't have any inputs (i.e. CONST)
        // it should be ready for evaluation
        if (op->GetInputTensorNames().empty() && !node->getOnNextNodeList())
        {
            addToNextNodeList(node);
        }
        else if (!node->getInMainBlock())
        {
            non_const_node_vec.push_back(node);
        }

        // Bug fix: add the ready node in main block for evaluation
        if (node->hasAllInputsReady() && !node->getOnNextNodeList() && !node->getEvaluated())
        {
            addToNextNodeList(node);
        }

        idx++;
    }

    for (auto ts : block->GetTensors())
    {
        addTensor(ts);
    }

    DEBUG_INFO(GT, "Enumerating block %s graph inputs", block->GetName().c_str());
    for (auto& input_name : block->GetInputs())
    {
        TosaReference::Tensor* tensor = findTensorByName(input_name);
        DEBUG_INFO(GT, "input tensor name=%s", input_name.c_str());
        if (tensor)
        {
            tensor->setIsSubgraphInput();
            inputTensors.push_back(tensor);
        }
        else
        {
            SUBGRAPH_ERROR_IF(true, "SubgraphTraverser::initializeGraph(): Failed to find input tensor by name %s",
                              input_name.c_str());
        }
    }

    DEBUG_INFO(GT, "Enumerating block %s graph outputs", block->GetName().c_str());
    for (auto& output_name : block->GetOutputs())
    {
        TosaReference::Tensor* tensor = findTensorByName(output_name);
        DEBUG_INFO(GT, "output tensor name=%s", output_name.c_str());
        if (tensor)
        {
            tensor->setIsSubgraphOutput();
            outputTensors.push_back(tensor);
        }
        else
        {
            SUBGRAPH_ERROR_IF(true, "SubgraphTraverser::initializeGraph(): Failed to find output tensor by name %s",
                              output_name.c_str());
        }
    }

    if (DEBUG_ENABLED(DEBUG_VERB_HIGH, GT))
    {
        dumpNextNodeList(g_func_debug.func_debug_file);
    }

    // If the node is not in mainblock and not const
    for (auto node : non_const_node_vec)
    {
        bool all_inputs_from_parent = true;
        for (std::string& name : node->getInputNames())
        {
            TosaReference::Tensor* t = findTensorByName(name);
            if (!t->getIsParentGraphOutput())
            {
                all_inputs_from_parent = false;
            }
        }
        // In the children block, when a node has all its inputs from parent
        // block, we have to manually add this node to the evaluation list
        if (all_inputs_from_parent && !node->getOnNextNodeList())
        {
            addToNextNodeList(node);
        }
    }
    return 0;
}

int SubgraphTraverser::allocateInputTensors()
{
    auto input_tensor_names_vec = block->GetInputs();

    for (auto input_tensor_name : input_tensor_names_vec)
    {
        this->allocateTensor(input_tensor_name);
    }

    // allocate variable tensors if not already allocated
    for (auto ts : block->GetTensors())
    {
        if (ts->GetVariable())
        {
            TosaReference::Tensor* tensor = findTensorByName(ts->GetName());
            SUBGRAPH_ERROR_IF(!tensor, "SubgraphTraverser::allocateInputTensors(): can't find tensor %s.",
                              ts->GetName().c_str());
            if (!tensor->is_allocated())
            {
                DEBUG_INFO(GT, "Is a VariableTensor %s", ts->GetName().c_str());
                this->allocateTensor(ts->GetName());
            }
        }
    }

    return 0;
}

int SubgraphTraverser::allocateTensor(std::string name)
{
    auto ts = block->GetTensorByName(name);

    // Bail out if tensor is used and any of its dimension is invalid.
    auto got = used_tensor_name_set.find(ts->GetName());
    if (got != used_tensor_name_set.end())
    {
        uint32_t elements = 1;
        for (auto& dim : ts->GetShape())
        {
            if (dim <= 0)
            {
                DEBUG_INFO(GT, "Failed to allocate tensor %s with invalid dimension of %d", ts->GetName().c_str(), dim);
                this->setGraphStatus(GraphStatus::TOSA_UNPREDICTABLE);
                return 1;
            }
            if (dim > static_cast<int32_t>(TOSA_MAX_TENSOR_SIZE / elements))
            {
                // Size greather than maximum defined in spec
                DEBUG_INFO(GT, "Tensor %s size is greater than allowed maximum", ts->GetName().c_str());
                this->setGraphStatus(GraphStatus::TOSA_UNPREDICTABLE);
                return 1;
            }
        }
    }

    TosaReference::Tensor* tensor = findTensorByName(ts->GetName());
    SUBGRAPH_ERROR_IF(!tensor, "SubgraphTraverser::allocateTensor(): can't find tensor %s.", ts->GetName().c_str());

    DEBUG_INFO(GT, "Allocating tensor %s", tensor->getName().c_str());
    if (tensor->allocate())
    {
        FATAL_ERROR("Failed to allocate tensor %s", tensor->getName().c_str());
    }

    if (!ts->GetData().empty())
    {
        if (ts->GetVariable() && g_func_config.initialize_variable_tensor_from_numpy)
            return 0;
        DEBUG_INFO(GT, "Setting data for tensor %s", tensor->getName().c_str());
        auto serialization_dtype = ts->GetDtype();
        switch (serialization_dtype)
        {
            case DType_INT4: {
                std::vector<int8_t> i4_data;
                TosaSerializationHandler::ConvertU8toI4(ts->GetData(), tensor->getElementCount(), i4_data);
                std::vector<int32_t> i32_data(i4_data.begin(), i4_data.end());
                tensor->setTensorValueInt32(i32_data.size(), i32_data.data());
            }
            break;
            case DType_INT8: {
                std::vector<int8_t> i8_data;
                TosaSerializationHandler::ConvertU8toI8(ts->GetData(), tensor->getElementCount(), i8_data);
                std::vector<int32_t> i32_data(i8_data.begin(), i8_data.end());
                tensor->setTensorValueInt32(i32_data.size(), i32_data.data());
            }
            break;
            case DType_INT16: {
                std::vector<int16_t> i16_data;
                TosaSerializationHandler::ConvertU8toI16(ts->GetData(), tensor->getElementCount(), i16_data);
                std::vector<int32_t> i32_data(i16_data.begin(), i16_data.end());
                tensor->setTensorValueInt32(i32_data.size(), i32_data.data());
            }
            break;
            case DType_INT32: {
                std::vector<int32_t> i32_data;
                TosaSerializationHandler::ConvertU8toI32(ts->GetData(), tensor->getElementCount(), i32_data);
                tensor->setTensorValueInt32(i32_data.size(), i32_data.data());
            }
            break;
            case DType_INT48:
            case DType_SHAPE: {
                std::vector<int64_t> i64_data;
                TosaSerializationHandler::ConvertU8toI48(ts->GetData(), tensor->getElementCount(), i64_data);
                tensor->setTensorValueInt64(i64_data.size(), i64_data.data());
            }
            break;
            case DType_FP16: {
                // Interpret f16 data as float
                std::vector<float> f16_data;
                TosaSerializationHandler::ConvertU8toF16(ts->GetData(), tensor->getElementCount(), f16_data);
                if (tensor->getDtype() == TOSA_REF_TYPE_FP64)
                {
                    std::vector<double> f64_data(f16_data.begin(), f16_data.end());
                    tensor->setTensorValueDouble(f64_data.size(), f64_data.data());
                }
                else
                {
                    tensor->setTensorValueFloat(f16_data.size(), f16_data.data());
                }
            }
            break;
            case DType_BF16: {
                std::vector<float> fp32_data;
                TosaSerializationHandler::ConvertU8toF32(ts->GetData(), tensor->getElementCount(), fp32_data);
                // Ensure valid bfloat16 stored in each float
                for (auto f : fp32_data)
                    ASSERT_MSG(checkValidBFloat(f), "Float value %f not valid bfloat16", f);
                if (tensor->getDtype() == TOSA_REF_TYPE_FP64)
                {
                    std::vector<double> f64_data(fp32_data.begin(), fp32_data.end());
                    tensor->setTensorValueDouble(f64_data.size(), f64_data.data());
                }
                else
                {
                    tensor->setTensorValueFloat(fp32_data.size(), fp32_data.data());
                }
            }
            break;
            case DType_FP32: {
                std::vector<float> fp32_data;
                TosaSerializationHandler::ConvertU8toF32(ts->GetData(), tensor->getElementCount(), fp32_data);
                if (tensor->getDtype() == TOSA_REF_TYPE_FP64)
                {
                    std::vector<double> f64_data(fp32_data.begin(), fp32_data.end());
                    tensor->setTensorValueDouble(f64_data.size(), f64_data.data());
                }
                else
                {
                    tensor->setTensorValueFloat(fp32_data.size(), fp32_data.data());
                }
            }
            break;
            case DType_BOOL: {
                std::vector<bool> bool_data;
                TosaSerializationHandler::ConvertU8toBool(ts->GetData(), tensor->getElementCount(), bool_data);

                // std::vector<bool>::data() will return bit mask instead of array of bool array.
                // Need to translate manually.
                bool* bool_array = (bool*)calloc(bool_data.size(), sizeof(bool));
                for (size_t i = 0; i < bool_data.size(); i++)
                {
                    bool_array[i] = bool_data[i];
                }
                tensor->setTensorValueBool(bool_data.size(), bool_array);
            }
            break;
            default:
                SUBGRAPH_ERROR_IF(true, "SubgraphTraverser::initializeGraph(): Unsupported tensor type %s.",
                                  EnumNameDType(ts->GetDtype()));
        }
        tensor->setIsValid();
        // Push ready consumers to the next node list
        for (auto gn : tensor->getConsumers())
        {
            if (gn->hasAllInputsReady() && !gn->getOnNextNodeList() && !gn->getEvaluated())
            {
                addToNextNodeList(gn);
            }
        }
    }
    return 0;
}

int SubgraphTraverser::isFullyEvaluated() const
{
    return nextNodeList.empty();
}

GraphNode* SubgraphTraverser::getNextNode()
{
    GraphNode* nextNode = nextNodeList.front();
    ASSERT_MSG(nextNode, "SubgraphTraverser::getNextNode(): called with empty next node list");
    ASSERT_MSG(nextNode->getOnNextNodeList(),
               "SubgraphTraverser::getNextNode(): internal state error: node is not listed as being on next node list");

    nextNodeList.pop_front();

    nextNode->clearOnNextNodeList();
    return nextNode;
}

int SubgraphTraverser::addToNextNodeList(GraphNode* nextNode)
{
    ASSERT_MSG(nextNode, "SubgraphTraverser::addToNextNodeList(): called with no node");
    ASSERT_MSG(!nextNode->getOnNextNodeList(),
               "SubgraphTraverser::addToNextNodeList(): internal state error: node is already on next node list");

    nextNode->setOnNextNodeList();
    nextNodeList.push_back(nextNode);

    return 0;
}

int SubgraphTraverser::evaluateNextNode()
{
    if (isFullyEvaluated())
        return 0;

    GraphNode* currNode = getNextNode();

    DEBUG_INFO(GT, "Evaluating node_%03lu, %8s, output tensor=%s", currNode->getID(), EnumNamesOp()[currNode->getOp()],
               currNode->getOutputNames()[0].c_str());

    // Sanity check for never-ending loops
    if (currNode->getEvalCount() >= MAX_EVAL_COUNT && (currNode->getEvalCount() % MAX_EVAL_COUNT) == 0)
    {
        WARNING("SubgraphTraverser::evaluateNextNode(): Node %lu has been evaluated %d times.  Loop suspected.",
                currNode->getID(), currNode->getEvalCount());
    }

    for (auto tensor : currNode->getOutputs())
    {
        if (!tensor->is_allocated())
        {
            if (this->allocateTensor(tensor->getName()))
            {
                FATAL_ERROR("SubgraphTraverser::evaluateNextNode(): Failed to allocate Eigen tensor %s",
                            tensor->getName().c_str());
            }
        }
    }

    if (currNode->eval())
    {
        WARNING("SubgraphTraverser::evaluateNextNode(): Failed to evaluate node: %lu", currNode->getID());
        return 1;
    }

    currNode->setEvaluated();

    // free input tensor if all of its consumers have all of their outputs ready and it's not block's output
    for (auto tensor : currNode->getInputs())
    {
        bool in_use = false;

        auto tensor_check = findTensorByName(tensor->getName());
        if (tensor_check->getIsParentGraphOutput())
        {
            // if it's parent's block output tensor, we can't free it
            continue;
        }

        if (tensor->getIsVariable())
        {
            // if tensor is a Variable, we cannot free it
            continue;
        }

        for (auto node : tensor->getConsumers())
        {
            // If the node is inside a loop, the input tensor is still needed
            if (!node->hasAllOutputsReady())
            {
                in_use = true;
            }
        }

        for (auto name : block->GetOutputs())
        {
            if (name == tensor->getName())
            {
                in_use = true;
            }
        }

        if (!in_use)
        {
            tensor->deallocate();
        }
    }

    // Search the output tensors of this node to see if
    // there are now new ready nodes available from completing this node
    for (TosaReference::Tensor* tensor : currNode->getOutputs())
    {
        for (GraphNode* node : tensor->getConsumers())
        {
            if (!node->getOnNextNodeList() && node->hasAllInputsReady() && !node->getEvaluated())
            {
                addToNextNodeList(node);
            }
        }
    }

    if (DEBUG_ENABLED(DEBUG_VERB_HIGH, GT))
    {
        dumpNextNodeList(g_func_debug.func_debug_file);
    }

    if (g_func_config.dump_intermediates)
    {
        currNode->dumpNode(g_func_debug.func_debug_file);
        for (auto outs : currNode->getOutputs())
        {
            outs->dumpTensorParams(g_func_debug.func_debug_file);
            outs->dumpTensor(g_func_debug.func_debug_file);
            fprintf(g_func_debug.func_debug_file, "\n");
        }
    }

    return 0;
}

int SubgraphTraverser::dumpNextNodeList(FILE* out) const
{

    // Dump next node list
    fprintf(out, "Next node list\n");

    if (nextNodeList.empty())
    {
        fprintf(out, "<empty>\n");
    }

    for (auto gn : nextNodeList)
    {
        gn->dumpNode(out);
    }

    fprintf(out, "Done.\n");
    return 0;
}

int SubgraphTraverser::clearAllNodeMarkings()
{
    for (GraphNode* currNode : nodes)
    {
        currNode->clearNodeMarked();
    }

    return false;
}

int SubgraphTraverser::addTensor(const TosaSerializationTensor* ts)
{
    TosaReference::Tensor* tensor = nullptr;

    // variable tensors are shared: make new tensor only if not found
    if (ts->GetVariable())
    {
        tensor = getVariableTensorByName(ts->GetName());
    }

    if (!tensor)
    {
        DEBUG_INFO(GT, "Creating tensor %s", ts->GetName().c_str());
        tensor = TensorFactory::newTensor(ts->GetName(), ts->GetDtype(), ts->GetShape(), ts->GetShape().size());

        SUBGRAPH_ERROR_IF(!tensor, "SubgraphTraverser::initializeGraph(): Unsupported tensor name=%s, type=%s, rank=%d",
                          ts->GetName().c_str(), EnumNameDType(ts->GetDtype()), (int)ts->GetShape().size());

        if (ts->GetVariable())
        {
            tensor->setIsVariable();
            registerVariableTensor(tensor);
        }
    }

    // Enforce no duplicate tensors/tensor names
    // O(N), but the number of tensors is small
    for (TosaReference::Tensor* currTensor : tensors)
    {
        if (tensor == currTensor || currTensor->getName() == tensor->getName())
        {
            FATAL_ERROR("SubgraphTraverser::addTensor(): Duplicate tensor or tensor name being added to graph: %s\n",
                        tensor->getName().c_str());
            return 1;
        }
    }

    tensors.push_back(tensor);

    if (tensor->getIsSubgraphInput())
    {
        inputTensors.push_back(tensor);
    }

    if (tensor->getIsSubgraphOutput())
    {
        outputTensors.push_back(tensor);
    }

    return 0;
}
int SubgraphTraverser::addNode(GraphNode* newNode)
{
    // Enforce no duplicate nodes
    for (GraphNode* currNode : nodes)
    {
        if (currNode == newNode)
        {
            FATAL_ERROR("SubgraphTraverser::addNode(): duplicate node being added to graph");
            return 1;
        }
    }

    nodes.push_back(newNode);

    return 0;
}

TosaReference::Tensor* SubgraphTraverser::findTensorByName(const std::string& name) const
{
    TosaReference::Tensor* res_tensor = nullptr;

    for (TosaReference::Tensor* currTensor : tensors)
    {
        if (currTensor->getName() == name)
        {
            res_tensor = currTensor;
            return res_tensor;
        }
    }

    if (parent_sgt)
    {
        for (TosaReference::Tensor* currTensor : parent_sgt->tensors)
        {
            if (currTensor->getName() == name)
            {
                res_tensor = currTensor;
                res_tensor->setIsParentGraphOutput();
            }
        }
    }

    if (!res_tensor)
    {
        WARNING("SubgraphTraverser::findTensorByName(): Unable to find tensor with name: %s\n", name.c_str());
        return nullptr;
    }
    return res_tensor;
}

int SubgraphTraverser::linkTensorsAndNodes()
{
    // Nodes have a list of input/output tensor names
    // For each node, read this list, link up the tensors with their inputs/outputs
    for (GraphNode* currNode : nodes)
    {
        // Link inputs/consuming nodes
        for (std::string& name : currNode->getInputNames())
        {
            TosaReference::Tensor* t = findTensorByName(name);
            SUBGRAPH_ERROR_IF(!t, "SubgraphTraverser::linkTensorsAndNodes(): Cannot find tensor %s in node %lu\n",
                              name.c_str(), currNode->getID());
            SUBGRAPH_ERROR_IF(currNode->addInputTensor(t),
                              "SubgraphTraverser::linkTensorsAndNodes(): cannot link tensor %s to node %lu\n",
                              name.c_str(), currNode->getID());
            SUBGRAPH_ERROR_IF(t->addConsumer(currNode),
                              "SubgraphTraverser::linkTensorsAndNodes(): cannot link consumer node %lu to tensor %s\n",
                              currNode->getID(), name.c_str());
        }

        // Link outputs/producing nodes
        for (std::string& name : currNode->getOutputNames())
        {
            TosaReference::Tensor* t = findTensorByName(name);
            SUBGRAPH_ERROR_IF(!t, "SubgraphTraverser::linkTensorsAndNodes(): Cannot find tensor %s in node %lu\n",
                              name.c_str(), currNode->getID());
            SUBGRAPH_ERROR_IF(currNode->addOutputTensor(t),
                              "SubgraphTraverser::linkTensorsAndNodes(): cannot link tensor %s to node %lu\n",
                              name.c_str(), currNode->getID());

            SUBGRAPH_ERROR_IF(
                t->setProducer(currNode),
                "SubgraphTraverser::linkTensorsAndNodes(): cannot link producer node %lu to tensor tensor %s\n",
                currNode->getID(), name.c_str());
        }
    }

    return 0;
}

int SubgraphTraverser::validateGraph()
{
    // Need to make sure that:
    //   - each tensor is actually used
    //   - input and output tesnsors truly are just input and just output
    // Graph building already determined that each node has found its input/output tensors

    for (TosaReference::Tensor* currTensor : tensors)
    {
        // It's okay for block input tensor not being consumed by operators.
        // This is common in control flow op execution.
        if (!currTensor->getIsSubgraphInput())
        {
            if (!currTensor->getProducer() && currTensor->getConsumers().empty())
            {
                WARNING("SubgraphTraverser::validateGraph(): TosaReference::Tensor %s has no producers or consumers\n",
                        currTensor->getName().c_str());
                return 1;
            }
        }

        if (g_func_config.tosa_profile == 0)
        {
            TOSA_REF_TYPE dtype = currTensor->getDtype();

            // Float-point disallowed
            if (dtype == TOSA_REF_TYPE_FP32 || dtype == TOSA_REF_TYPE_FP16)
            {
                WARNING("SubgraphTraverser::validateGraph(): TOSA Base Inference profile selected: All floating point "
                        "disabled, but %s tensor %s found\n",
                        EnumNameTOSAREFTYPE(dtype), currTensor->getName().c_str());
                return 1;
            }
        }
        else if (g_func_config.tosa_profile == 1 || g_func_config.tosa_profile == 2)
        {
            // Do nothing. All FP types allowed
            // Currently no implementation difference between Main Inference and Main Training modes
        }
        else
        {
            FATAL_ERROR("SubgraphTraverser::validateGraph(): TOSA profile not recognized: %d",
                        g_func_config.tosa_profile);
        }
    }

    for (GraphNode* currNode : nodes)
    {
        SUBGRAPH_ERROR_IF(currNode->checkTensorAttributes(),
                          "SubgraphTraverser::validateGraph(): TosaReference::Tensor attribute check failed");
    }

    if (outputTensors.size() <= 0)
    {
        DEBUG_MED(GT, "Graph output tensor empty");
        return 0;
    }

    return 0;
}

int SubgraphTraverser::dumpGraph(FILE* out) const
{
    int i = 0;

    fprintf(out, "Full graph dump:\n");
    for (GraphNode* currNode : nodes)
    {
        fprintf(out, "Node [%d]: ", i++);
        currNode->dumpNode(out);
    }

    return 0;
}

int SubgraphTraverser::evaluateAll()
{
    // evaluation loop
    while (!isFullyEvaluated())
    {
        if (evaluateNextNode())
        {
            return 1;
        }
    }

    return 0;
}
