# 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
"""Utilities for describing benchmarks.

This file provides common and structured representation of devices, benchmark
definitions, and benchmark result collections, so that they can be shared
between different stages of the same benchmark pipeline.
"""

import json
import pathlib
import re
import subprocess

import dataclasses
from enum import Enum
from typing import Any, Dict, List, Optional, Sequence, Tuple

from e2e_test_framework.definitions import common_definitions

# A map from CPU ABI to IREE's benchmark target architecture.
CPU_ABI_TO_TARGET_ARCH_MAP = {
    "arm64-v8a":
        common_definitions.DeviceArchitecture.ARMV8_2_A_GENERIC,
    "x86_64-cascadelake":
        common_definitions.DeviceArchitecture.X86_64_CASCADELAKE,
}

# A map from GPU name to IREE's benchmark target architecture.
GPU_NAME_TO_TARGET_ARCH_MAP = {
    "adreno-640":
        common_definitions.DeviceArchitecture.QUALCOMM_ADRENO,
    "adreno-650":
        common_definitions.DeviceArchitecture.QUALCOMM_ADRENO,
    "adreno-660":
        common_definitions.DeviceArchitecture.QUALCOMM_ADRENO,
    "adreno-730":
        common_definitions.DeviceArchitecture.QUALCOMM_ADRENO,
    "mali-g77":
        common_definitions.DeviceArchitecture.ARM_VALHALL,
    "mali-g78":
        common_definitions.DeviceArchitecture.ARM_VALHALL,
    "tesla-v100-sxm2-16gb":
        common_definitions.DeviceArchitecture.NVIDIA_PASCAL,
    "nvidia-a100-sxm4-40gb":
        common_definitions.DeviceArchitecture.NVIDIA_AMPERE,
    "nvidia-geforce-rtx-3090":
        common_definitions.DeviceArchitecture.NVIDIA_AMPERE,
}


@dataclasses.dataclass
class DriverInfo:
  """An object describing a IREE HAL driver.

  It includes the following characteristics:
  - pretty_name: the pretty name, e.g., 'IREE-LLVM-CPU'
  - device_type: the targeted device type, e.g., 'CPU'
  - driver_name: runtime driver flag, e.g., 'local-task'
  - loader_name: executable loader name, if used
  """

  pretty_name: str
  device_type: str
  driver_name: str
  loader_name: str


# A map for IREE driver names. This allows us to normalize driver names like
# mapping to more friendly ones and detach to keep driver names used in
# benchmark presentation stable.
IREE_DRIVERS_INFOS = {
    "iree-llvm-cpu":
        DriverInfo("IREE-LLVM-CPU", "CPU", "local-task", "embedded-elf"),
    "iree-llvm-cpu-sync":
        DriverInfo("IREE-LLVM-CPU-Sync", "CPU", "local-sync", "embedded-elf"),
    "iree-vmvx":
        DriverInfo("IREE-VMVX", "CPU", "local-task", "vmvx-module"),
    "iree-vmvx-sync":
        DriverInfo("IREE-VMVX-Sync", "CPU", "local-sync", "vmvx-module"),
    "iree-vulkan":
        DriverInfo("IREE-Vulkan", "GPU", "vulkan", ""),
    "iree-cuda":
        DriverInfo("IREE-CUDA", "GPU", "cuda", ""),
}

IREE_PRETTY_NAME_TO_DRIVER_NAME = {
    v.pretty_name: k for k, v in IREE_DRIVERS_INFOS.items()
}


def execute_cmd(args: Sequence[Any],
                verbose: bool = False,
                **kwargs) -> subprocess.CompletedProcess:
  """Executes a command and returns the completed process.

  A thin wrapper around subprocess.run that sets some useful defaults and
  optionally prints out the command being run.

  Raises:
    CalledProcessError if the command fails.
  """
  if verbose:
    print(f"cmd: {args}")
  try:
    return subprocess.run(args, check=True, text=True, **kwargs)
  except subprocess.CalledProcessError as exc:
    print((f"\n\nThe following command failed:\n\n{args}"
           f"\n\nReturn code: {exc.returncode}\n\n"))
    if exc.stdout:
      print(f"Stdout:\n\n{exc.stdout}\n\n")
    if exc.stderr:
      print(f"Stderr:\n\n{exc.stderr}\n\n")
    raise exc


def execute_cmd_and_get_output(args: Sequence[Any],
                               verbose: bool = False,
                               **kwargs) -> Tuple[str, str]:
  """Executes a command and returns its stdout and stderr

  Same as execute_cmd except captures stdout and stderr.
  """
  exc = execute_cmd(args,
                    verbose=verbose,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    **kwargs)
  return exc.stdout.strip(), exc.stderr.strip()


def execute_cmd_and_get_stdout(args: Sequence[Any],
                               verbose: bool = False,
                               **kwargs) -> str:
  """Executes a command and returns its stdout.

  Same as execute_cmd except captures stdout (and not stderr).
  """
  stdout, _ = execute_cmd_and_get_output(args, verbose=verbose, **kwargs)
  return stdout


def get_git_commit_hash(commit: str) -> str:
  return execute_cmd_and_get_stdout(['git', 'rev-parse', commit],
                                    cwd=pathlib.Path(__file__).resolve().parent)


def get_iree_benchmark_module_arguments(
    results_filename: str,
    driver_info: DriverInfo,
    benchmark_min_time: Optional[float] = None):
  """Returns the common arguments to run iree-benchmark-module."""

  if driver_info.loader_name == "vmvx-module":
    # VMVX is very unoptimized for now and can take a long time to run.
    # Decrease the repetition for it until it's reasonably fast.
    repetitions = 3
  else:
    repetitions = 10

  cmd = [
      "--time_unit=ns",
      "--benchmark_format=json",
      "--benchmark_out_format=json",
      f"--benchmark_out={results_filename}",
      "--print_statistics=true",
  ]
  if benchmark_min_time:
    cmd.extend([
        f"--benchmark_min_time={benchmark_min_time}",
    ])
  else:
    cmd.extend([
        f"--benchmark_repetitions={repetitions}",
    ])

  return cmd


def wait_for_iree_benchmark_module_start(process: subprocess.Popen,
                                         verbose: bool = False) -> None:
  """Wait for the start of iree-benchmark module; otherwise will see connection
  failure when opening the catpure tool."""

  while True:
    line = process.stdout.readline()  # pytype: disable=attribute-error
    if line == "" and process.poll() is not None:  # Process completed
      raise ValueError("Cannot find benchmark result line in the log!")
    if verbose:
      print(line.strip())
    # Result available
    if re.match(r"^BM_.+/real_time", line) is not None:
      break


class PlatformType(Enum):
  ANDROID = "Android"
  LINUX = "Linux"


@dataclasses.dataclass(frozen=True)
class DeviceInfo:
  """An object describing a device.

  It includes the following characteristics:
  - platform_type: the OS platform, e.g., 'Android'
  - model: the product model, e.g., 'Pixel-4'
  - cpu_abi: the CPU ABI, e.g., 'arm64-v8a', 'x86_64'
  - cpu_uarch: the CPU microarchitecture, e.g., 'CascadeLake'
  - cpu_features: the detailed CPU features, e.g., ['fphp', 'sve']
  - gpu_name: the GPU name, e.g., 'Mali-G77'
  """

  platform_type: PlatformType
  model: str
  cpu_abi: str
  cpu_uarch: Optional[str]
  cpu_features: Sequence[str]
  gpu_name: str

  def __str__(self):
    features = ", ".join(self.cpu_features)
    params = [
        f"model='{self.model}'",
        f"cpu_abi='{self.cpu_abi}'",
        f"cpu_uarch='{self.cpu_uarch}'",
        f"gpu_name='{self.gpu_name}'",
        f"cpu_features=[{features}]",
    ]
    params = ", ".join(params)
    return f"{self.platform_type.value} device <{params}>"

  def get_cpu_arch(self) -> Optional[common_definitions.DeviceArchitecture]:
    name = self.cpu_abi.lower()
    if self.cpu_uarch:
      name += f"-{self.cpu_uarch.lower()}"

    return CPU_ABI_TO_TARGET_ARCH_MAP.get(name)

  def get_gpu_arch(self) -> Optional[common_definitions.DeviceArchitecture]:
    name = self.gpu_name.lower()
    return GPU_NAME_TO_TARGET_ARCH_MAP.get(name)

  def get_detailed_cpu_arch_name(self) -> str:
    """Returns the detailed architecture name."""

    if self.cpu_abi == "arm64-v8a":
      return self.__get_arm_cpu_arch_revision()
    if self.cpu_abi == "x86_64":
      return self.__get_x86_detailed_cpu_arch_name()
    raise ValueError("Unrecognized CPU ABI; need to update the list")

  def to_json_object(self) -> Dict[str, Any]:
    return {
        "platform_type": self.platform_type.value,
        "model": self.model,
        "cpu_abi": self.cpu_abi,
        "cpu_uarch": self.cpu_uarch if self.cpu_uarch else "",
        "cpu_features": self.cpu_features,
        "gpu_name": self.gpu_name,
    }

  @staticmethod
  def from_json_object(json_object: Dict[str, Any]):
    cpu_uarch = json_object.get("cpu_uarch")
    return DeviceInfo(PlatformType(json_object["platform_type"]),
                      json_object["model"], json_object["cpu_abi"],
                      None if cpu_uarch == "" else cpu_uarch,
                      json_object["cpu_features"], json_object["gpu_name"])

  def __get_x86_detailed_cpu_arch_name(self) -> str:
    """Returns the x86 architecture with microarchitecture name."""

    if not self.cpu_uarch:
      return self.cpu_abi

    return f"{self.cpu_abi}-{self.cpu_uarch}"

  def __get_arm_cpu_arch_revision(self) -> str:
    """Returns the ARM architecture revision."""

    # CPU features for ARMv8 revisions.
    # From https://en.wikichip.org/wiki/arm/armv8#ARMv8_Extensions_and_Processor_Features
    rev1_features = ["atomics", "asimdrdm"]
    rev2_features = [
        "fphp", "dcpop", "sha3", "sm3", "sm4", "asimddp", "sha512", "sve"
    ]

    rev = "ARMv8-A"
    if any([f in self.cpu_features for f in rev1_features]):
      rev = "ARMv8.1-A"
    if any([f in self.cpu_features for f in rev2_features]):
      rev = "ARMv8.2-A"
    return rev


@dataclasses.dataclass(frozen=True)
class BenchmarkInfo:
  """An object describing the current benchmark.

  It includes the following benchmark characteristics:
  - name: the benchmark name
  - model_name: the model name, e.g., 'MobileNetV2'
  - model_tags: a list of tags used to describe additional model information,
      e.g., ['imagenet']
  - model_source: the source of the model, e.g., 'TensorFlow'
  - bench_mode: a list of tags for benchmark mode,
      e.g., ['1-thread', 'big-core', 'full-inference']
  - device_info: an DriverInfo object describing the IREE runtime dirver.
  - device_info: an DeviceInfo object describing the device where benchmarks run
  - compile_tags: an optional list of tags to describe the compile configs,
      e.g., ['fuse-padding']
  - runner: which runner is used for benchmarking, e.g., 'iree_vulkan', 'tflite'
  - run_config_id: ID of the corresponding iree_definitions.E2EModelRunConfig.
  """

  name: str
  model_name: str
  model_tags: Sequence[str]
  model_source: str
  bench_mode: Sequence[str]
  driver_info: DriverInfo
  device_info: DeviceInfo
  compile_tags: Optional[Sequence[str]] = None
  run_config_id: Optional[str] = None

  def __str__(self):
    return self.name

  def to_json_object(self) -> Dict[str, Any]:
    return {
        "name": self.name,
        "model_name": self.model_name,
        "model_tags": self.model_tags,
        "model_source": self.model_source,
        "bench_mode": self.bench_mode,
        "compile_tags": self.compile_tags,
        # Get the "iree-*" driver name from the DriverInfo.
        "runner": IREE_PRETTY_NAME_TO_DRIVER_NAME[self.driver_info.pretty_name],
        "device_info": self.device_info.to_json_object(),
        "run_config_id": self.run_config_id
    }

  @staticmethod
  def from_json_object(json_object: Dict[str, Any]):
    driver_info = IREE_DRIVERS_INFOS.get(json_object["runner"])
    if not driver_info:
      raise ValueError(f"Unrecognized runner: {json_object['runner']}")

    return BenchmarkInfo(name=json_object["name"],
                         model_name=json_object["model_name"],
                         model_tags=json_object["model_tags"],
                         model_source=json_object["model_source"],
                         bench_mode=json_object["bench_mode"],
                         compile_tags=json_object.get("compile_tags"),
                         driver_info=driver_info,
                         device_info=DeviceInfo.from_json_object(
                             json_object["device_info"]),
                         run_config_id=json_object.get("run_config_id"))


@dataclasses.dataclass(frozen=True)
class BenchmarkLatency:
  """Stores latency statistics for a benchmark run."""
  mean: int
  median: int
  stddev: int
  unit: str

  def to_json_object(self) -> Dict[str, Any]:
    return dataclasses.asdict(self)

  @staticmethod
  def from_json_object(json_object: Dict[str, Any]):
    return BenchmarkLatency(**json_object)


def _get_google_benchmark_latencies(
    benchmark_json: Dict[str,
                         Any]) -> Tuple[BenchmarkLatency, BenchmarkLatency]:
  """Returns the Google Benchmark aggregate latencies.

    Args:
      benchmark_json: The JSON string or object returned by Google Benchmark.

    Returns:
      Real time and CPU time BenchmarkLatency.
    """
  real_time_object: Dict[str, Any] = dict(unit="ns")
  cpu_time_object: Dict[str, Any] = dict(unit="ns")
  metrics = ["mean", "median", "stddev"]
  for case in benchmark_json["benchmarks"]:
    if any(case["name"].endswith(f"real_time_{m}") for m in metrics):
      if case["time_unit"] != "ns":
        raise ValueError(f"Expected ns as time unit")
      metric = case["name"].split("_")[-1]
      real_time_object[metric] = int(round(case["real_time"]))
      cpu_time_object[metric] = int(round(case["cpu_time"]))

  # from_json_object implicitly validates that all metrics were found.
  real_time = BenchmarkLatency.from_json_object(real_time_object)
  cpu_time = BenchmarkLatency.from_json_object(cpu_time_object)
  return real_time, cpu_time


@dataclasses.dataclass(frozen=True)
class BenchmarkMemory:
  """Stores memory statistics for a benchmark run."""
  peak: int
  allocated: int
  freed: int
  live: int
  unit: str

  def to_json_object(self) -> Dict[str, int]:
    return dataclasses.asdict(self)

  @staticmethod
  def from_json_object(json_object: Dict[str, Any]):
    return BenchmarkMemory(**json_object)


def _get_iree_memory_statistics(benchmark_stderr: str,
                                device: str) -> BenchmarkMemory:
  """Extracts IREE's memory statistics for a given device."""
  # The memory statistics for each device are listed on their own line.
  pattern = (rf"{device}:"
             r"\s*(?P<peak>\d+)B peak /"
             r"\s*(?P<allocated>\d+)B allocated /"
             r"\s*(?P<freed>\d+)B freed /"
             r"\s*(?P<live>\d+)B live")
  match = re.search(pattern, benchmark_stderr)
  if match is None:
    raise ValueError(
        f"Unable to find memory statistics in '{benchmark_stderr}'")
  return BenchmarkMemory(
      peak=int(match["peak"]),
      allocated=int(match["allocated"]),
      freed=int(match["freed"]),
      live=int(match["live"]),
      unit="bytes",
  )


@dataclasses.dataclass(frozen=True)
class BenchmarkMetrics(object):
  """An object describing the results from a single benchmark.

  - real_time: the real time latency statistics returned by the benchmarking
      framework.
  - cpu_time: the cpu time latency statistics returned by the benchmarking
      framework.
  - host_memory: the host memory statistics returned by the benchmarking
      framework.
  - device_memory: the device memory statistics returned by the benchmarking
      framework.
  - raw_data: additional JSON-compatible raw results returned by the
      benchmarking framework.
  """
  real_time: BenchmarkLatency
  cpu_time: BenchmarkLatency
  host_memory: BenchmarkMemory
  device_memory: BenchmarkMemory
  raw_data: Dict[str, Any]

  def to_json_object(self) -> Dict[str, Any]:
    return {
        "real_time": self.real_time.to_json_object(),
        "cpu_time": self.cpu_time.to_json_object(),
        "host_memory": self.host_memory.to_json_object(),
        "device_memory": self.device_memory.to_json_object(),
        "raw_data": self.raw_data,
    }

  @staticmethod
  def from_json_object(json_object: Dict[str, Any]):
    return BenchmarkMetrics(
        real_time=BenchmarkLatency.from_json_object(json_object["real_time"]),
        cpu_time=BenchmarkLatency.from_json_object(json_object["cpu_time"]),
        host_memory=BenchmarkMemory.from_json_object(
            json_object["host_memory"]),
        device_memory=BenchmarkMemory.from_json_object(
            json_object["device_memory"]),
        raw_data=json_object["raw_data"],
    )


def parse_iree_benchmark_metrics(benchmark_stdout: str,
                                 benchmark_stderr: str) -> BenchmarkMetrics:
  """Extract benchmark metrics from the output of iree-benchmark-module.

  Args:
    benchmark_stdout: The stdout of iree-benchmark-module with
      --benchmark_format=json.
    benchmark_stdout: The stderr of iree-benchmark-module with
      --print_statistics=true.

  Returns:
    A populated BenchmarkMetrics dataclass.
  """
  benchmark_json = json.loads(benchmark_stdout)
  real_time, cpu_time = _get_google_benchmark_latencies(benchmark_json)
  return BenchmarkMetrics(
      real_time=real_time,
      cpu_time=cpu_time,
      host_memory=_get_iree_memory_statistics(benchmark_stderr, "HOST_LOCAL"),
      device_memory=_get_iree_memory_statistics(benchmark_stderr,
                                                "DEVICE_LOCAL"),
      raw_data=benchmark_json,
  )


@dataclasses.dataclass(frozen=True)
class BenchmarkRun(object):
  """An object describing a single run of the benchmark binary.

  - info: a BenchmarkInfo object describing the benchmark setup.
  - metrics: a BenchmarkMetrics object containing the results of the benchmark.
  """
  info: BenchmarkInfo
  metrics: BenchmarkMetrics

  def to_json_object(self) -> Dict[str, Any]:
    return {
        "info": self.info.to_json_object(),
        "metrics": self.metrics.to_json_object(),
    }

  @staticmethod
  def from_json_object(json_object: Dict[str, Any]):
    return BenchmarkRun(
        BenchmarkInfo.from_json_object(json_object["info"]),
        BenchmarkMetrics.from_json_object(json_object["metrics"]),
    )


class BenchmarkResults(object):
  """An object describing a set of benchmarks for one particular commit.

    It contains the following fields:
    - commit: the commit SHA for this set of benchmarks.
    - benchmarks: a list of BenchmarkRun objects
    """

  def __init__(self):
    self.commit: str = "<unknown>"
    self.benchmarks: List[BenchmarkRun] = []

  def set_commit(self, commit: str):
    self.commit = commit

  def merge(self, other):
    if self.commit != other.commit:
      raise ValueError("Inconsistent pull request commit")
    self.benchmarks.extend(other.benchmarks)

  def to_json_str(self) -> str:
    json_object = {"commit": self.commit, "benchmarks": []}
    json_object["benchmarks"] = [b.to_json_object() for b in self.benchmarks]
    return json.dumps(json_object, indent=2)

  @staticmethod
  def from_json_str(json_str: str):
    json_object = json.loads(json_str)
    results = BenchmarkResults()
    results.set_commit(json_object["commit"])
    results.benchmarks = [
        BenchmarkRun.from_json_object(b) for b in json_object["benchmarks"]
    ]
    return results


@dataclasses.dataclass(frozen=True)
class CompilationInfo(object):
  name: str
  model_name: str
  model_tags: Tuple[str]
  model_source: str
  target_arch: str
  compile_tags: Tuple[str]
  gen_config_id: Optional[str] = None

  def __str__(self):
    return self.name

  @staticmethod
  def from_json_object(json_object: Dict[str, Any]):
    return CompilationInfo(name=json_object["name"],
                           model_name=json_object["model_name"],
                           model_tags=tuple(json_object["model_tags"]),
                           model_source=json_object["model_source"],
                           target_arch=json_object["target_arch"],
                           compile_tags=tuple(json_object["compile_tags"]),
                           gen_config_id=json_object.get("gen_config_id"))


@dataclasses.dataclass(frozen=True)
class ModuleComponentSizes(object):
  file_bytes: int
  vm_component_bytes: int
  const_component_bytes: int
  total_dispatch_component_bytes: int

  @staticmethod
  def from_json_object(json_object: Dict[str, Any]):
    return ModuleComponentSizes(**json_object)


@dataclasses.dataclass(frozen=True)
class IRStatistics(object):
  # Number of cmd.dispatch ops in IR.
  stream_dispatch_count: int

  @staticmethod
  def from_json_object(json_object: Dict[str, Any]):
    return IRStatistics(**json_object)


@dataclasses.dataclass(frozen=True)
class CompilationStatistics(object):
  compilation_info: CompilationInfo
  # Module file and component sizes.
  module_component_sizes: ModuleComponentSizes
  # Module compilation time in ms.
  compilation_time_ms: int
  # IR-level statistics
  ir_stats: IRStatistics

  @staticmethod
  def from_json_object(json_object: Dict[str, Any]):
    return CompilationStatistics(
        compilation_info=CompilationInfo.from_json_object(
            json_object["compilation_info"]),
        module_component_sizes=ModuleComponentSizes.from_json_object(
            json_object["module_component_sizes"]),
        compilation_time_ms=json_object["compilation_time_ms"],
        ir_stats=IRStatistics.from_json_object(json_object["ir_stats"]))


@dataclasses.dataclass(frozen=True)
class CompilationResults(object):
  commit: str
  compilation_statistics: Sequence[CompilationStatistics]

  @staticmethod
  def from_json_object(json_object: Dict[str, Any]):
    return CompilationResults(
        commit=json_object["commit"],
        compilation_statistics=[
            CompilationStatistics.from_json_object(obj)
            for obj in json_object["compilation_statistics"]
        ])
