# Copyright 2022 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 handling the benchmark suite.

Benchmark artifacts should be generated by building the `iree-benchmark-suites`
CMake target, which put them in the following directory structure:

<root-build-dir>/benchmark_suites
└── <benchmark-category> (e.g., TFLite)
    ├── <benchmark-suite> (e.g., MobileBertSquad-fp32)
    │   ├── <benchmark-case> (e.g., iree-vulkan__GPU-Mali-Valhall__kernel-execution)
    │   │   ├── compilation_statistics.json
    │   │   ├── tool
    │   │   └── flagfile
    │   ├── ...
    │   │   ├── compilation_statistics.json
    │   │   ├── tool
    │   │   └── flagfile
    │   └── <benchmark_case>
    │   │   ├── compilation_statistics.json
    │       ├── tool
    │       └── flagfile
    └── vmfb
        ├── <compiled-iree-model>-<sha1>.vmfb
        ├── ...
        └── <compiled-iree-model>-<sha1>.vmfb
"""

import collections
import pathlib
import re

from dataclasses import dataclass
from typing import Dict, List, Optional, Sequence, Tuple
from common.benchmark_definition import IREE_DRIVERS_INFOS, DriverInfo
from e2e_test_framework.definitions import iree_definitions

# All benchmarks' relative path against root build directory.
BENCHMARK_SUITE_REL_PATH = "benchmark_suites"

MODEL_FLAGFILE_NAME = "flagfile"
MODEL_TOOLFILE_NAME = "tool"


@dataclass
class BenchmarkCase:
  """Represents a benchmark case.

    model_name: the source model, e.g., 'MobileSSD'.
    model_tags: the source model tags, e.g., ['f32'].
    bench_mode: the benchmark mode, e.g., '1-thread,big-core'.
    target_arch: the target CPU/GPU architature, e.g., 'GPU-Adreno'.
    driver_info: the IREE driver configuration.
    benchmark_tool_name: the benchmark tool, e.g., 'iree-benchmark-module'.
    benchmark_case_dir: the path to benchmark case directory.
    run_config: the run config from e2e test framework. This overrides the
      `benchmark_case_dir`.
  """

  model_name: str
  model_tags: Sequence[str]
  bench_mode: Sequence[str]
  target_arch: str
  driver_info: DriverInfo
  benchmark_tool_name: str
  benchmark_case_dir: Optional[pathlib.Path] = None
  run_config: Optional[iree_definitions.E2EModelRunConfig] = None


# A map from execution config to driver info. This is temporary during migration
# before we can drop the DriverInfo.
EXECUTION_CONFIG_TO_DRIVER_INFO_KEY_MAP: Dict[Tuple[
    iree_definitions.RuntimeDriver, iree_definitions.RuntimeLoader], str] = {
        (iree_definitions.RuntimeDriver.LOCAL_TASK, iree_definitions.RuntimeLoader.EMBEDDED_ELF):
            "iree-llvm-cpu",
        (iree_definitions.RuntimeDriver.LOCAL_SYNC, iree_definitions.RuntimeLoader.EMBEDDED_ELF):
            "iree-llvm-cpu-sync",
        (iree_definitions.RuntimeDriver.LOCAL_TASK, iree_definitions.RuntimeLoader.VMVX_MODULE):
            "iree-vmvx",
        (iree_definitions.RuntimeDriver.LOCAL_SYNC, iree_definitions.RuntimeLoader.VMVX_MODULE):
            "iree-vmvx-sync",
        (iree_definitions.RuntimeDriver.VULKAN, iree_definitions.RuntimeLoader.NONE):
            "iree-vulkan",
        (iree_definitions.RuntimeDriver.CUDA, iree_definitions.RuntimeLoader.NONE):
            "iree-cuda",
    }


class BenchmarkSuite(object):
  """Represents the benchmarks in benchmark suite directory."""

  def __init__(self, suite_map: Dict[pathlib.Path, List[BenchmarkCase]]):
    """Construct a benchmark suite.

    Args:
      suites: the map of benchmark cases keyed by category directories.
    """
    self.suite_map = suite_map
    self.category_map = dict((category_dir.name, category_dir)
                             for category_dir in self.suite_map.keys())

  def list_categories(self) -> List[Tuple[str, pathlib.Path]]:
    """Returns all categories and their directories.

    Returns:
      A tuple of (category name, category dir).
    """
    category_list = [(name, path) for name, path in self.category_map.items()]
    # Fix the order of category list.
    category_list.sort(key=lambda category: category[0])
    return category_list

  def filter_benchmarks_for_category(
      self,
      category: str,
      available_drivers: Optional[Sequence[str]] = None,
      available_loaders: Optional[Sequence[str]] = None,
      cpu_target_arch_filter: Optional[str] = None,
      gpu_target_arch_filter: Optional[str] = None,
      driver_filter: Optional[str] = None,
      mode_filter: Optional[str] = None,
      model_name_filter: Optional[str] = None) -> Sequence[BenchmarkCase]:
    """Filters benchmarks in a specific category for the given device.
      Args:
        category: the specific benchmark category.
        available_drivers: list of drivers supported by the tools. None means to
          match any driver.
        available_loaders: list of executable loaders supported by the tools.
          None means to match any loader.
        cpu_target_arch_filter: CPU target architecture filter regex.
        gpu_target_arch_filter: GPU target architecture filter regex.
        driver_filter: driver filter regex.
        mode_filter: benchmark mode regex.
        model_name_filter: model name regex.
      Returns:
        A list of matched benchmark cases.
    """,

    category_dir = self.category_map.get(category)
    if category_dir is None:
      return []

    chosen_cases = []
    for benchmark_case in self.suite_map[category_dir]:
      driver_info = benchmark_case.driver_info

      driver_name = driver_info.driver_name
      matched_available_driver = (available_drivers is None or
                                  driver_name in available_drivers)
      matched_drivler_filter = driver_filter is None or re.match(
          driver_filter, driver_name) is not None
      matched_driver = matched_available_driver and matched_drivler_filter

      matched_loader = not driver_info.loader_name or available_loaders is None or (
          driver_info.loader_name in available_loaders)

      target_arch = benchmark_case.target_arch.lower()
      matched_cpu_arch = (cpu_target_arch_filter is not None and re.match(
          cpu_target_arch_filter, target_arch) is not None)
      matched_gpu_arch = (gpu_target_arch_filter is not None and re.match(
          gpu_target_arch_filter, target_arch) is not None)
      matched_arch = (matched_cpu_arch or matched_gpu_arch or
                      (cpu_target_arch_filter is None and
                       gpu_target_arch_filter is None))
      bench_mode = ','.join(benchmark_case.bench_mode)
      matched_mode = (mode_filter is None or
                      re.match(mode_filter, bench_mode) is not None)

      model_name_with_tags = benchmark_case.model_name
      if len(benchmark_case.model_tags) > 0:
        model_name_with_tags += f"-{','.join(benchmark_case.model_tags)}"
      if benchmark_case.run_config is not None:
        # For the new run option, we drop the obscure old semantic and only
        # search on model name and its tags.
        model_and_case_name = model_name_with_tags
      elif benchmark_case.benchmark_case_dir is not None:
        # For backward compatibility, model_name_filter matches against the string:
        #   <model name with tags>/<benchmark case name>
        model_and_case_name = f"{model_name_with_tags}/{benchmark_case.benchmark_case_dir.name}"
      else:
        raise ValueError("Either run_config or benchmark_case_dir must be set.")
      matched_model_name = (model_name_filter is None or re.match(
          model_name_filter, model_and_case_name) is not None)

      if (matched_driver and matched_loader and matched_arch and
          matched_model_name and matched_mode):
        chosen_cases.append(benchmark_case)

    return chosen_cases

  @staticmethod
  def load_from_run_configs(
      run_configs: Sequence[iree_definitions.E2EModelRunConfig]):
    """Loads the benchmarks from the run configs.

    Args:
      run_configs: list of benchmark run configs.
    Returns:
      A benchmark suite.
    """

    suite_map = collections.defaultdict(list)
    for run_config in run_configs:
      module_gen_config = run_config.module_generation_config
      module_exec_config = run_config.module_execution_config
      target_device_spec = run_config.target_device_spec

      driver_info_key = EXECUTION_CONFIG_TO_DRIVER_INFO_KEY_MAP.get(
          (module_exec_config.driver, module_exec_config.loader))
      if driver_info_key is None:
        raise ValueError(
            f"Can't map execution config to driver info: {module_exec_config}.")
      driver_info = IREE_DRIVERS_INFOS[driver_info_key]

      arch_info = target_device_spec.architecture
      target_arch = f"{arch_info.type.value}-{arch_info.architecture}-{arch_info.microarchitecture}"

      model = module_gen_config.imported_model.model

      benchmark_case = BenchmarkCase(
          model_name=model.name,
          model_tags=model.tags,
          bench_mode=module_exec_config.tags,
          target_arch=target_arch,
          driver_info=driver_info,
          benchmark_tool_name="iree-benchmark-module",
          run_config=run_config)
      category = pathlib.Path(model.source_type.value)
      suite_map[category].append(benchmark_case)

    return BenchmarkSuite(suite_map=suite_map)

  @staticmethod
  def load_from_benchmark_suite_dir(benchmark_suite_dir: pathlib.Path):
    """Scans and loads the benchmarks under the directory."""

    suite_map: Dict[pathlib.Path,
                    List[BenchmarkCase]] = collections.defaultdict(list)
    for benchmark_case_dir in benchmark_suite_dir.glob("**"):
      model_dir = benchmark_case_dir.parent
      benchmark_name = benchmark_case_dir.name
      # Take the benchmark directory name and see if it matches the benchmark
      # naming convention:
      #   <iree-driver>__<target-architecture>__<benchmark_mode>
      segments = benchmark_name.split("__")
      if len(segments) != 3 or not segments[0].startswith("iree-"):
        continue

      config, target_arch, bench_mode = segments
      bench_mode = bench_mode.split(",")

      # The path of model_dir is expected to be:
      #   <benchmark_suite_dir>/<category>/<model_name>-<model_tags>
      category_dir = model_dir.parent
      model_name_with_tags = model_dir.name
      model_name_parts = model_name_with_tags.split("-", 1)
      model_name = model_name_parts[0]
      if len(model_name_parts) == 2:
        model_tags = model_name_parts[1].split(",")
      else:
        model_tags = []

      tool_name = (benchmark_case_dir / MODEL_TOOLFILE_NAME).read_text().strip()

      suite_map[category_dir].append(
          BenchmarkCase(model_name=model_name,
                        model_tags=model_tags,
                        bench_mode=bench_mode,
                        target_arch=target_arch,
                        driver_info=IREE_DRIVERS_INFOS[config.lower()],
                        benchmark_case_dir=benchmark_case_dir,
                        benchmark_tool_name=tool_name))

    return BenchmarkSuite(suite_map=suite_map)
