// Copyright 2023 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 "iree/base/api.h"
#include "iree/base/internal/file_io.h"
#include "iree/schemas/instruments/dispatch.h"

// NOTE: include order matters:
#include "iree/base/internal/flatcc/parsing.h"
#include "iree/schemas/instruments/dispatch_def_reader.h"

typedef struct {
  iree_instruments_DispatchFunctionDef_vec_t functions_def;
  iree_instruments_DispatchSiteDef_vec_t dispatch_sites_def;
} iree_dispatch_metadata_t;

static iree_status_t iree_tooling_dump_dispatch_metadata(
    const uint8_t* flatbuffer_ptr, iree_host_size_t flatbuffer_size,
    iree_dispatch_metadata_t* out_metadata, FILE* stream) {
  memset(out_metadata, 0, sizeof(*out_metadata));

  iree_instruments_DispatchInstrumentDef_table_t instr_def =
      iree_instruments_DispatchInstrumentDef_as_root(flatbuffer_ptr);

  iree_instruments_DispatchFunctionDef_vec_t functions_def =
      iree_instruments_DispatchInstrumentDef_functions(instr_def);
  out_metadata->functions_def = functions_def;
  for (iree_host_size_t i = 0;
       i < iree_instruments_DispatchFunctionDef_vec_len(functions_def); ++i) {
    fprintf(stream, "\n");
    iree_instruments_DispatchFunctionDef_table_t function_def =
        iree_instruments_DispatchFunctionDef_vec_at(functions_def, i);
    flatbuffers_string_t name =
        iree_instruments_DispatchFunctionDef_name(function_def);
    fprintf(stream,
            "//"
            "===---------------------------------------------------------------"
            "-------===//\n");
    fprintf(stream, "// export[%" PRIhsz "]: %s\n", i, name);
    fprintf(stream,
            "//"
            "===---------------------------------------------------------------"
            "-------===//\n");
    flatbuffers_string_t target =
        iree_instruments_DispatchFunctionDef_target(function_def);
    if (target) fprintf(stream, "//  target: %s\n", target);
    flatbuffers_string_t layout =
        iree_instruments_DispatchFunctionDef_layout(function_def);
    if (layout) fprintf(stream, "//  layout: %s\n", layout);
    flatbuffers_string_t source =
        iree_instruments_DispatchFunctionDef_source(function_def);
    if (source) fprintf(stream, "%s\n", source);
    fprintf(stream, "\n");
  }

  fprintf(stream,
          "//"
          "===---------------------------------------------------------------"
          "-------===//\n");
  iree_instruments_DispatchSiteDef_vec_t dispatch_sites_def =
      iree_instruments_DispatchInstrumentDef_sites(instr_def);
  out_metadata->dispatch_sites_def = dispatch_sites_def;
  for (iree_host_size_t i = 0;
       i < iree_instruments_DispatchSiteDef_vec_len(dispatch_sites_def); ++i) {
    iree_instruments_DispatchSiteDef_table_t dispatch_site_def =
        iree_instruments_DispatchSiteDef_vec_at(dispatch_sites_def, i);
    iree_instruments_DispatchFunctionDef_table_t function_def =
        iree_instruments_DispatchFunctionDef_vec_at(
            functions_def,
            iree_instruments_DispatchSiteDef_function(dispatch_site_def));
    flatbuffers_string_t name =
        iree_instruments_DispatchFunctionDef_name(function_def);
    fprintf(stream, "// dispatch site %" PRIhsz ": %s\n", i, name);
  }
  fprintf(stream,
          "//"
          "===---------------------------------------------------------------"
          "-------===//\n\n");

  return iree_ok_status();
}

static void iree_tooling_dump_print_value(
    iree_instrument_dispatch_value_type_t type, uint64_t raw_value,
    FILE* stream) {
  union {
    int8_t i8;
    int16_t i16;
    int32_t i32;
    int64_t i64;
    float f32;
    double f64;
    uint8_t value_storage[sizeof(uint64_t)];
  } value = {.i64 = raw_value};
  switch (type) {
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_SINT_8:
      fprintf(stream, "%" PRId8, value.i8);
      break;
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_UINT_8:
      fprintf(stream, "%" PRIu8, value.i8);
      break;
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_SINT_16:
      fprintf(stream, "%" PRId16, value.i16);
      break;
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_UINT_16:
      fprintf(stream, "%" PRIu16, value.i16);
      break;
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_SINT_32:
      fprintf(stream, "%" PRId32, value.i32);
      break;
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_UINT_32:
      fprintf(stream, "%" PRIu32, value.i32);
      break;
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_SINT_64:
      fprintf(stream, "%" PRId64, value.i64);
      break;
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_UINT_64:
      fprintf(stream, "%" PRIu64, value.i64);
      break;
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_POINTER:
      fprintf(stream, "%16" PRIX64, value.i64);
      break;
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_FLOAT_16:
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_BFLOAT_16:
      fprintf(stream, "%4" PRIX16, value.i16);
      break;
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_FLOAT_32:
      fprintf(stream, "%e %f", value.f32, value.f32);
      break;
    case IREE_INSTRUMENT_DISPATCH_VALUE_TYPE_FLOAT_64:
      fprintf(stream, "%e %f", value.f64, value.f64);
      break;
    default:
      fprintf(stream, "<<unknown type: %02X>>", (uint32_t)type);
      break;
  }
}

static iree_status_t iree_tooling_dump_dispatch_ringbuffer(
    const uint8_t* data_ptr, iree_host_size_t data_size,
    const iree_dispatch_metadata_t* metadata, FILE* stream) {
  const uint64_t ring_size = data_size - IREE_INSTRUMENT_DISPATCH_PADDING;
  const uint8_t* ring_data = data_ptr;
  const uint64_t ring_head = *(const uint64_t*)(ring_data + data_size - 8);
  const uint64_t ring_range = iree_min(ring_head, ring_size);

  for (iree_host_size_t i = 0; i < ring_range;) {
    const iree_instrument_dispatch_header_t* header =
        (const iree_instrument_dispatch_header_t*)(ring_data + i);
    switch (header->tag) {
      case IREE_INSTRUMENT_DISPATCH_TYPE_WORKGROUP: {
        const iree_instrument_dispatch_workgroup_t* workgroup =
            (const iree_instrument_dispatch_workgroup_t*)header;
        iree_instruments_DispatchSiteDef_table_t dispatch_site_def =
            iree_instruments_DispatchSiteDef_vec_at(
                metadata->dispatch_sites_def, workgroup->dispatch_id);
        iree_instruments_DispatchFunctionDef_table_t function_def =
            iree_instruments_DispatchFunctionDef_vec_at(
                metadata->functions_def,
                iree_instruments_DispatchSiteDef_function(dispatch_site_def));
        flatbuffers_string_t name_def =
            iree_instruments_DispatchFunctionDef_name(function_def);
        fprintf(stream,
                "%016" PRIX64
                " | WORKGROUP dispatch(%u %s %ux%ux%u) %u,%u,%u pid:%u\n",
                (uint64_t)i, workgroup->dispatch_id, name_def,
                workgroup->workgroup_count_x, workgroup->workgroup_count_y,
                workgroup->workgroup_count_z, workgroup->workgroup_id_x,
                workgroup->workgroup_id_y, workgroup->workgroup_id_z,
                workgroup->processor_id);
        i += sizeof(*workgroup);
        break;
      }
      case IREE_INSTRUMENT_DISPATCH_TYPE_PRINT: {
        const iree_instrument_dispatch_print_t* print =
            (const iree_instrument_dispatch_print_t*)header;
        fprintf(stream, "%016" PRIX64 " | PRINT %.*s\n",
                (uint64_t)print->workgroup_offset, (int)print->length,
                print->data);
        i += iree_host_align(sizeof(*print) + print->length, 16);
        break;
      }
      case IREE_INSTRUMENT_DISPATCH_TYPE_VALUE: {
        const iree_instrument_dispatch_value_t* value =
            (const iree_instrument_dispatch_value_t*)header;
        fprintf(stream, "%016" PRIX64 " | VALUE %04u = ",
                (uint64_t)value->workgroup_offset, (uint32_t)value->ordinal);
        iree_tooling_dump_print_value(value->type, value->bits, stream);
        fputc('\n', stream);
        i += sizeof(*value);
        break;
      }
      case IREE_INSTRUMENT_DISPATCH_TYPE_MEMORY_LOAD: {
        const iree_instrument_dispatch_memory_op_t* op =
            (const iree_instrument_dispatch_memory_op_t*)header;
        fprintf(stream, "%016" PRIX64 " | LOAD  %016" PRIX64 " %u\n",
                (uint64_t)op->workgroup_offset, op->address, (int)op->length);
        i += sizeof(*op);
        break;
      }
      case IREE_INSTRUMENT_DISPATCH_TYPE_MEMORY_STORE: {
        const iree_instrument_dispatch_memory_op_t* op =
            (const iree_instrument_dispatch_memory_op_t*)header;
        fprintf(stream, "%016" PRIX64 " | STORE %016" PRIX64 " %u\n",
                (uint64_t)op->workgroup_offset, op->address, (int)op->length);
        i += sizeof(*op);
        break;
      }
      default:
        return iree_make_status(IREE_STATUS_UNIMPLEMENTED,
                                "unimplemented dispatch instr type: %u",
                                (uint32_t)header->tag);
    }
  }

  return iree_ok_status();
}

static iree_status_t iree_tooling_dump_instrument_file(
    iree_const_byte_span_t file_contents, FILE* stream) {
  const uint8_t* file_ptr = file_contents.data;
  iree_host_size_t file_size = file_contents.data_length;

  iree_dispatch_metadata_t dispatch_metadata = {0};
  for (iree_host_size_t file_offset = 0; file_offset < file_size;) {
    const iree_idbts_chunk_header_t* header =
        (const iree_idbts_chunk_header_t*)(file_ptr + file_offset);
    const uint8_t* payload = file_ptr + file_offset + sizeof(*header);
    switch (header->type) {
      case IREE_IDBTS_CHUNK_TYPE_DISPATCH_METADATA: {
        IREE_RETURN_IF_ERROR(iree_tooling_dump_dispatch_metadata(
            payload, header->content_length, &dispatch_metadata, stream));
        break;
      }
      case IREE_IDBTS_CHUNK_TYPE_DISPATCH_RINGBUFFER: {
        IREE_RETURN_IF_ERROR(iree_tooling_dump_dispatch_ringbuffer(
            payload, header->content_length, &dispatch_metadata, stream));
        break;
      }
      default:
        return iree_make_status(IREE_STATUS_UNIMPLEMENTED,
                                "unimplemented chunk type: %u",
                                (uint32_t)header->type);
    }
    file_offset +=
        sizeof(*header) + iree_host_align(header->content_length, 16);
  }

  return iree_ok_status();
}

int main(int argc, char** argv) {
  IREE_TRACE_APP_ENTER();

  if (argc < 2) {
    fprintf(stderr,
            "Syntax: iree-dump-instruments instruments.bin > instruments.txt\n"
            "Example usage:\n"
            "  $ iree-compile \\n"
            "        --iree-hal-target-backends=llvm-cpu \\n"
            "        --iree-hal-instrument-dispatches=16mib \\n"
            "        --iree-llvmcpu-instrument-memory-accesses=false \\n"
            "        runtime/src/iree/runtime/demo/simple_mul.mlir \\n"
            "        -o=simple_mul_instr.vmfb\n"
            "  $ iree-run-module \\n"
            "        --device=local-sync \\n"
            "        --module=simple_mul_instr.vmfb \\n"
            "        --function=simple_mul \\n"
            "        --input=4xf32=2 \\n"
            "        --input=4xf32=4 \\n"
            "        --instrument_file=instrument.bin\n"
            "  $ iree-dump-instruments instrument.bin\n"
            "\n");
    IREE_TRACE_APP_EXIT(EXIT_FAILURE);
    return EXIT_FAILURE;
  }

  iree_file_contents_t* file_contents = NULL;
  iree_status_t status =
      iree_file_read_contents(argv[1], IREE_FILE_READ_FLAG_DEFAULT,
                              iree_allocator_system(), &file_contents);
  if (iree_status_is_ok(status)) {
    status =
        iree_tooling_dump_instrument_file(file_contents->const_buffer, stdout);
  }
  iree_file_contents_free(file_contents);

  if (!iree_status_is_ok(status)) {
    iree_status_fprint(stderr, status);
    iree_status_free(status);
    IREE_TRACE_APP_EXIT(EXIT_FAILURE);
    return EXIT_FAILURE;
  }
  IREE_TRACE_APP_EXIT(EXIT_SUCCESS);
  return EXIT_SUCCESS;
}
