/*
 * Copyright (c) 2019-2021 Arm Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "arm_compute/graph.h"
#include "arm_compute/graph/Types.h"
#include "support/ToolchainSupport.h"
#include "utils/CommonGraphOptions.h"
#include "utils/GraphUtils.h"
#include "utils/Utils.h"

using namespace arm_compute::utils;
using namespace arm_compute::graph;
using namespace arm_compute::graph::frontend;
using namespace arm_compute::graph_utils;

/** Example demonstrating how to implement DeepSpeech v0.4.1's network using the Compute Library's graph API */
class GraphDeepSpeechExample : public Example
{
public:
    GraphDeepSpeechExample()
        : cmd_parser(), common_opts(cmd_parser), common_params(), graph(0, "DeepSpeech v0.4.1")
    {
    }
    bool do_setup(int argc, char **argv) override
    {
        // Parse arguments
        cmd_parser.parse(argc, argv);
        cmd_parser.validate();

        // Consume common parameters
        common_params = consume_common_graph_parameters(common_opts);

        // Return when help menu is requested
        if(common_params.help)
        {
            cmd_parser.print_help(argv[0]);
            return false;
        }

        // Print parameter values
        std::cout << common_params << std::endl;

        // Get trainable parameters data path
        std::string       data_path  = common_params.data_path;
        const std::string model_path = "/cnn_data/deepspeech_model/";

        if(!data_path.empty())
        {
            data_path += model_path;
        }

        // How many timesteps to process at once, higher values mean more latency
        // Notice that this corresponds to the number of LSTM cells that will be instantiated
        const unsigned int n_steps = 16;

        // ReLU clipping value for non-recurrent layers
        const float cell_clip = 20.f;

        // Create input descriptor
        const TensorShape tensor_shape     = permute_shape(TensorShape(26U, 19U, n_steps, 1U), DataLayout::NHWC, common_params.data_layout);
        TensorDescriptor  input_descriptor = TensorDescriptor(tensor_shape, common_params.data_type).set_layout(common_params.data_layout);

        // Set weights trained layout
        const DataLayout weights_layout = DataLayout::NHWC;

        graph << common_params.target
              << common_params.fast_math_hint
              << InputLayer(input_descriptor,
                            get_weights_accessor(data_path, "input_values_x" + std::to_string(n_steps) + ".npy", weights_layout))
              .set_name("input_node");

        if(common_params.data_layout == DataLayout::NCHW)
        {
            graph << PermuteLayer(PermutationVector(2U, 0U, 1U), common_params.data_layout).set_name("permute_to_nhwc");
        }

        graph << ReshapeLayer(TensorShape(494U, n_steps)).set_name("Reshape_input")
              // Layer 1
              << FullyConnectedLayer(
                  2048U,
                  get_weights_accessor(data_path, "h1_transpose.npy", weights_layout),
                  get_weights_accessor(data_path, "MatMul_bias.npy"))
              .set_name("fc0")
              << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, cell_clip))
              .set_name("Relu")
              // Layer 2
              << FullyConnectedLayer(
                  2048U,
                  get_weights_accessor(data_path, "h2_transpose.npy", weights_layout),
                  get_weights_accessor(data_path, "MatMul_1_bias.npy"))
              .set_name("fc1")
              << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, cell_clip))
              .set_name("Relu_1")
              // Layer 3
              << FullyConnectedLayer(
                  2048U,
                  get_weights_accessor(data_path, "h3_transpose.npy", weights_layout),
                  get_weights_accessor(data_path, "MatMul_2_bias.npy"))
              .set_name("fc2")
              << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, cell_clip))
              .set_name("Relu_2")
              // Layer 4
              << ReshapeLayer(TensorShape(2048U, 1U, n_steps)).set_name("Reshape_1");

        // Unstack Layer (using SplitLayerNode)
        NodeParams unstack_params = { "unstack", graph.hints().target_hint };
        NodeID     unstack_nid    = GraphBuilder::add_split_node(graph.graph(), unstack_params, { graph.tail_node(), 0 }, n_steps, 2);

        // Create input state descriptor
        TensorDescriptor state_descriptor = TensorDescriptor(TensorShape(2048U), common_params.data_type).set_layout(common_params.data_layout);
        SubStream        previous_state(graph);
        SubStream        add_y(graph);

        // Initial state for LSTM is all zeroes for both state_h and state_c, therefore only one input is created
        previous_state << InputLayer(state_descriptor,
                                     get_weights_accessor(data_path, "zeros.npy"))
                       .set_name("previous_state_c_h");
        add_y << InputLayer(state_descriptor,
                            get_weights_accessor(data_path, "ones.npy"))
              .set_name("add_y");

        // Create LSTM Fully Connected weights and bias descriptors
        TensorDescriptor lstm_weights_descriptor = TensorDescriptor(TensorShape(4096U, 8192U), common_params.data_type).set_layout(common_params.data_layout);
        TensorDescriptor lstm_bias_descriptor    = TensorDescriptor(TensorShape(8192U), common_params.data_type).set_layout(common_params.data_layout);
        SubStream        lstm_fc_weights(graph);
        SubStream        lstm_fc_bias(graph);
        lstm_fc_weights << ConstantLayer(lstm_weights_descriptor,
                                         get_weights_accessor(data_path, "rnn_lstm_cell_kernel_transpose.npy", weights_layout))
                        .set_name("h5/transpose");
        lstm_fc_bias << ConstantLayer(lstm_bias_descriptor,
                                      get_weights_accessor(data_path, "rnn_lstm_cell_MatMul_bias.npy"))
                     .set_name("MatMul_3_bias");

        // LSTM Block
        std::pair<SubStream, SubStream> new_state_1  = add_lstm_cell(unstack_nid, 0, previous_state, previous_state, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_2  = add_lstm_cell(unstack_nid, 1, new_state_1.first, new_state_1.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_3  = add_lstm_cell(unstack_nid, 2, new_state_2.first, new_state_2.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_4  = add_lstm_cell(unstack_nid, 3, new_state_3.first, new_state_3.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_5  = add_lstm_cell(unstack_nid, 4, new_state_4.first, new_state_4.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_6  = add_lstm_cell(unstack_nid, 5, new_state_5.first, new_state_5.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_7  = add_lstm_cell(unstack_nid, 6, new_state_6.first, new_state_6.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_8  = add_lstm_cell(unstack_nid, 7, new_state_7.first, new_state_7.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_9  = add_lstm_cell(unstack_nid, 8, new_state_8.first, new_state_8.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_10 = add_lstm_cell(unstack_nid, 9, new_state_9.first, new_state_9.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_11 = add_lstm_cell(unstack_nid, 10, new_state_10.first, new_state_10.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_12 = add_lstm_cell(unstack_nid, 11, new_state_11.first, new_state_11.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_13 = add_lstm_cell(unstack_nid, 12, new_state_12.first, new_state_12.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_14 = add_lstm_cell(unstack_nid, 13, new_state_13.first, new_state_13.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_15 = add_lstm_cell(unstack_nid, 14, new_state_14.first, new_state_14.second, add_y, lstm_fc_weights, lstm_fc_bias);
        std::pair<SubStream, SubStream> new_state_16 = add_lstm_cell(unstack_nid, 15, new_state_15.first, new_state_15.second, add_y, lstm_fc_weights, lstm_fc_bias);

        // Concatenate new states on height
        const int axis = 1;
        graph << StackLayer(axis,
                            std::move(new_state_1.second),
                            std::move(new_state_2.second),
                            std::move(new_state_3.second),
                            std::move(new_state_4.second),
                            std::move(new_state_5.second),
                            std::move(new_state_6.second),
                            std::move(new_state_7.second),
                            std::move(new_state_8.second),
                            std::move(new_state_9.second),
                            std::move(new_state_10.second),
                            std::move(new_state_11.second),
                            std::move(new_state_12.second),
                            std::move(new_state_13.second),
                            std::move(new_state_14.second),
                            std::move(new_state_15.second),
                            std::move(new_state_16.second))
              .set_name("concat");

        graph << FullyConnectedLayer(
                  2048U,
                  get_weights_accessor(data_path, "h5_transpose.npy", weights_layout),
                  get_weights_accessor(data_path, "MatMul_3_bias.npy"))
              .set_name("fc3")
              << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, cell_clip))
              .set_name("Relu3")
              << FullyConnectedLayer(
                  29U,
                  get_weights_accessor(data_path, "h6_transpose.npy", weights_layout),
                  get_weights_accessor(data_path, "MatMul_4_bias.npy"))
              .set_name("fc3")
              << SoftmaxLayer().set_name("logits");

        graph << OutputLayer(get_output_accessor(common_params, 5));

        // Finalize graph
        GraphConfig config;
        config.num_threads        = common_params.threads;
        config.use_tuner          = common_params.enable_tuner;
        config.tuner_file         = common_params.tuner_file;
        config.mlgo_file          = common_params.mlgo_file;
        config.use_synthetic_type = arm_compute::is_data_type_quantized(common_params.data_type);
        config.synthetic_type     = common_params.data_type;

        graph.finalize(common_params.target, config);

        return true;
    }
    void do_run() override
    {
        // Run graph
        graph.run();
    }

private:
    CommandLineParser  cmd_parser;
    CommonGraphOptions common_opts;
    CommonGraphParams  common_params;
    Stream             graph;

    Status set_node_params(Graph &g, NodeID nid, NodeParams &params)
    {
        INode *node = g.node(nid);
        ARM_COMPUTE_RETURN_ERROR_ON(!node);

        node->set_common_node_parameters(params);

        return Status{};
    }

    std::pair<SubStream, SubStream> add_lstm_cell(NodeID unstack_nid,
                                                  unsigned int unstack_idx,
                                                  SubStream    previous_state_c,
                                                  SubStream    previous_state_h,
                                                  SubStream    add_y,
                                                  SubStream    lstm_fc_weights,
                                                  SubStream    lstm_fc_bias)
    {
        const std::string         cell_name("rnn/lstm_cell_" + std::to_string(unstack_idx));
        const DataLayoutDimension concat_dim = (common_params.data_layout == DataLayout::NHWC) ? DataLayoutDimension::CHANNEL : DataLayoutDimension::WIDTH;

        // Concatenate result of Unstack with previous_state_h
        NodeParams concat_params = { cell_name + "/concat", graph.hints().target_hint };
        NodeID     concat_nid    = graph.graph().add_node<ConcatenateLayerNode>(2, concat_dim);
        graph.graph().add_connection(unstack_nid, unstack_idx, concat_nid, 0);
        graph.graph().add_connection(previous_state_h.tail_node(), 0, concat_nid, 1);
        set_node_params(graph.graph(), concat_nid, concat_params);
        graph.forward_tail(concat_nid);

        graph << FullyConnectedLayer(
                  8192U,
                  lstm_fc_weights,
                  lstm_fc_bias)
              .set_name(cell_name + "/BiasAdd");

        // Split Layer
        const unsigned int num_splits = 4;
        const unsigned int split_axis = 0;

        NodeParams split_params = { cell_name + "/split", graph.hints().target_hint };
        NodeID     split_nid    = GraphBuilder::add_split_node(graph.graph(), split_params, { graph.tail_node(), 0 }, num_splits, split_axis);

        NodeParams sigmoid_1_params = { cell_name + "/Sigmoid_1", graph.hints().target_hint };
        NodeParams add_params       = { cell_name + "/add", graph.hints().target_hint };
        NodeParams sigmoid_2_params = { cell_name + "/Sigmoid_2", graph.hints().target_hint };
        NodeParams tanh_params      = { cell_name + "/Tanh", graph.hints().target_hint };

        // Sigmoid 1 (first split)
        NodeID sigmoid_1_nid = graph.graph().add_node<ActivationLayerNode>(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC));
        graph.graph().add_connection(split_nid, 0, sigmoid_1_nid, 0);
        set_node_params(graph.graph(), sigmoid_1_nid, sigmoid_1_params);

        // Tanh (second split)
        NodeID tanh_nid = graph.graph().add_node<ActivationLayerNode>(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::TANH, 1.f, 1.f));
        graph.graph().add_connection(split_nid, 1, tanh_nid, 0);
        set_node_params(graph.graph(), tanh_nid, tanh_params);

        SubStream tanh_ss(graph);
        tanh_ss.forward_tail(tanh_nid);

        // Add (third split)
        NodeID add_nid = graph.graph().add_node<EltwiseLayerNode>(descriptors::EltwiseLayerDescriptor{ EltwiseOperation::Add });
        graph.graph().add_connection(split_nid, 2, add_nid, 0);
        graph.graph().add_connection(add_y.tail_node(), 0, add_nid, 1);
        set_node_params(graph.graph(), add_nid, add_params);

        // Sigmoid 2 (fourth split)
        NodeID sigmoid_2_nid = graph.graph().add_node<ActivationLayerNode>(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC));
        graph.graph().add_connection(split_nid, 3, sigmoid_2_nid, 0);
        set_node_params(graph.graph(), sigmoid_2_nid, sigmoid_2_params);

        SubStream sigmoid_1_ss(graph);
        sigmoid_1_ss.forward_tail(sigmoid_1_nid);
        SubStream mul_1_ss(sigmoid_1_ss);
        mul_1_ss << EltwiseLayer(std::move(sigmoid_1_ss), std::move(tanh_ss), EltwiseOperation::Mul)
                 .set_name(cell_name + "/mul_1");

        SubStream tanh_1_ss_tmp(graph);
        tanh_1_ss_tmp.forward_tail(add_nid);

        tanh_1_ss_tmp << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC))
                      .set_name(cell_name + "/Sigmoid");
        SubStream tanh_1_ss_tmp2(tanh_1_ss_tmp);
        tanh_1_ss_tmp2 << EltwiseLayer(std::move(tanh_1_ss_tmp), std::move(previous_state_c), EltwiseOperation::Mul)
                       .set_name(cell_name + "/mul");
        SubStream tanh_1_ss(tanh_1_ss_tmp2);
        tanh_1_ss << EltwiseLayer(std::move(tanh_1_ss_tmp2), std::move(mul_1_ss), EltwiseOperation::Add)
                  .set_name(cell_name + "/new_state_c");
        SubStream new_state_c(tanh_1_ss);

        tanh_1_ss << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::TANH, 1.f, 1.f))
                  .set_name(cell_name + "/Tanh_1");

        SubStream sigmoid_2_ss(graph);
        sigmoid_2_ss.forward_tail(sigmoid_2_nid);
        graph << EltwiseLayer(std::move(sigmoid_2_ss), std::move(tanh_1_ss), EltwiseOperation::Mul)
              .set_name(cell_name + "/new_state_h");

        SubStream new_state_h(graph);
        return std::pair<SubStream, SubStream>(new_state_c, new_state_h);
    }
};

/** Main program for DeepSpeech v0.4.1
 *
 * Model is based on:
 *      https://arxiv.org/abs/1412.5567
 *      "Deep Speech: Scaling up end-to-end speech recognition"
 *      Awni Hannun, Carl Case, Jared Casper, Bryan Catanzaro, Greg Diamos, Erich Elsen, Ryan Prenger, Sanjeev Satheesh, Shubho Sengupta, Adam Coates, Andrew Y. Ng
 *
 * Provenance: https://github.com/mozilla/DeepSpeech
 *
 * @note To list all the possible arguments execute the binary appended with the --help option
 *
 * @param[in] argc Number of arguments
 * @param[in] argv Arguments
 *
 * @return Return code
 */
int main(int argc, char **argv)
{
    return arm_compute::utils::run_example<GraphDeepSpeechExample>(argc, argv);
}
