# 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 urllib.parse
import urllib.request

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

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(frozen=True)
class ResourceLocation:
    """Class to represent either local resource path or an URL."""

    local_path: Optional[pathlib.Path]
    url: Optional[str]

    def get_local_path(self) -> Optional[pathlib.Path]:
        """Returns the local path or None if it is an URL."""
        return self.local_path

    def get_url(self) -> Optional[str]:
        """Returns the URL or None if it is a local path."""
        return self.url

    def __truediv__(self, sub_path: Union[str, pathlib.PurePath]) -> "ResourceLocation":
        """Appends the sub path and returns the new location."""
        local_path = self.get_local_path()
        if local_path:
            return self.__class__.build_local_path(local_path / sub_path)
        url = self.get_url()
        assert url is not None
        sub_url_path = urllib.request.pathname2url(str(sub_path))
        # urljoin requires the directly URL ended with "/".
        return self.__class__.build_url(urllib.parse.urljoin(url + "/", sub_url_path))

    @classmethod
    def build_local_path(cls, path: Union[pathlib.Path, str]) -> "ResourceLocation":
        """Build from a local path."""
        return cls(local_path=pathlib.Path(path), url=None)

    @classmethod
    def build_url(cls, url: str) -> "ResourceLocation":
        """Build from an URL."""
        return cls(local_path=None, url=url)


@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 parse_external_param_url(param_url: str) -> Tuple[str, str, str]:
    """Parse `scope=url` into (scope, URL, filename of the URL)."""
    scope, url = param_url.split("=", maxsplit=1)
    url_path = urllib.parse.urlparse(url).path
    filename = pathlib.PurePath(url_path).name
    return scope, url, filename


def get_iree_benchmark_module_arguments(
    driver_info: DriverInfo,
    benchmark_min_time: Optional[float] = None,
    dump_results: bool = True,
    capture_mode: bool = 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 dump_results:
        cmd += [
            "--time_unit=ns",
            "--benchmark_format=json",
            "--benchmark_out_format=json",
            "--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"]
            ],
        )
