#!/usr/bin/env python3
# Copyright 2026 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
"""Generates shared AMDGPU device library target map fragments.

The map in this file is the source of truth for the small generated tables used
by Bazel, CMake, and the runtime device-library loader. Keep build logic in
Starlark/CMake; keep target facts here.
"""

import argparse
import difflib
import re
import sys
from pathlib import Path

DEFAULT_TARGET_SELECTIONS = ("all",)

# Each exact target must match an HSA ISA architecture suffix. Each code object
# target must be accepted by LLVM clang/lld as an AMDGPU -march value. Generic
# code object coverage follows LLVM generic processor documentation; TheRock
# family membership follows ROCm/TheRock's cmake/therock_amdgpu_targets.cmake.
EXACT_TARGET_CODE_OBJECTS = (
    ("gfx900", "gfx9-generic"),
    ("gfx902", "gfx9-generic"),
    ("gfx904", "gfx9-generic"),
    ("gfx90c", "gfx9-generic"),
    ("gfx906", "gfx9-generic"),
    ("gfx908", "gfx908"),
    ("gfx909", "gfx9-generic"),
    ("gfx90a", "gfx90a"),
    ("gfx940", "gfx9-4-generic"),
    ("gfx941", "gfx9-4-generic"),
    ("gfx942", "gfx9-4-generic"),
    ("gfx950", "gfx9-4-generic"),
    ("gfx1010", "gfx10-1-generic"),
    ("gfx1011", "gfx10-1-generic"),
    ("gfx1012", "gfx10-1-generic"),
    ("gfx1013", "gfx10-1-generic"),
    ("gfx1030", "gfx10-3-generic"),
    ("gfx1031", "gfx10-3-generic"),
    ("gfx1032", "gfx10-3-generic"),
    ("gfx1033", "gfx10-3-generic"),
    ("gfx1034", "gfx10-3-generic"),
    ("gfx1035", "gfx10-3-generic"),
    ("gfx1036", "gfx10-3-generic"),
    ("gfx1100", "gfx11-generic"),
    ("gfx1101", "gfx11-generic"),
    ("gfx1102", "gfx11-generic"),
    ("gfx1103", "gfx11-generic"),
    ("gfx1150", "gfx11-generic"),
    ("gfx1151", "gfx11-generic"),
    ("gfx1152", "gfx11-generic"),
    ("gfx1153", "gfx11-generic"),
    ("gfx1170", "gfx11-generic"),
    ("gfx1171", "gfx11-generic"),
    ("gfx1172", "gfx11-generic"),
    ("gfx1200", "gfx12-generic"),
    ("gfx1201", "gfx12-generic"),
    ("gfx1250", "gfx12-5-generic"),
    ("gfx1251", "gfx12-5-generic"),
)

FEATURE_SRAMECC = "sramecc"
FEATURE_XNACK = "xnack"

# Feature support follows ROCr's ISA registry. A target absent from a feature
# set does not support that feature; supported targets may still select an
# explicit on/off mode at runtime.
TARGET_FEATURE_SUPPORT = {
    "gfx900": (FEATURE_XNACK,),
    "gfx902": (FEATURE_XNACK,),
    "gfx904": (FEATURE_XNACK,),
    "gfx906": (FEATURE_SRAMECC, FEATURE_XNACK),
    "gfx908": (FEATURE_SRAMECC, FEATURE_XNACK),
    "gfx909": (FEATURE_XNACK,),
    "gfx90c": (FEATURE_XNACK,),
    "gfx90a": (FEATURE_SRAMECC, FEATURE_XNACK),
    "gfx940": (FEATURE_SRAMECC, FEATURE_XNACK),
    "gfx941": (FEATURE_SRAMECC, FEATURE_XNACK),
    "gfx942": (FEATURE_SRAMECC, FEATURE_XNACK),
    "gfx950": (FEATURE_SRAMECC, FEATURE_XNACK),
    "gfx1010": (FEATURE_XNACK,),
    "gfx1011": (FEATURE_XNACK,),
    "gfx1012": (FEATURE_XNACK,),
    "gfx1013": (FEATURE_XNACK,),
}

ALL_EXACT_TARGETS = object()

TARGET_FAMILIES = (
    ("all", ALL_EXACT_TARGETS),
    (
        "dcgpu-all",
        ("gfx908", "gfx90a", "gfx940", "gfx941", "gfx942", "gfx950"),
    ),
    (
        "dgpu-all",
        (
            "gfx900",
            "gfx902",
            "gfx904",
            "gfx906",
            "gfx909",
            "gfx1010",
            "gfx1011",
            "gfx1012",
            "gfx1013",
            "gfx1030",
            "gfx1031",
            "gfx1032",
            "gfx1034",
            "gfx1100",
            "gfx1101",
            "gfx1102",
            "gfx1200",
            "gfx1201",
        ),
    ),
    ("gfx900-dgpu", ("gfx900",)),
    ("gfx906-dgpu", ("gfx906",)),
    ("gfx908-dcgpu", ("gfx908",)),
    ("gfx90a-dcgpu", ("gfx90a",)),
    ("gfx90c-igpu", ("gfx90c",)),
    ("gfx94X-all", ("gfx940", "gfx941", "gfx942")),
    ("gfx94X-dcgpu", ("gfx940", "gfx941", "gfx942")),
    ("gfx950-all", ("gfx950",)),
    ("gfx950-dcgpu", ("gfx950",)),
    ("gfx101X-all", ("gfx1010", "gfx1011", "gfx1012", "gfx1013")),
    ("gfx101X-dgpu", ("gfx1010", "gfx1011", "gfx1012", "gfx1013")),
    (
        "gfx103X-all",
        (
            "gfx1030",
            "gfx1031",
            "gfx1032",
            "gfx1033",
            "gfx1034",
            "gfx1035",
            "gfx1036",
        ),
    ),
    ("gfx103X-dgpu", ("gfx1030", "gfx1031", "gfx1032", "gfx1034")),
    ("gfx103X-igpu", ("gfx1033", "gfx1035", "gfx1036")),
    ("gfx110X-all", ("gfx1100", "gfx1101", "gfx1102", "gfx1103")),
    ("gfx110X-dgpu", ("gfx1100", "gfx1101", "gfx1102")),
    ("gfx110X-igpu", ("gfx1103",)),
    ("gfx115X-all", ("gfx1150", "gfx1151", "gfx1152", "gfx1153")),
    ("gfx115X-igpu", ("gfx1150", "gfx1151", "gfx1152", "gfx1153")),
    ("gfx117X-all", ("gfx1170", "gfx1171", "gfx1172")),
    ("gfx120X-all", ("gfx1200", "gfx1201")),
    ("gfx125X-all", ("gfx1250", "gfx1251")),
    (
        "igpu-all",
        (
            "gfx90c",
            "gfx1033",
            "gfx1035",
            "gfx1036",
            "gfx1103",
            "gfx1150",
            "gfx1151",
            "gfx1152",
            "gfx1153",
        ),
    ),
)


def find_repo_root():
    current = Path(__file__).resolve()
    while current != current.parent:
        if (current / "runtime" / "src" / "iree").exists():
            return current
        current = current.parent
    print("error: could not find IREE repository root", file=sys.stderr)
    sys.exit(1)


def append_unique(values, new_values):
    for value in new_values:
        if value not in values:
            values.append(value)


def exact_targets():
    return [exact_target for exact_target, _ in EXACT_TARGET_CODE_OBJECTS]


def code_object_targets():
    values = []
    for _, code_object_target in EXACT_TARGET_CODE_OBJECTS:
        append_unique(values, [code_object_target])
    return values


def family_targets(targets):
    if targets is ALL_EXACT_TARGETS:
        return exact_targets()
    return list(targets)


def target_family_names():
    return [family for family, _ in TARGET_FAMILIES]


def validate_target_map():
    exact = exact_targets()
    if len(set(exact)) != len(exact):
        raise ValueError("duplicate exact AMDGPU targets in target map")

    families = target_family_names()
    if len(set(families)) != len(families):
        raise ValueError("duplicate AMDGPU target families in target map")

    exact_set = set(exact)
    feature_targets = set(TARGET_FEATURE_SUPPORT)
    unknown_feature_targets = sorted(feature_targets - exact_set)
    if unknown_feature_targets:
        raise ValueError(
            "target feature support references unknown exact targets: {}".format(
                ", ".join(unknown_feature_targets)
            )
        )

    for family, targets in TARGET_FAMILIES:
        unknown_targets = sorted(set(family_targets(targets)) - exact_set)
        if unknown_targets:
            raise ValueError(
                "target family {} references unknown exact targets: {}".format(
                    family, ", ".join(unknown_targets)
                )
            )


def generated_header(comment_prefix, output_path):
    return "\n".join(
        [
            "{} Generated by build_tools/scripts/amdgpu_target_map.py.".format(
                comment_prefix
            ),
            "{} Do not edit directly; edit the map in that script and regenerate.".format(
                comment_prefix
            ),
            "{} Output: {}".format(comment_prefix, output_path),
        ]
    )


def bzl_list(name, values):
    lines = ["{} = [".format(name)]
    lines.extend(['    "{}",'.format(value) for value in values])
    lines.append("]")
    return "\n".join(lines)


def bzl_string_dict(name, values):
    lines = ["{} = {{".format(name)]
    for key, value in values:
        lines.append('    "{}": "{}",'.format(key, value))
    lines.append("}")
    return "\n".join(lines)


def bzl_family_dict(name):
    lines = ["{} = {{".format(name)]
    for family, targets in TARGET_FAMILIES:
        values = family_targets(targets)
        if targets is ALL_EXACT_TARGETS:
            lines.append(
                '    "{}": IREE_HAL_AMDGPU_DEVICE_LIBRARY_EXACT_TARGETS,'.format(family)
            )
        elif len(values) == 1:
            lines.append('    "{}": ["{}"],'.format(family, values[0]))
        else:
            lines.append('    "{}": ['.format(family))
            lines.extend(['        "{}",'.format(value) for value in values])
            lines.append("    ],")
    lines.append("}")
    return "\n".join(lines)


def render_bzl():
    output_path = "runtime/src/iree/hal/drivers/amdgpu/device/binaries/target_map.bzl"
    return (
        "\n\n".join(
            [
                generated_header("#", output_path),
                bzl_list(
                    "IREE_HAL_AMDGPU_DEVICE_LIBRARY_DEFAULT_TARGETS",
                    DEFAULT_TARGET_SELECTIONS,
                ),
                bzl_list(
                    "IREE_HAL_AMDGPU_DEVICE_LIBRARY_EXACT_TARGETS",
                    exact_targets(),
                ),
                bzl_list(
                    "IREE_HAL_AMDGPU_DEVICE_LIBRARY_CODE_OBJECT_TARGETS",
                    code_object_targets(),
                ),
                bzl_string_dict(
                    "IREE_HAL_AMDGPU_DEVICE_LIBRARY_EXACT_TARGET_CODE_OBJECTS",
                    EXACT_TARGET_CODE_OBJECTS,
                ),
                bzl_list(
                    "IREE_HAL_AMDGPU_DEVICE_LIBRARY_TARGET_FAMILY_NAMES",
                    target_family_names(),
                ),
                bzl_family_dict("IREE_HAL_AMDGPU_DEVICE_LIBRARY_TARGET_FAMILIES"),
            ]
        )
        + "\n"
    )


def cmake_list(name, values):
    lines = ["set({}".format(name)]
    lines.extend(['  "{}"'.format(value) for value in values])
    lines.append(")")
    return "\n".join(lines)


def cmake_identifier(value):
    return re.sub(r"[^A-Za-z0-9_]", "_", value)


def render_cmake():
    output_path = "runtime/src/iree/hal/drivers/amdgpu/device/binaries/target_map.cmake"
    lines = [
        generated_header("#", output_path),
        "",
        cmake_list("_IREE_HAL_AMDGPU_DEVICE_TARGETS", exact_targets()),
        "",
        cmake_list(
            "_IREE_HAL_AMDGPU_DEVICE_CODE_OBJECT_TARGETS", code_object_targets()
        ),
        "",
    ]
    for exact_target, code_object_target in EXACT_TARGET_CODE_OBJECTS:
        lines.append(
            'set(_IREE_HAL_AMDGPU_DEVICE_TARGET_CODE_OBJECT_{} "{}")'.format(
                exact_target, code_object_target
            )
        )
    lines.extend(
        [
            "",
            cmake_list(
                "_IREE_HAL_AMDGPU_DEVICE_TARGET_FAMILIES", target_family_names()
            ),
            "",
        ]
    )
    for family, targets in TARGET_FAMILIES:
        var_name = "_IREE_HAL_AMDGPU_DEVICE_TARGET_FAMILY_{}".format(
            cmake_identifier(family)
        )
        if targets is ALL_EXACT_TARGETS:
            lines.append("set({}".format(var_name))
            lines.append("  ${_IREE_HAL_AMDGPU_DEVICE_TARGETS}")
            lines.append(")")
        else:
            lines.append(cmake_list(var_name, family_targets(targets)))
    lines.append("")
    return "\n".join(lines)


def render_target_id_inl():
    output_path = "runtime/src/iree/hal/drivers/amdgpu/util/target_id_map.inl"
    lines = [
        generated_header("//", output_path),
        "//",
        "// Included inside iree_hal_amdgpu_target_id_mappings.",
        "",
        "// clang-format off",
    ]
    feature_flag_names = {
        FEATURE_SRAMECC: "IREE_HAL_AMDGPU_TARGET_FEATURE_SUPPORT_SRAMECC",
        FEATURE_XNACK: "IREE_HAL_AMDGPU_TARGET_FEATURE_SUPPORT_XNACK",
    }
    for exact_target, code_object_target in EXACT_TARGET_CODE_OBJECTS:
        features = TARGET_FEATURE_SUPPORT.get(exact_target, ())
        feature_flags = " | ".join(feature_flag_names[feature] for feature in features)
        if not feature_flags:
            feature_flags = "IREE_HAL_AMDGPU_TARGET_FEATURE_SUPPORT_NONE"
        lines.append(
            '{{IREE_SVL("{}"), IREE_SVL("{}"), {}}},'.format(
                exact_target, code_object_target, feature_flags
            )
        )
    lines.append("")
    return "\n".join(lines)


def generated_outputs(repo_root):
    binary_output_dir = (
        repo_root / "runtime/src/iree/hal/drivers/amdgpu/device/binaries"
    )
    util_output_dir = repo_root / "runtime/src/iree/hal/drivers/amdgpu/util"
    return {
        binary_output_dir / "target_map.bzl": render_bzl(),
        binary_output_dir / "target_map.cmake": render_cmake(),
        util_output_dir / "target_id_map.inl": render_target_id_inl(),
    }


def check_outputs(repo_root, outputs):
    failed = False
    for path, content in outputs.items():
        if not path.exists():
            print("error: {} does not exist".format(path), file=sys.stderr)
            failed = True
            continue
        existing = path.read_text()
        if existing == content:
            continue
        rel_path = path.relative_to(repo_root)
        print("error: {} is out of date".format(rel_path), file=sys.stderr)
        diff = difflib.unified_diff(
            existing.splitlines(keepends=True),
            content.splitlines(keepends=True),
            fromfile=str(rel_path),
            tofile=str(rel_path) + " (generated)",
        )
        sys.stderr.writelines(diff)
        failed = True
    if failed:
        print(
            "Run 'python build_tools/scripts/amdgpu_target_map.py' to regenerate.",
            file=sys.stderr,
        )
        return 1
    print("AMDGPU target map generated files are up to date.")
    return 0


def write_outputs(outputs):
    for path, content in outputs.items():
        path.parent.mkdir(parents=True, exist_ok=True)
        path.write_text(content)
        print("Wrote {}".format(path))
    return 0


def main():
    parser = argparse.ArgumentParser(
        description="Generate AMDGPU device library target map fragments."
    )
    parser.add_argument(
        "--check",
        action="store_true",
        help="Check that generated files are up to date without modifying them.",
    )
    args = parser.parse_args()

    validate_target_map()
    repo_root = find_repo_root()
    outputs = generated_outputs(repo_root)
    if args.check:
        return check_outputs(repo_root, outputs)
    return write_outputs(outputs)


if __name__ == "__main__":
    sys.exit(main())
