Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mldebuglib.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from types import SimpleNamespace

from mldebug.aie_status import AIEStatus as _AIES
from mldebug.arch import AIE_DEV_PHX, AIE_DEV_STX
from mldebug.arch import AIE_DEV_STX
from mldebug.arch import load_aie_arch as _load_aie
from mldebug.aie_overlay import Overlay as _OL
from mldebug.input_parser import RunFlags as _RunFlags
Expand Down Expand Up @@ -64,7 +64,7 @@ def __init__(self, device=AIE_DEV_STX, overlay="4x4", ctxid=None, pid=None, back
raise ValueError(f"Unsupported backend '{backend}'. Use BACKEND_XRT or BACKEND_TEST.")
self.backend = backend
self.aie_iface = _load_aie(device)
self.aie_iface.init(device == AIE_DEV_PHX)
self.aie_iface.init(device)

if backend == BACKEND_XRT:
args = SimpleNamespace(device=device, aie_iface=self.aie_iface, l3=False)
Expand Down
26 changes: 25 additions & 1 deletion src/mldebug/arch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,28 @@
Top level AIE Arch Module
"""

from .loader import load_aie_arch, AIE_DEV_PHX, AIE_DEV_STX, AIE_DEV_TEL, AIE_DEV_NPU3
from .device_configs import (
AIE_DEV_NPU3,
AIE_DEV_PHX,
AIE_DEV_STX,
AIE_DEV_T10,
AIE_DEV_T20,
AIE_DEV_TEL,
DEVICE_CONFIGS,
get_base_device,
resolve_variant,
)
from .loader import load_aie_arch

__all__ = [
"AIE_DEV_NPU3",
"AIE_DEV_PHX",
"AIE_DEV_STX",
"AIE_DEV_T10",
"AIE_DEV_T20",
"AIE_DEV_TEL",
"DEVICE_CONFIGS",
"get_base_device",
"load_aie_arch",
"resolve_variant",
]
16 changes: 13 additions & 3 deletions src/mldebug/arch/aie2p_defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import json

from .device_configs import AIE_DEV_PHX, DEVICE_CONFIGS

AIE_TILE_T = "aie_tile"
SHIM_TILE_T = "shim_tile"
MEM_TILE_T = "mem_tile"
Expand Down Expand Up @@ -126,11 +128,19 @@ def _create_bds(tile_t, registers):
}


def init(is_aie2):
def init(device=None):
"""
Inititalize aie2/2p specific
Initialize aie2/2p specific state from the central registry.

`device` is the resolved sub-device name (e.g. 'phx' or 'stx'). It selects
AIE_TILE_ROW_OFFSET/MEM_TILE_SZ; AIE2 (phx) also relocates CORE_PC.
"""
if is_aie2:
global AIE_TILE_ROW_OFFSET, MEM_TILE_SZ
cfg = DEVICE_CONFIGS.get(device)
if cfg:
AIE_TILE_ROW_OFFSET = cfg["core_row_start"]
MEM_TILE_SZ = cfg["mem_tile_sz"]
if device == AIE_DEV_PHX:
Core_registers["CORE_PC"] = 0x31100


Expand Down
16 changes: 13 additions & 3 deletions src/mldebug/arch/aie2ps_defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import json

from .device_configs import DEVICE_CONFIGS

AIE_TILE_T = "aie_tile"
SHIM_TILE_T = "shim_tile"
MEM_TILE_T = "mem_tile"
Expand Down Expand Up @@ -128,11 +130,19 @@ def _create_bds(tile_t, registers):
}


def init(_):
def init(device=None):
"""
consistent interface with aie2p
Apply device/variant geometry from the central registry.

`device` is the resolved sub-device name (e.g. 'telluride' or 't20');
it selects AIE_TILE_ROW_OFFSET (= core_row_start) and MEM_TILE_SZ so
same-hwGen variants can differ in geometry.
"""
return
global AIE_TILE_ROW_OFFSET, MEM_TILE_SZ
cfg = DEVICE_CONFIGS.get(device)
if cfg:
AIE_TILE_ROW_OFFSET = cfg["core_row_start"]
MEM_TILE_SZ = cfg["mem_tile_sz"]


_create_bds(AIE_TILE_T, Core_registers)
Expand Down
146 changes: 146 additions & 0 deletions src/mldebug/arch/device_configs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2024-2026 Advanced Micro Devices, Inc. All rights reserved.

"""
Central device geometry registry -- single source of truth for per-device
and per-variant AIE geometry.

Keyed by device/variant name. Fields:
arch -- which defs module the loader should import (aie2p/aie2ps)
base -- base device name understood by the C++ binding and xrt-smi;
variants (e.g. t20) map back to their base (telluride)
hwGen -- hardware generation (matches the core-dump header hwGen)
core_row_start -- first core-tile row; also the AIE tile row offset
numrows/numcols -- full-device geometry, used to disambiguate variants
that share a hwGen

Variants may share a hwGen (telluride/t20) and are disambiguated by
(numrows, numcols).
"""

MB = 1024 * 1024

# Device / variant name constants. Defined here (the lowest-level arch module)
# so they can key DEVICE_CONFIGS; re-exported by loader for the rest of the code.
AIE_DEV_PHX = "phx"
AIE_DEV_STX = "stx"
AIE_DEV_TEL = "telluride"
AIE_DEV_NPU3 = "npu3"
AIE_DEV_T20 = "t20"
AIE_DEV_T10 = "t10"

# Arch (defs-module) names, resolved to modules by the loader.
ARCH_AIE2P = "aie2p"
ARCH_AIE2PS = "aie2ps"

DEVICE_CONFIGS = {
AIE_DEV_PHX: {
"arch": ARCH_AIE2P,
"base": AIE_DEV_PHX,
"hwGen": 2,
"baseAddr": 0x0,
"core_row_start": 2,
"mem_row_start": 1,
"memtile_rows": 1,
"numrows": 6,
"numcols": 4,
"shim_tile_block_size": MB,
"mem_tile_block_size": MB,
"core_tile_block_size": MB,
"mem_tile_sz": 0x80000,
},
AIE_DEV_STX: {
"arch": ARCH_AIE2P,
"base": AIE_DEV_STX,
"hwGen": 4,
"baseAddr": 0x0,
"core_row_start": 2,
"mem_row_start": 1,
"memtile_rows": 1,
"numrows": 6,
"numcols": 8,
"shim_tile_block_size": MB,
"mem_tile_block_size": MB,
"core_tile_block_size": MB,
"mem_tile_sz": 0x80000,
},
AIE_DEV_TEL: {
"arch": ARCH_AIE2PS,
"base": AIE_DEV_TEL,
"hwGen": 5,
"baseAddr": 0x0,
"core_row_start": 3,
"mem_row_start": 1,
"memtile_rows": 2,
"numrows": 7,
"numcols": 36,
"shim_tile_block_size": MB,
"mem_tile_block_size": MB,
"core_tile_block_size": MB,
"mem_tile_sz": 0x80000,
},
# aie2ps-based variants sharing telluride's hwGen; disambiguated by geometry.
AIE_DEV_T20: {
"arch": ARCH_AIE2PS,
"base": AIE_DEV_TEL,
"hwGen": 5,
"baseAddr": 0x0,
"core_row_start": 2,
"mem_row_start": 1,
"memtile_rows": 1,
"numrows": 6,
"numcols": 24,
"shim_tile_block_size": MB,
"mem_tile_block_size": MB,
"core_tile_block_size": MB,
"mem_tile_sz": 0x80000,
},
AIE_DEV_T10: {
"arch": ARCH_AIE2PS,
"base": AIE_DEV_TEL,
"hwGen": 5,
"baseAddr": 0x0,
"core_row_start": 2,
"mem_row_start": 1,
"memtile_rows": 1,
"numrows": 4,
"numcols": 8,
"shim_tile_block_size": MB,
"mem_tile_block_size": MB,
"core_tile_block_size": MB,
"mem_tile_sz": 0x80000,
},
}


def get_base_device(name):
"""
Return the base device name for a device/variant. Unknown names map to
themselves so callers can pass through user-specified devices unchanged.
"""
cfg = DEVICE_CONFIGS.get(name)
return cfg["base"] if cfg else name


def resolve_variant(hw_gen, num_rows=None, num_cols=None):
"""
Resolve a device/variant name from a hardware generation and (optional)
full-device geometry.

Matches hwGen first. When several variants share a hwGen, disambiguate by
(num_rows, num_cols). Falls back to the first (base) candidate when the
geometry is unavailable or does not match a variant. Returns None if no
device matches the hwGen.
"""
candidates = [n for n, c in DEVICE_CONFIGS.items() if c["hwGen"] == hw_gen]
if not candidates:
return None
if len(candidates) == 1:
return candidates[0]
if num_rows is not None and num_cols is not None:
for n in candidates:
c = DEVICE_CONFIGS[n]
if c["numrows"] == num_rows and c["numcols"] == num_cols:
return n
# Base device is listed first among same-hwGen candidates.
return candidates[0]
25 changes: 15 additions & 10 deletions src/mldebug/arch/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,24 @@

import importlib

AIE_DEV_PHX = "phx"
AIE_DEV_STX = "stx"
AIE_DEV_TEL = "telluride"
AIE_DEV_NPU3 = "npu3"
from .device_configs import AIE_DEV_NPU3, ARCH_AIE2P, ARCH_AIE2PS, DEVICE_CONFIGS

# Maps a config's `arch` field to its defs module.
_ARCH_MODULES = {
ARCH_AIE2P: ".aie2p_defs",
ARCH_AIE2PS: ".aie2ps_defs",
}


def load_aie_arch(device):
"""
return specific aie arch module based on name
return specific aie arch module based on device/variant name
"""
mod = ".aie2p_defs"
if device == AIE_DEV_TEL:
mod = ".aie2ps_defs"
elif device == AIE_DEV_NPU3:
mod = ".npu3_defs"
# npu3 is not yet in the geometry registry; keep it as a special case.
if device == AIE_DEV_NPU3:
return importlib.import_module(".npu3_defs", package="mldebug.arch")

cfg = DEVICE_CONFIGS.get(device)
arch = cfg["arch"] if cfg else ARCH_AIE2P
mod = _ARCH_MODULES.get(arch, ".aie2p_defs")
return importlib.import_module(mod, package="mldebug.arch")
52 changes: 6 additions & 46 deletions src/mldebug/backend/core_dump_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@

import struct
from pathlib import Path

from mldebug.arch import DEVICE_CONFIGS, resolve_variant
from mldebug.utils import print_tile_grid
from mldebug.arch import AIE_DEV_PHX, AIE_DEV_STX, AIE_DEV_TEL, AIE_DEV_NPU3

from .backend_interface import BackendInterface

try:
Expand All @@ -18,46 +20,6 @@
except ImportError:
HAS_XRT_BACKEND = False

# Device architecture metadata (from C++ CoreDumpDataAccessBackend)
DEVICE_CONFIGS = {
AIE_DEV_PHX: {
"hwGen": 2,
"baseAddr": 0x0,
"core_row_start": 2,
"mem_row_start": 1,
"memtile_rows": 1,
"numrows": 6,
"numcols": 4,
"shim_tile_block_size": 1024 * 1024, # 1MB
"mem_tile_block_size": 1024 * 1024, # 1MB
"core_tile_block_size": 1024 * 1024, # 1MB
},
AIE_DEV_STX: {
"hwGen": 4,
"baseAddr": 0x0,
"core_row_start": 2,
"mem_row_start": 1,
"memtile_rows": 1,
"numrows": 6,
"numcols": 8,
"shim_tile_block_size": 1024 * 1024,
"mem_tile_block_size": 1024 * 1024,
"core_tile_block_size": 1024 * 1024,
},
AIE_DEV_TEL: {
"hwGen": 5,
"baseAddr": 0x0,
"core_row_start": 3,
"mem_row_start": 1,
"memtile_rows": 2,
"numrows": 7,
"numcols": 36,
"shim_tile_block_size": 1024 * 1024,
"mem_tile_block_size": 1024 * 1024,
"core_tile_block_size": 1024 * 1024,
},
}


class CoreDumpFallbackReader:
"""
Expand Down Expand Up @@ -155,11 +117,9 @@ def peek_device(filename):
"<BBBBBB", header[8:14]
)

detected = None
for name, cfg in DEVICE_CONFIGS.items():
if cfg["hwGen"] == hw_gen:
detected = name
break
# Match hwGen, disambiguating same-hwGen variants (e.g. telluride/t20)
# by the header's total rows/cols.
detected = resolve_variant(hw_gen, total_rows, total_cols)

print("[INFO] Core dump header:")
print(f" Magic: {magic.decode('ascii', errors='ignore').rstrip(chr(0))}")
Expand Down
Loading
Loading