From e77dd1a1abb0cb761b43d6b5a08e06b522f5625f Mon Sep 17 00:00:00 2001 From: xuchen-amd Date: Tue, 1 Apr 2025 12:18:07 -0400 Subject: [PATCH] Improve chip id logic (#648) * Improve chip id logic, add missing physical and virtual chip ids. --- src/rocprof_compute_soc/soc_base.py | 4 +- src/utils/mi_gpu_spec.py | 159 ++++-------------------- src/utils/mi_gpu_spec.yaml | 184 +++++++++++++--------------- src/utils/specs.py | 18 +-- 4 files changed, 120 insertions(+), 245 deletions(-) diff --git a/src/rocprof_compute_soc/soc_base.py b/src/rocprof_compute_soc/soc_base.py index c47d4f9346..7dd9fb4706 100644 --- a/src/rocprof_compute_soc/soc_base.py +++ b/src/rocprof_compute_soc/soc_base.py @@ -180,11 +180,11 @@ class OmniSoC_Base: self._mspec.cur_sclk = self._mspec.max_sclk self._mspec.cur_mclk = self._mspec.max_mclk - self._mspec.gpu_series = get_gpu_series(self._mspec.gpu_arch).upper() + self._mspec.gpu_series = get_gpu_series(self._mspec.gpu_arch) # specify gpu model name for gfx942 hardware self._mspec.gpu_model = get_gpu_model( self._mspec.gpu_arch, self._mspec.gpu_chip_id - ).upper() + ) self._mspec.num_xcd = str( total_xcds(self._mspec.gpu_model, self._mspec.compute_partition) ) diff --git a/src/utils/mi_gpu_spec.py b/src/utils/mi_gpu_spec.py index ecdc1e161b..957e5ae955 100644 --- a/src/utils/mi_gpu_spec.py +++ b/src/utils/mi_gpu_spec.py @@ -18,123 +18,11 @@ MI_CONSTANS = {MI50: "mi50", MI100: "mi100", MI200: "mi200", MI300: "mi300"} gpu_series_dict = {} # key: gpu arch gpu_model_dict = {} # key: gpu_arch -mi300_archs_dict = {} # key: gpu model mi300_num_xcds_dict = {} # key: gpu model -mi300_nps_dict = {} # key: gpu model (NOTE: key can also be architecture) +mi300_nps_dict = {} # key: gpu model mi300_chip_id_dict = {} # key: chip id (int) -# ---------------------------- -# Data Class handling to preserve the hierarchical gpu information -# ---------------------------- - - -@dataclass -class ComputePartitionMode: - """ - Represents the compute partition mode. - """ - - def __init__(self, num_xcds=None): - self.__num_xcds = num_xcds - - def get_num_xcds(self): - return self.__num_xcds - - -class Singleton(object): - _instances = {} - - def __new__(class_, *args, **kwargs): - if class_ not in class_._instances: - class_._instances[class_] = super(Singleton, class_).__new__( - class_, *args, **kwargs - ) - return class_._instances[class_] - - -@dataclass -class MIGPU(Singleton): - """ - Singleton class representing the detected MI GPU of current system. - Ensures only one instance exists. - """ - - _instance = None # Class variable to hold the single instance - - def __new__(cls, *args, **kwargs): - if cls._instance is None: - cls._instance = super(MIGPU, cls).__new__(cls) - cls._instance.mi_gpu_spec = [] # Initialize the instance attribute - return cls._instance - - def __init__( - self, - gpu_series, - gpu_arch, - gpu_model, - chip_id=None, - mi300_arch=None, - num_xcds=None, - ): - """ - gpu series, gpu_arch and gpu_model information must be available for a given MI GPU. - gpu series (str) - gpu_arch (str) - gpu_model (str) - """ - # gpu_series (str): The GPU series name (e.g., 'mi50', 'mi100', 'mi200', 'mi300') - self.gpu_series = gpu_series - self.gpu_arch = gpu_arch - self.gpu_model = gpu_model - self.chip_id = chip_id - self.mi300_arch = mi300_arch - self.compute_partition = ComputePartitionMode(num_xcds) - - self.is_mi300 = True if self.mi300_arch is not None else False - - def __post_init__(self): - if self.is_mi300: - # NOTE: currently, all mi300 series gpus shall have compute partition information - if self.compute_partition is None: - console_warning( - "[MIGPU post init] mi300 gpu detected, but no num_xcd/compute partition data detected!!!" - ) - - def set_chip_id(self, chip_id): - self.chip_id = chip_id - - def set_mi300_arch(self, mi300_arch, num_xcds): - """ - All mi300 series gpus shall have compute partition information. - """ - if num_xcds is None: - console_warning( - "[MIGPU post init] mi300 gpu detected, but no num_xcd/compute partition data detected!!!" - ) - - self.mi300_arch = mi300_arch - self.compute_partition = ComputePartitionMode(num_xcds) - - def get_gpu_series(self): - return self.gpu_series - - def get_gpu_arch(self): - return self.gpu_arch - - def get_gpu_model(self): - return self.gpu_model - - def get_chip_id(self): - return self.chip_id - - def get_mi300_arch(self): - return self.mi300_arch - - def get_compute_partition(self): - return self.compute_partition - - # ---------------------------- # YAML Parsing and Data Handling # ---------------------------- @@ -210,25 +98,31 @@ def parse_mi_gpu_spec(): for models in value[MI300]["gpu_archs"][idx]["models"]: gpu_model = models["gpu_model"] - # NOTE: mi300 architecture is available for all mi300 gpu models - mi300_archs_dict[gpu_model] = models["mi300_arch"]["architecture"] + # 1. Parse compute partition. NOTE: compute partition mode num xcds is available for all mi300 gpu models + mi300_num_xcds_dict[gpu_model] = models["partition_mode"][ + "compute_partition_mode" + ]["num_xcds"] - # NOTE: compute partition mode num xcds is available for all mi300 gpu models - mi300_num_xcds_dict[gpu_model] = models["mi300_arch"][ - "partition_mode" - ]["compute_partition_mode"]["num_xcds"] + # 2. Parse memory_partition. NOTE: memory partition mode nps is available for all mi300 gpu models + mi300_nps_dict[gpu_model] = models["partition_mode"][ + "memory_partition_mode" + ] - # NOTE: memory partition mode nps is available for all mi300 gpu models - mi300_nps_dict[gpu_model] = models["mi300_arch"][ - "partition_mode" - ]["memory_partition_mode"] - - if not models["chip_ids"]["local"] is None: + # 3. Parse chip id (physical and virtual). + if models["chip_ids"]["physical"]: # save chip_id, gpu_model pair if chip id is available # NOTE: chip id is available for all gfx942 machines - mi300_chip_id_dict[models["chip_ids"]["local"]] = models[ + mi300_chip_id_dict[models["chip_ids"]["physical"]] = models[ "gpu_model" ] + + if models["chip_ids"]["virtual"]: + # save chip_id, gpu_model pair if chip id is available + # NOTE: chip id is available for all gfx942 machines + mi300_chip_id_dict[models["chip_ids"]["virtual"]] = models[ + "gpu_model" + ] + mi300_models_dict[arch].append(gpu_model) gpu_model_dict.update(mi300_models_dict) @@ -253,7 +147,7 @@ def get_gpu_series(gpu_arch_): # Normalize the key by checking both the raw and lowercase versions gpu_series = gpu_series_dict.get(gpu_arch_) or gpu_series_dict.get(gpu_arch_.lower()) if gpu_series: - return gpu_series + return gpu_series.upper() console_warning(f"No matching gpu series found for gpu arch: {gpu_arch_}") return None @@ -289,16 +183,7 @@ def get_gpu_model(gpu_arch_, chip_id_): console_warning(f"No gpu model found for gpu arch: {gpu_arch_lower}") return None - return gpu_model - - -def get_mi300_archs_dict(): - if not mi300_archs_dict: - console_error( - "mi300_archs_dict not yet populated, did you run parse_mi_gpu_spec()?" - ) - return None - return mi300_archs_dict + return gpu_model.upper() def get_mi300_num_xcds(gpu_model_, compute_partition_): diff --git a/src/utils/mi_gpu_spec.yaml b/src/utils/mi_gpu_spec.yaml index c481ffd963..a86779a62e 100644 --- a/src/utils/mi_gpu_spec.yaml +++ b/src/utils/mi_gpu_spec.yaml @@ -11,10 +11,9 @@ # |-- architecture: currently, only mi300 gpus hold different architectures # |-- models # |-- chip_ids: chip id is specific to the environment the gpu is being used on -# |-- mi300_arch: mi300 specific architectures; mi300a, mi300x -# |-- partition_mode: currently, only mi300 gpus hold partition mode information -# two types: compute partition mode, memory partition mode, -# currently only mi300 gpus contains compute partition mode information on number of xcds +# |-- partition_mode: currently, only mi300 gpus hold partition mode information +# two types: compute partition mode, memory partition mode, +# currently only mi300 gpus contains compute partition mode information on number of xcds # # -------------------------------------------------------------------------------- @@ -24,141 +23,130 @@ mi_gpu_spec: - gpu_arch: gfx906 models: - gpu_model: mi50 - mi300_arch: - architecture: null - partition_mode: null + partition_mode: null chip_ids: - local: null + physical: null + virtual: null - gpu_model: mi60 - mi300_arch: - architecture: null - partition_mode: null + partition_mode: null chip_ids: - local: null + physical: null + virtual: null - gpu_series: mi100 gpu_archs: - gpu_arch: gfx908 models: - gpu_model: mi100 - mi300_arch: - architecture: null - partition_mode: null + partition_mode: null chip_ids: - local: null + physical: 29580 + virtual: null - gpu_series: mi200 gpu_archs: - gpu_arch: gfx90a models: - gpu_model: mi210 - mi300_arch: - architecture: null - partition_mode: null + partition_mode: null chip_ids: - local: null + physical: 29711 + virtual: null - gpu_model: mi250 - mi300_arch: - architecture: null - partition_mode: null + partition_mode: null chip_ids: - local: null + physical: 29708 + virtual: null - gpu_model: mi250x - mi300_arch: - architecture: null - partition_mode: null + partition_mode: null chip_ids: - local: null + physical: 29704 + virtual: null - gpu_series: mi300 gpu_archs: - gpu_arch: gfx940 models: - gpu_model: mi300a_a0 - mi300_arch: - architecture: mi300a - partition_mode: - compute_partition_mode: - num_xcds: - spx: 6 - dpx: null - tpx: 2 - qpx: null - cpx: null - memory_partition_mode: - nps4: {tpx} - nps1: {spx, tpx} + partition_mode: + compute_partition_mode: + num_xcds: + spx: 6 + dpx: null + tpx: 2 + qpx: null + cpx: null + memory_partition_mode: + nps4: [tpx] + nps1: [spx, tpx] chip_ids: - local: null + physical: null + virtual: null - gpu_arch: gfx941 models: - gpu_model: mi300x_a0 - mi300_arch: - architecture: mi300x - partition_mode: - compute_partition_mode: - num_xcds: - spx: 8 - dpx: 4 - tpx: null - qpx: 2 - cpx: 1 - memory_partition_mode: - nps4: {qpx, cpx} - nps1: {spx, qpx, cpx} + partition_mode: + compute_partition_mode: + num_xcds: + spx: 8 + dpx: 4 + tpx: null + qpx: 2 + cpx: 1 + memory_partition_mode: + nps4: [qpx, cpx] + nps1: [spx, qpx, cpx] chip_ids: - local: null + physical: null + virtual: null - gpu_arch: gfx942 models: - gpu_model: mi300a_a1 - mi300_arch: - architecture: mi300a - partition_mode: - compute_partition_mode: - num_xcds: - spx: 6 - dpx: null - tpx: 2 - qpx: null - cpx: null - memory_partition_mode: - nps4: {tpx} - nps1: {spx, tpx} + partition_mode: + compute_partition_mode: + num_xcds: + spx: 6 + dpx: null + tpx: 2 + qpx: null + cpx: null + memory_partition_mode: + nps4: [tpx] + nps1: [spx, tpx] chip_ids: - local: 29856 + physical: 29856 + virtual: 29876 - gpu_model: mi300x_a1 - mi300_arch: - architecture: mi300x - partition_mode: - compute_partition_mode: - num_xcds: - spx: 8 - dpx: 4 - tpx: null - qpx: 2 - cpx: 1 - memory_partition_mode: - nps4: {qpx, cpx} - nps1: {spx, qpx, cpx} + partition_mode: + compute_partition_mode: + num_xcds: + spx: 8 + dpx: 4 + tpx: null + qpx: 2 + cpx: 1 + memory_partition_mode: + nps4: [qpx, cpx] + nps1: [spx, qpx, cpx] chip_ids: - local: 29857 + physical: 29857 + virtual: 29877 - gpu_model: mi308x - mi300_arch: - architecture: mi308x - partition_mode: - compute_partition_mode: - num_xcds: - spx: 4 - dpx: 2 - tpx: null - qpx: null - cpx: 1 - memory_partition_mode: - nps4: {cpx} - nps1: {spx, dpx, cpx} + partition_mode: + compute_partition_mode: + num_xcds: + spx: 4 + dpx: 2 + tpx: null + qpx: null + cpx: 1 + memory_partition_mode: + nps4: [cpx] + nps1: [spx, dpx, cpx] chip_ids: - local: 29858 + physical: 29858 + virtual: 29878 diff --git a/src/utils/specs.py b/src/utils/specs.py index 298fe8ff1d..c0bf2a326a 100644 --- a/src/utils/specs.py +++ b/src/utils/specs.py @@ -71,20 +71,21 @@ def detect_arch(_rocminfo): def detect_gpu_chip_id(_rocminfo): + gpu_chip_id = None + mi300_chip_id_dict = get_mi300_chip_id_dict().keys() + for idx1, linetext in enumerate(_rocminfo): # NOTE: current supported socs only have numbers in Chip ID - gpu_chip_id = search(r"^\s*Chip ID\s*:\s* ([0-9]+).*\s*$", linetext) - if gpu_chip_id and int(gpu_chip_id) in get_mi300_chip_id_dict().keys(): - gpu_chip_id = str(gpu_chip_id) - break - if str(gpu_chip_id) in get_mi300_chip_id_dict().keys(): - gpu_chip_id = str(gpu_chip_id) + chip_found = search(r"^\s*Chip ID\s*:\s* ([0-9]+).*\s*$", linetext) + if chip_found: + gpu_chip_id = str(chip_found) break + if not gpu_chip_id: console_warning("No Chip ID detected: " + str(gpu_chip_id)) elif ( - gpu_chip_id not in get_mi300_chip_id_dict().keys() - and int(gpu_chip_id) not in get_mi300_chip_id_dict().keys() + gpu_chip_id not in mi300_chip_id_dict + and int(gpu_chip_id) not in mi300_chip_id_dict ): console_warning("Unknown Chip ID detected: " + str(gpu_chip_id)) return gpu_chip_id @@ -541,6 +542,7 @@ class MachineSpecs: mi300a_archs = ["mi300a_a0", "mi300a_a1"] mi300x_archs = ["mi300x_a0", "mi300x_a1"] mi308x_archs = ["mi308x"] + if self.gpu_model.lower() in mi300a_archs + mi300x_archs + mi308x_archs: hbmchannels = 128 if self.memory_partition.lower() == "nps2":