// Copyright 2021 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "iree/base/api.h"
#include "iree/base/internal/flags.h"
#include "iree/base/internal/path.h"
#include "iree/hal/api.h"
#include "iree/tooling/device_util.h"
#include "iree/tooling/trace_replay.h"
#include "iree/tooling/vm_util.h"
#include "iree/tooling/yaml_util.h"
#include "iree/vm/api.h"

IREE_FLAG(bool, trace_execution, false, "Traces VM execution to stderr.");

IREE_FLAG(bool, print_statistics, false,
          "Prints runtime statistics to stderr on exit.");

IREE_FLAG(bool, print_calls, false, "Prints all I/O for each call to stdout.");
IREE_FLAG(bool, print_call_inputs, false,
          "Prints all inputs for each call before they are made to stdout.");
IREE_FLAG(bool, print_call_outputs, false,
          "Prints all outputs for each call after they are made to stdout.");

IREE_FLAG_LIST(
    string, input,
    "An input (a) value or (b) buffer of the format:\n"
    "  (a) scalar value\n"
    "     value\n"
    "     e.g.: --input=\"3.14\"\n"
    "  (b) buffer:\n"
    "     [shape]xtype=[value]\n"
    "     e.g.: --input=\"2x2xi32=1 2 3 4\"\n"
    "Optionally, brackets may be used to separate the element values:\n"
    "  2x2xi32=[[1 2][3 4]]\n"
    "Raw binary files can be read to provide buffer contents:\n"
    "  2x2xi32=@some/file.bin\n"
    "\n"
    "Numpy npy files from numpy.save can be read to provide 1+ values:\n"
    "  @some.npy\n"
    "\n"
    "Each occurrence of the flag indicates an input in the order they were\n"
    "specified on the command line.");

IREE_FLAG_LIST(
    string, output,
    "Specifies how to handle an output from the invocation:\n"
    "  `` (empty): ignore output\n"
    "     e.g.: --output=\n"
    "  `-`: print textual form to stdout\n"
    "     e.g.: --output=-\n"
    "  `@file.npy`: create/overwrite a numpy npy file and write buffer view\n"
    "     e.g.: --output=@file.npy\n"
    "  `+file.npy`: create/append a numpy npy file and write buffer view\n"
    "     e.g.: --output=+file.npy\n"
    "\n"
    "Numpy npy files can be read in Python using numpy.load, for example an\n"
    "invocation producing two outputs can be concatenated as:\n"
    "    --output=@file.npy --output=+file.npy\n"
    "And then loaded in Python by reading from the same file:\n"
    "  with open('file.npy', 'rb') as f:\n"
    "    print(numpy.load(f))\n"
    "    print(numpy.load(f))\n"
    "\n"
    "Each occurrence of the flag indicates an output in the order they were\n"
    "specified on the command line.");

IREE_FLAG_LIST(string, expected_output,
               "An expected function output following the same format as "
               "--input. When present the results of the "
               "invocation will be compared against these values and the "
               "tool will return non-zero if any differ. If the value of a "
               "particular output is not of interest provide `(ignored)`.");

IREE_FLAG(int32_t, output_max_element_count, 1024,
          "Prints up to the maximum number of elements of output tensors, "
          "eliding the remainder.");

static iree_status_t iree_trace_replay_call_before(void* user_data,
                                                   iree_trace_replay_t* replay,
                                                   yaml_document_t* document,
                                                   yaml_node_t* event_node,
                                                   iree_vm_function_t function,
                                                   iree_vm_list_t* input_list) {
  if (FLAG_print_calls || FLAG_print_call_inputs) {
    iree_string_view_t function_name = iree_vm_function_name(&function);
    fprintf(stdout, "--- CALL[%.*s] ---\n", (int)function_name.size,
            function_name.data);
    IREE_RETURN_IF_ERROR(iree_tooling_variant_list_fprint(
        IREE_SV("arg"), input_list,
        (iree_host_size_t)FLAG_output_max_element_count, stdout));
  }
  return iree_ok_status();
}

static iree_status_t iree_trace_replay_call_after(void* user_data,
                                                  iree_trace_replay_t* replay,
                                                  yaml_document_t* document,
                                                  yaml_node_t* event_node,
                                                  iree_vm_function_t function,
                                                  iree_vm_list_t* output_list) {
  if (FLAG_print_calls || FLAG_print_call_outputs) {
    if (!FLAG_print_calls && !FLAG_print_call_inputs) {
      iree_string_view_t function_name = iree_vm_function_name(&function);
      fprintf(stdout, "--- CALL[%.*s] ---\n", (int)function_name.size,
              function_name.data);
    }
    IREE_RETURN_IF_ERROR(iree_tooling_variant_list_fprint(
        IREE_SV("result"), output_list,
        (iree_host_size_t)FLAG_output_max_element_count, stdout));
  }
  return iree_ok_status();
}

// Runs the trace in |file| using |root_path| as the base for any path lookups
// required for external files referenced in |file|.
static iree_status_t iree_run_trace_file(iree_string_view_t root_path,
                                         FILE* file,
                                         iree_vm_instance_t* instance) {
  iree_trace_replay_t replay;
  IREE_RETURN_IF_ERROR(iree_trace_replay_initialize(
      root_path, instance,
      FLAG_trace_execution ? IREE_VM_CONTEXT_FLAG_TRACE_EXECUTION
                           : IREE_VM_CONTEXT_FLAG_NONE,
      iree_hal_available_driver_registry(), iree_allocator_system(), &replay));

  // Hook into all calls processed during the trace.
  replay.call_hooks.user_data = NULL;
  replay.call_hooks.before = iree_trace_replay_call_before;
  replay.call_hooks.after = iree_trace_replay_call_after;

  // Query device overrides, if any. When omitted the devices from the trace
  // file will be used.
  // TODO(#5724): remove this and instead provide a device set on initialize.
  iree_host_size_t device_uri_count = 0;
  const iree_string_view_t* device_uris = NULL;
  iree_hal_get_devices_flag_list(&device_uri_count, &device_uris);
  iree_trace_replay_set_hal_devices_override(&replay, device_uri_count,
                                             device_uris);

  yaml_parser_t parser;
  if (!yaml_parser_initialize(&parser)) {
    iree_trace_replay_deinitialize(&replay, IREE_TRACE_REPLAY_SHUTDOWN_QUIET);
    return iree_make_status(IREE_STATUS_INTERNAL,
                            "yaml_parser_initialize failed");
  }
  yaml_parser_set_input_file(&parser, file);

  bool have_parsed_inputs = false;
  iree_status_t status = iree_ok_status();
  for (bool document_eof = false; !document_eof;) {
    // Parse the subdocument event.
    yaml_document_t document;
    if (!yaml_parser_load(&parser, &document)) {
      status = iree_status_from_yaml_parser_error(&parser);
      break;
    }

    // Execute the event or handle EOF (empty document).
    yaml_node_t* event_node = yaml_document_get_root_node(&document);
    if (event_node) {
      status = iree_trace_replay_event(&replay, &document, event_node);
    } else {
      document_eof = true;
    }

    // Reclaim subdocument resources before moving on to the next.
    yaml_document_delete(&document);
    if (!iree_status_is_ok(status)) break;

    // If the event created a device and we haven't yet performed our input
    // loading we can do that now before processing subsequent events.
    if (!have_parsed_inputs && replay.device) {
      status = iree_tooling_parse_into_variant_list(
          iree_hal_device_allocator(replay.device), FLAG_input_list().values,
          FLAG_input_list().count, replay.host_allocator, replay.inputs);
      have_parsed_inputs = true;
    }
    if (!iree_status_is_ok(status)) break;
  }

  yaml_parser_delete(&parser);

  // Optionally process outputs from the replay session.
  if (iree_status_is_ok(status)) {
    if (FLAG_output_list().count == 0) {
      IREE_RETURN_IF_ERROR(
          iree_tooling_variant_list_fprint(
              IREE_SV("output"), replay.outputs,
              (iree_host_size_t)FLAG_output_max_element_count, stdout),
          "printing results");
    } else {
      IREE_RETURN_IF_ERROR(
          iree_tooling_output_variant_list(
              replay.outputs, FLAG_output_list().values,
              FLAG_output_list().count,
              (iree_host_size_t)FLAG_output_max_element_count, stdout),
          "outputting results");
    }
  }

  iree_trace_replay_deinitialize(
      &replay, FLAG_print_statistics
                   ? IREE_TRACE_REPLAY_SHUTDOWN_PRINT_STATISTICS
                   : IREE_TRACE_REPLAY_SHUTDOWN_QUIET);
  return status;
}

// Runs each of the given traces files sequentially in isolated contexts.
static iree_status_t iree_run_trace_files(int file_count, char** file_paths,
                                          iree_vm_instance_t* instance) {
  for (int i = 0; i < file_count; ++i) {
    iree_string_view_t file_path = iree_make_cstring_view(file_paths[i]);
    iree_string_view_t root_path = iree_file_path_dirname(file_path);
    FILE* file = fopen(file_paths[i], "rb");
    if (!file) {
      return iree_make_status(iree_status_code_from_errno(errno),
                              "failed to open trace file '%.*s'",
                              (int)file_path.size, file_path.data);
    }
    iree_status_t status = iree_run_trace_file(root_path, file, instance);
    fclose(file);
    IREE_RETURN_IF_ERROR(status, "replaying trace file '%.*s'",
                         (int)file_path.size, file_path.data);
  }
  return iree_ok_status();
}

int main(int argc, char** argv) {
  iree_flags_set_usage(
      "iree-run-trace",
      "Executes a YAML trace file containing a sequence of context operations\n"
      "and calls represented as subdocuments.\n"
      "\n"
      "Example loading a bytecode module and calling a function:\n"
      "\n"
      "```yaml\n"
      "type: context_load\n"
      "---\n"
      "type: module_load\n"
      "module:\n"
      "  type: buildin\n"
      "  name: hal\n"
      "---\n"
      "type: module_load\n"
      "module:\n"
      "  type: bytecode\n"
      "  path: ../build/some_module.vmfb\n"
      "---\n"
      "type: call\n"
      "function: module.mul\n"
      "args:\n"
      "- !input.take 0\n"
      "- !input.take 1\n"
      "results:\n"
      "- !output.push\n"
      "- !output.push\n"
      "```\n"
      "\n"
      "This can be invoked like iree-run-module specifying inputs/outputs:\n"
      "  iree-run-trace trace.yml    \\\n"
      "      --device=local-sync     \\\n"
      "      --input=4xf32=0,1,2,3,4 \\\n"
      "      --input=@input1.npy     \\\n"
      "      --output=@outputs.npy   \\\n"
      "      --output=+outputs.npy\n"
      "\n"
      "In addition to `--input=`/`--output=` flag access a user-defined\n"
      "blackboard exists for preserving temporary values used within the\n"
      "trace. Blackboard slots are defined by ordinal and they can be used\n"
      "in any context and input/output can be, `!blackboard.get` instead of\n"
      "`!input.get` and `!blackboard.set` instead of `!output.set`.\n"
      "\n"
      "--- Events ---\n"
      "\n"
      "`type: context_load`\n"
      "Loads an empty VM context with no modules registered.\n"
      "\n"
      "`type: module_load`\n"
      "Loads a module into the current context. Modules may either be\n"
      "`builtin` (compiled into the binary) or dynamically-loaded `bytecode`.\n"
      "\n"
      "`type: blackboard_clear`\n"
      "Clears the contents of the blackboard and resets it to 0 elements.\n"
      "\n"
      "`type: assign`\n"
      "Assigns sources from a `from` sequence to targets in a `to` sequence.\n"
      "Equivalent to an identity function call and can be used to move\n"
      "between inputs, outputs, and the blackboard.\n"
      "\n"
      "`type: numpy_load`\n"
      "Loads one or more ndarrays from a .npy value. Each array has a target\n"
      "where the array will be retained such as `!blackboard.set 2`.\n"
      "\n"
      "`type: numpy_save\n"
      "Saves one or more ndarrays to a .npy value. Each array has a source\n"
      "where the array will be taken from such as `!blackboard.get 2`.\n"
      "\n"
      "`type: call`\n"
      "Invokes a function in the context by fully-qualified `function` name.\n"
      "Uses arguments from an `args` sequence and produces results into a\n"
      "`results` sequence.\n"
      "\n"
      "--- Sources ---\n"
      "\n"
      "`type: null`\n"
      "A null ref value.\n"
      "\n"
      "`!hal.buffer_view 4xf32=0,1,2,3`\n"
      "A constant iree_hal_buffer_view_t/!hal.buffer_view value using the\n"
      "same formatting as iree-run-module's `--input=` flag.\n"
      "\n"
      "`!hal.buffer 4xf32=0,1,2,3`\n"
      "An initialized iree_hal_buffer_t/!hal.buffer without the wrapping view\n"
      "metadata.\n"
      "\n"
      "`!input.get ORDINAL` / `!input.take ORDINAL`\n"
      "Returns a reference to `--input=` flag at ORDINAL. Note that a single\n"
      "npy file may expand to multiple inputs. The `take` variant transfers\n"
      "ownership and clears the slot in the list and is recommended to avoid\n"
      "keeping unneeded inputs around for the duration of the trace.\n"
      "\n"
      "`!output.get ORDINAL` / `!output.take ORDINAL`\n"
      "Returns a reference to the `--output=` flag at ORDINAL. These are\n"
      "initially empty until assigned by the trace.\n"
      "\n"
      "`!blackboard.get ORDINAL` / `!blackboard.take ORDINAL`\n"
      "Returns a reference to the blackboard slot ORDINAL. The blackboard is\n"
      "initially empty and slots must be assigned in order to define them.\n"
      "The `take` variant transfers ownership and clears the slot in the\n"
      "blackboard and is recommended to avoid keeping large resources live\n"
      "in the blackboard longer than they need to be.\n"
      "\n"
      "--- Targets ---\n"
      "\n"
      "`!output.set ORDINAL` / `!output.push`\n"
      "Sets the `--output=` flag result value at ORDINAL or pushes it to the\n"
      "back of the output list. Outputs can either be dumped to files or by\n"
      "default printed to stdout.\n"
      "\n"
      "`!blackboard.set ORDINAL` / `blackboard.push`\n"
      "Sets the value of the blackboard slot ORDINAL or pushes it to the back\n"
      "of the blackboard list. Blackboard values will be retained until they\n"
      "are consumed via `!blackboard.take` or the blackboard is cleared.\n"
      "\n");
  iree_flags_parse_checked(IREE_FLAGS_PARSE_MODE_DEFAULT, &argc, &argv);
  if (argc <= 1) {
    fprintf(stderr,
            "no trace files provided; pass one or more yaml file paths");
    return 1;
  }

  iree_vm_instance_t* instance = NULL;
  iree_status_t status =
      iree_vm_instance_create(iree_allocator_system(), &instance);
  if (iree_status_is_ok(status)) {
    status = iree_run_trace_files(argc - 1, argv + 1, instance);
  }
  iree_vm_instance_release(instance);
  if (!iree_status_is_ok(status)) {
    iree_status_fprint(stderr, status);
    iree_status_free(status);
    return 1;
  }
  return 0;
}
