# 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(
    driver_info: DriverInfo,
    results_filename: Optional[str] = None,
    benchmark_min_time: Optional[float] = None,
    capture_mode=False,
):
    """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
    elif capture_mode:
        # Capture mode is slower and we just need enough repetition to collect
        # trace after the warmup phase.
        repetitions = 4
    else:
        repetitions = 10

    cmd = []
    if results_filename is not None:
        cmd += [
            "--time_unit=ns",
            "--benchmark_format=json",
            "--benchmark_out_format=json",
            "--print_statistics=true",
            f"--benchmark_out={results_filename}",
        ]

    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"]
            ],
        )
