Add chip specs (#681)
* Add perfmon config spec, enhance memory partition info. * Add gfx950 perfmon config. * Add High Freq variants in gfx942. * Add backup detection methods for gpu model. * Improve get_num_xcds logic by adding detection of 1to1 arch-to-compute_partition logic. * Add default compute partition settings spx:8 for when gpu_model=None. * Update gpu spec tests. * Add backup compute partition detection. --------- Signed-off-by: xuchen-amd <xuchen@amd.com>
This commit is contained in:
@@ -186,12 +186,73 @@ class OmniSoC_Base:
|
||||
self._mspec.gpu_model = mi_gpu_specs.get_gpu_model(
|
||||
self._mspec.gpu_arch, self._mspec.gpu_chip_id
|
||||
)
|
||||
|
||||
if not self._mspec.gpu_model:
|
||||
self._mspec.gpu_model = self.detect_gpu_model(self._mspec.gpu_arch)
|
||||
|
||||
self._mspec.num_xcd = str(
|
||||
mi_gpu_specs.get_num_xcds(
|
||||
self._mspec.gpu_model, self._mspec.compute_partition
|
||||
self._mspec.gpu_arch, self._mspec.gpu_model, self._mspec.compute_partition
|
||||
)
|
||||
)
|
||||
|
||||
@demarcate
|
||||
def detect_gpu_model(self, gpu_arch):
|
||||
"""
|
||||
Detects the GPU model using various identifiers from 'amd-smi static'.
|
||||
Falls back through multiple methods if the primary method fails.
|
||||
"""
|
||||
|
||||
from utils.specs import run, search
|
||||
|
||||
# TODO: use amd-smi python api when available
|
||||
amd_smi_static = run(["amd-smi", "static", "--gpu=0"], exit_on_error=True)
|
||||
|
||||
# Purposely search for patterns without variants suffix to try and match a known GPU model.
|
||||
detection_methods = [
|
||||
{
|
||||
"name": "Market Name",
|
||||
"pattern": r"MARKET_NAME:\s*.*(mi|MI\d*[a-zA-Z]*)",
|
||||
},
|
||||
{
|
||||
"name": "VBIOS Name",
|
||||
"pattern": r"NAME:\s*.*(mi|MI\d*[a-zA-Z]*)",
|
||||
},
|
||||
{"name": "Product Name", "pattern": r"PRODUCT_NAME:\s*.*(mi|MI\d*[a-zA-Z]*)"},
|
||||
]
|
||||
|
||||
gpu_model = None
|
||||
for method in detection_methods:
|
||||
console_log(f"Determining GPU model using {method['name']}.")
|
||||
gpu_model = search(method["pattern"], amd_smi_static)
|
||||
if gpu_model:
|
||||
break
|
||||
|
||||
if not gpu_model:
|
||||
console_warning("Unable to determine the GPU model.")
|
||||
return
|
||||
|
||||
gpu_model = self._adjust_mi300_model(gpu_model.lower(), gpu_arch.lower())
|
||||
|
||||
if gpu_model.lower() not in mi_gpu_specs.get_num_xcds_dict().keys():
|
||||
console_warning(f"Unknown GPU model detected: '{gpu_model}'.")
|
||||
return
|
||||
|
||||
return gpu_model.upper()
|
||||
|
||||
def _adjust_mi300_model(self, gpu_model, gpu_arch):
|
||||
"""
|
||||
Applies specific adjustments for MI300 series GPU models based on architecture.
|
||||
"""
|
||||
|
||||
if gpu_model in ["mi300a", "mi300x"]:
|
||||
if gpu_arch in ["gfx940", "gfx941"]:
|
||||
gpu_model += "_a0"
|
||||
elif gpu_arch == "gfx942":
|
||||
gpu_model += "_a1"
|
||||
|
||||
return gpu_model
|
||||
|
||||
@demarcate
|
||||
def detect_counters(self):
|
||||
"""
|
||||
|
||||
@@ -22,11 +22,9 @@
|
||||
# SOFTWARE.
|
||||
##############################################################################el
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import config
|
||||
from rocprof_compute_soc.soc_base import OmniSoC_Base
|
||||
from utils.logger import console_error, demarcate
|
||||
from utils.mi_gpu_spec import mi_gpu_specs
|
||||
|
||||
|
||||
class gfx906_soc(OmniSoC_Base):
|
||||
@@ -35,20 +33,7 @@ class gfx906_soc(OmniSoC_Base):
|
||||
self.set_arch("gfx906")
|
||||
self.set_compatible_profilers(["rocprofv1", "rocscope"])
|
||||
# Per IP block max number of simultaneous counters. GFX IP Blocks
|
||||
self.set_perfmon_config(
|
||||
{
|
||||
"SQ": 8,
|
||||
"TA": 2,
|
||||
"TD": 2,
|
||||
"TCP": 4,
|
||||
"TCC": 4,
|
||||
"CPC": 2,
|
||||
"CPF": 2,
|
||||
"SPI": 2,
|
||||
"GRBM": 2,
|
||||
"GDS": 4,
|
||||
}
|
||||
)
|
||||
self.set_perfmon_config({mi_gpu_specs.get_perfmon_config("gfx906")})
|
||||
|
||||
# Set arch specific specs
|
||||
self._mspec._l2_banks = 16
|
||||
|
||||
@@ -27,6 +27,7 @@ from pathlib import Path
|
||||
import config
|
||||
from rocprof_compute_soc.soc_base import OmniSoC_Base
|
||||
from utils.logger import console_error, demarcate
|
||||
from utils.mi_gpu_spec import mi_gpu_specs
|
||||
|
||||
|
||||
class gfx908_soc(OmniSoC_Base):
|
||||
@@ -37,20 +38,7 @@ class gfx908_soc(OmniSoC_Base):
|
||||
["rocprofv1", "rocscope", "rocprofv3", "rocprofiler-sdk"]
|
||||
)
|
||||
# Per IP block max number of simultaneous counters. GFX IP Blocks
|
||||
self.set_perfmon_config(
|
||||
{
|
||||
"SQ": 8,
|
||||
"TA": 2,
|
||||
"TD": 2,
|
||||
"TCP": 4,
|
||||
"TCC": 4,
|
||||
"CPC": 2,
|
||||
"CPF": 2,
|
||||
"SPI": 2,
|
||||
"GRBM": 2,
|
||||
"GDS": 4,
|
||||
}
|
||||
)
|
||||
self.set_perfmon_config(mi_gpu_specs.get_perfmon_config("gfx908"))
|
||||
|
||||
# Set arch specific specs
|
||||
self._mspec._l2_banks = 32
|
||||
|
||||
@@ -28,6 +28,7 @@ import config
|
||||
from rocprof_compute_soc.soc_base import OmniSoC_Base
|
||||
from roofline import Roofline
|
||||
from utils.logger import console_log, console_warning, demarcate
|
||||
from utils.mi_gpu_spec import mi_gpu_specs
|
||||
from utils.utils import mibench
|
||||
|
||||
|
||||
@@ -50,20 +51,7 @@ class gfx90a_soc(OmniSoC_Base):
|
||||
["rocprofv1", "rocscope", "rocprofv2", "rocprofv3", "rocprofiler-sdk"]
|
||||
)
|
||||
# Per IP block max number of simultaneous counters. GFX IP Blocks
|
||||
self.set_perfmon_config(
|
||||
{
|
||||
"SQ": 8,
|
||||
"TA": 2,
|
||||
"TD": 2,
|
||||
"TCP": 4,
|
||||
"TCC": 4,
|
||||
"CPC": 2,
|
||||
"CPF": 2,
|
||||
"SPI": 2,
|
||||
"GRBM": 2,
|
||||
"GDS": 4,
|
||||
}
|
||||
)
|
||||
self.set_perfmon_config(mi_gpu_specs.get_perfmon_config("gfx90a"))
|
||||
# Create roofline object if mode is provided; skip for --specs
|
||||
if hasattr(self.get_args(), "mode") and self.get_args().mode:
|
||||
self.roofline_obj = Roofline(args, self._mspec)
|
||||
|
||||
@@ -28,6 +28,7 @@ import config
|
||||
from rocprof_compute_soc.soc_base import OmniSoC_Base
|
||||
from roofline import Roofline
|
||||
from utils.logger import console_error, console_log, console_warning, demarcate
|
||||
from utils.mi_gpu_spec import mi_gpu_specs
|
||||
from utils.utils import mibench
|
||||
|
||||
|
||||
@@ -50,20 +51,7 @@ class gfx940_soc(OmniSoC_Base):
|
||||
["rocprofv1", "rocprofv2", "rocprofv3", "rocprofiler-sdk"]
|
||||
)
|
||||
# Per IP block max number of simultaneous counters. GFX IP Blocks
|
||||
self.set_perfmon_config(
|
||||
{
|
||||
"SQ": 8,
|
||||
"TA": 2,
|
||||
"TD": 2,
|
||||
"TCP": 4,
|
||||
"TCC": 4,
|
||||
"CPC": 2,
|
||||
"CPF": 2,
|
||||
"SPI": 2,
|
||||
"GRBM": 2,
|
||||
"GDS": 4,
|
||||
}
|
||||
)
|
||||
self.set_perfmon_config(mi_gpu_specs.get_perfmon_config("gfx940"))
|
||||
# Create roofline object if mode is provided; skip for --specs
|
||||
if hasattr(self.get_args(), "mode") and self.get_args().mode:
|
||||
self.roofline_obj = Roofline(args, self._mspec)
|
||||
|
||||
@@ -28,6 +28,7 @@ import config
|
||||
from rocprof_compute_soc.soc_base import OmniSoC_Base
|
||||
from roofline import Roofline
|
||||
from utils.logger import console_error, console_log, console_warning, demarcate
|
||||
from utils.mi_gpu_spec import mi_gpu_specs
|
||||
from utils.utils import mibench
|
||||
|
||||
|
||||
@@ -50,20 +51,7 @@ class gfx941_soc(OmniSoC_Base):
|
||||
["rocprofv1", "rocprofv2", "rocprofv3", "rocprofiler-sdk"]
|
||||
)
|
||||
# Per IP block max number of simultaneous counters. GFX IP Blocks
|
||||
self.set_perfmon_config(
|
||||
{
|
||||
"SQ": 8,
|
||||
"TA": 2,
|
||||
"TD": 2,
|
||||
"TCP": 4,
|
||||
"TCC": 4,
|
||||
"CPC": 2,
|
||||
"CPF": 2,
|
||||
"SPI": 2,
|
||||
"GRBM": 2,
|
||||
"GDS": 4,
|
||||
}
|
||||
)
|
||||
self.set_perfmon_config(mi_gpu_specs.get_perfmon_config("gfx941"))
|
||||
# Create roofline object if mode is provided; skip for --specs
|
||||
if hasattr(self.get_args(), "mode") and self.get_args().mode:
|
||||
self.roofline_obj = Roofline(args, self._mspec)
|
||||
|
||||
@@ -28,6 +28,7 @@ import config
|
||||
from rocprof_compute_soc.soc_base import OmniSoC_Base
|
||||
from roofline import Roofline
|
||||
from utils.logger import console_error, console_log, console_warning, demarcate
|
||||
from utils.mi_gpu_spec import mi_gpu_specs
|
||||
from utils.utils import mibench
|
||||
|
||||
|
||||
@@ -50,20 +51,7 @@ class gfx942_soc(OmniSoC_Base):
|
||||
["rocprofv1", "rocprofv2", "rocprofv3", "rocprofiler-sdk"]
|
||||
)
|
||||
# Per IP block max number of simultaneous counters. GFX IP Blocks
|
||||
self.set_perfmon_config(
|
||||
{
|
||||
"SQ": 8,
|
||||
"TA": 2,
|
||||
"TD": 2,
|
||||
"TCP": 4,
|
||||
"TCC": 4,
|
||||
"CPC": 2,
|
||||
"CPF": 2,
|
||||
"SPI": 2,
|
||||
"GRBM": 2,
|
||||
"GDS": 4,
|
||||
}
|
||||
)
|
||||
self.set_perfmon_config(mi_gpu_specs.get_perfmon_config("gfx942"))
|
||||
# Create roofline object if mode is provided; skip for --specs
|
||||
if hasattr(self.get_args(), "mode") and self.get_args().mode:
|
||||
self.roofline_obj = Roofline(args, self._mspec)
|
||||
|
||||
@@ -27,8 +27,9 @@ from pathlib import Path
|
||||
import config
|
||||
from rocprof_compute_soc.soc_base import OmniSoC_Base
|
||||
from roofline import Roofline
|
||||
from utils.logger import demarcate
|
||||
from utils.utils import console_error, console_log, console_warning, mibench
|
||||
from utils.logger import console_error, console_log, console_warning, demarcate
|
||||
from utils.mi_gpu_spec import mi_gpu_specs
|
||||
from utils.utils import mibench
|
||||
|
||||
|
||||
class gfx950_soc(OmniSoC_Base):
|
||||
@@ -48,21 +49,7 @@ class gfx950_soc(OmniSoC_Base):
|
||||
)
|
||||
self.set_compatible_profilers(["rocprofv3", "rocprofiler-sdk"])
|
||||
# Per IP block max number of simultaneous counters. GFX IP Blocks
|
||||
self.set_perfmon_config(
|
||||
{
|
||||
"SQ": 8,
|
||||
"TA": 2,
|
||||
"TD": 2,
|
||||
"TCP": 4,
|
||||
"TCC": 4,
|
||||
"CPC": 2,
|
||||
"CPF": 2,
|
||||
"SPI": 2,
|
||||
"GRBM": 2,
|
||||
"GDS": 4,
|
||||
"TCC_channels": 16,
|
||||
}
|
||||
)
|
||||
self.set_perfmon_config(mi_gpu_specs.get_perfmon_config("gfx950"))
|
||||
# Create roofline object if mode is provided; skip for --specs
|
||||
if hasattr(self.get_args(), "mode") and self.get_args().mode:
|
||||
self.roofline_obj = Roofline(args, self._mspec)
|
||||
|
||||
+150
-33
@@ -1,10 +1,10 @@
|
||||
import os
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict
|
||||
|
||||
import yaml
|
||||
|
||||
from utils.logger import console_debug, console_error, console_log, console_warning
|
||||
from utils.logger import console_debug, console_error, console_warning
|
||||
|
||||
# Constants for MI series
|
||||
# NOTE: Currently supports MI50, MI100, MI200, MI300
|
||||
@@ -32,10 +32,15 @@ MI_CONSTANS = {
|
||||
class MIGPUSpecs:
|
||||
_instance = None
|
||||
|
||||
_gpu_series_dict = {} # key: gpu arch
|
||||
_gpu_series_dict = {} # key: gpu_arch
|
||||
_gpu_model_dict = {} # key: gpu_arch
|
||||
_num_xcds_dict = {} # key: gpu model
|
||||
_chip_id_dict = {} # key: chip id (int)
|
||||
_num_xcds_dict = {} # key: gpu_model
|
||||
_chip_id_dict = {} # key: chip_id (int)
|
||||
_perfmon_config = {} # key: gpu_arch
|
||||
|
||||
_gpu_arch_to_compute_partition_dict = (
|
||||
{}
|
||||
) # key: gpu_arch, used for gpu archs containing only one gpu model and thus one compute partition
|
||||
|
||||
_initialized = False
|
||||
|
||||
@@ -88,9 +93,14 @@ class MIGPUSpecs:
|
||||
MI GPUs
|
||||
|-- series
|
||||
|-- architecture (list)
|
||||
|-- perfmon_config
|
||||
|-- gpu model
|
||||
|-- chip_ids
|
||||
| -- physical
|
||||
| -- virtual
|
||||
|-- partition_mode
|
||||
| -- compute partition mode
|
||||
| -- memory partition mode
|
||||
"""
|
||||
|
||||
current_dir = os.path.dirname(__file__)
|
||||
@@ -105,6 +115,7 @@ class MIGPUSpecs:
|
||||
for archs in series["gpu_archs"]:
|
||||
curr_gpu_arch = archs["gpu_arch"]
|
||||
cls._gpu_series_dict[curr_gpu_arch] = curr_gpu_series
|
||||
cls._perfmon_config[curr_gpu_arch] = archs["perfmon_config"]
|
||||
cls._gpu_model_dict[curr_gpu_arch] = []
|
||||
for models in archs["models"]:
|
||||
curr_gpu_model = models["gpu_model"]
|
||||
@@ -119,6 +130,28 @@ class MIGPUSpecs:
|
||||
if "chip_ids" in models and "virtual" in models["chip_ids"]:
|
||||
cls._chip_id_dict[models["chip_ids"]["virtual"]] = curr_gpu_model
|
||||
|
||||
# detect gpu arch to compute partition relationships
|
||||
cls._populate_gpu_arch_to_compute_partition_dict()
|
||||
|
||||
@classmethod
|
||||
def _populate_gpu_arch_to_compute_partition_dict(cls):
|
||||
"""
|
||||
This creates a mapping of gpu_arch -> compute_partition for architectures
|
||||
where there's only one model (and therefore one partition configuration).
|
||||
"""
|
||||
for gpu_arch, gpu_models in cls._gpu_model_dict.items():
|
||||
if len(gpu_models) == 1:
|
||||
single_model = gpu_models[0]
|
||||
compute_partition = cls._num_xcds_dict.get(single_model)
|
||||
|
||||
if compute_partition is not None:
|
||||
cls._gpu_arch_to_compute_partition_dict[gpu_arch] = compute_partition
|
||||
console_debug(
|
||||
"[populate_single_arch_partition_dict] Single model arch found: "
|
||||
"%s -> %s (partition: %s)"
|
||||
% (gpu_arch, single_model, compute_partition)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_gpu_series_dict(cls):
|
||||
if not cls._gpu_series_dict:
|
||||
@@ -146,6 +179,19 @@ class MIGPUSpecs:
|
||||
console_warning(f"No matching gpu series found for gpu arch: {gpu_arch_}")
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_perfmon_config(cls, gpu_arch_):
|
||||
# Check that gpu_model_dict is populated first
|
||||
if not cls._perfmon_config:
|
||||
console_error(
|
||||
"gpu_model_dict not yet populated. Did you run parse_mi_gpu_spec()?"
|
||||
)
|
||||
return None
|
||||
|
||||
gpu_arch_lower = gpu_arch_.lower()
|
||||
|
||||
return cls._perfmon_config.get(gpu_arch_lower, None)
|
||||
|
||||
@classmethod
|
||||
def get_gpu_model(cls, gpu_arch_, chip_id_):
|
||||
# Check that gpu_model_dict is populated first
|
||||
@@ -180,38 +226,99 @@ class MIGPUSpecs:
|
||||
return gpu_model.upper()
|
||||
|
||||
@classmethod
|
||||
def get_num_xcds(cls, gpu_model_, compute_partition_):
|
||||
# Only gpu in and above mi 300 series have more than one XCDs
|
||||
if gpu_model_.lower() in ("mi50", "mi60", "mi100", "mi210", "mi250", "mi250x"):
|
||||
def set_default_gpu_settings(self, gpu_arch, gpu_model, compute_partition):
|
||||
"""
|
||||
Set default GPU settings when model is unknown or cannot be determined.
|
||||
NOTE: This is a fallback to gfx942 settings - consider making this architecture-specific.
|
||||
"""
|
||||
DEFAULT_COMPUTE_PARTITION = "SPX"
|
||||
DEFAULT_NUM_XCD = 8
|
||||
console_warning(
|
||||
f"Unable to determine xcd count from:\n\t"
|
||||
f"GPU arch: '{gpu_arch}', model: '{gpu_model}', partition: '{compute_partition}'"
|
||||
)
|
||||
console_warning(
|
||||
f"Applying default gfx942 settings:\n"
|
||||
f"\t- Compute partition: {DEFAULT_COMPUTE_PARTITION}\n"
|
||||
f"\t- Number of XCDs: {DEFAULT_NUM_XCD}"
|
||||
)
|
||||
|
||||
return DEFAULT_NUM_XCD
|
||||
|
||||
@classmethod
|
||||
def get_num_xcds(
|
||||
cls, gpu_arch: str = None, gpu_model: str = None, compute_partition: str = None
|
||||
):
|
||||
"""
|
||||
Retrieve the number of XCDs based on GPU architecture, model, and compute partition.
|
||||
|
||||
Priority order:
|
||||
1. Legacy GPU check (returns 1 XCD for older architectures/models)
|
||||
2. Architecture-based lookup (preferred)
|
||||
3. Model + partition-based lookup (fallback)
|
||||
4. Default settings (last resort)
|
||||
"""
|
||||
# Constants for legacy GPUs that don't support compute partitions
|
||||
LEGACY_ARCHS = {"gfx906", "gfx908", "gfx90a"}
|
||||
LEGACY_MODELS = {"mi50", "mi60", "mi100", "mi210", "mi250", "mi250x"}
|
||||
|
||||
# Normalize inputs to lowercase for consistent comparison
|
||||
gpu_arch_norm = gpu_arch.lower().strip() if gpu_arch else ""
|
||||
gpu_model_norm = gpu_model.lower().strip() if gpu_model else ""
|
||||
partition_norm = compute_partition.lower().strip() if compute_partition else ""
|
||||
|
||||
# 1. Return 1 XCDs for archs/models not supporting compute partition
|
||||
# NOTE: gpu arch is enough to verify this logic, gpu model is used as a backup.
|
||||
if gpu_arch_norm in LEGACY_ARCHS or gpu_model_norm in LEGACY_MODELS:
|
||||
return 1
|
||||
|
||||
if not cls._num_xcds_dict:
|
||||
console_error(
|
||||
"mi300_num_xcds_dict not yet populated, did you run parse_mi_gpu_spec()?"
|
||||
)
|
||||
return None
|
||||
# 2. Try architecture-based lookup first (preferred method)
|
||||
if gpu_arch_norm and hasattr(cls, "_gpu_arch_to_compute_partition_dict"):
|
||||
arch_dict = cls._gpu_arch_to_compute_partition_dict
|
||||
if gpu_arch_norm in arch_dict:
|
||||
num_xcds = arch_dict[gpu_arch_norm]
|
||||
if num_xcds is not None:
|
||||
return num_xcds
|
||||
else:
|
||||
console_warning(
|
||||
f"No compute partition data found for architecture '{gpu_arch.upper()}'"
|
||||
)
|
||||
|
||||
gpu_model_lower = gpu_model_.lower()
|
||||
partition_lower = compute_partition_.lower()
|
||||
# 3. Fall back to model + partition-based lookup
|
||||
if gpu_model_norm:
|
||||
# Validate XCD dictionary is populated
|
||||
if not hasattr(cls, "_num_xcds_dict") or not cls._num_xcds_dict:
|
||||
console_error(
|
||||
"mi300_num_xcds_dict not populated. Did you run parse_mi_gpu_spec()?"
|
||||
)
|
||||
elif gpu_model_norm not in cls._num_xcds_dict:
|
||||
console_warning(
|
||||
f"Unknown gpu model provided for num xcds lookup: {gpu_model}."
|
||||
)
|
||||
else:
|
||||
model_dict = cls._num_xcds_dict[gpu_model_norm]
|
||||
|
||||
if gpu_model_lower not in cls._num_xcds_dict:
|
||||
return None
|
||||
if not partition_norm:
|
||||
console_warning(
|
||||
"No compute partition provided for model-based lookup"
|
||||
)
|
||||
elif partition_norm not in model_dict:
|
||||
console_warning(
|
||||
f"Unknown compute partition '{compute_partition}' for model '{gpu_model}'"
|
||||
)
|
||||
else:
|
||||
num_xcds = model_dict[partition_norm]
|
||||
if num_xcds is not None:
|
||||
return num_xcds
|
||||
else:
|
||||
console_warning(
|
||||
f"Unknown compute partition found for {compute_partition} / {gpu_model}"
|
||||
)
|
||||
else:
|
||||
console_warning("No gpu model provided for num xcds lookup.")
|
||||
|
||||
model_dict = cls._num_xcds_dict[gpu_model_lower]
|
||||
if partition_lower not in model_dict:
|
||||
console_log(f"Unknown compute partition: {compute_partition_}")
|
||||
return None
|
||||
|
||||
num_xcds = model_dict[partition_lower]
|
||||
if not num_xcds:
|
||||
console_warning(
|
||||
"Unknown compute partition found for %s / %s",
|
||||
compute_partition_,
|
||||
gpu_model_,
|
||||
)
|
||||
return None
|
||||
|
||||
return num_xcds
|
||||
# 4. Last resort: use default settings
|
||||
return cls.set_default_gpu_settings(gpu_arch, gpu_model, compute_partition)
|
||||
|
||||
@classmethod
|
||||
def get_chip_id_dict(cls):
|
||||
@@ -220,7 +327,17 @@ class MIGPUSpecs:
|
||||
else:
|
||||
console_error()
|
||||
|
||||
@classmethod
|
||||
def get_num_xcds_dict(cls):
|
||||
if cls._num_xcds_dict:
|
||||
return cls._num_xcds_dict
|
||||
else:
|
||||
console_error()
|
||||
|
||||
@classmethod
|
||||
def get_gpu_arch_to_compute_partition_dict(cls):
|
||||
return cls._gpu_arch_to_compute_partition_dict
|
||||
|
||||
|
||||
# pre-initialize the instance when module loads
|
||||
|
||||
mi_gpu_specs = MIGPUSpecs()
|
||||
|
||||
+223
-16
@@ -9,8 +9,11 @@
|
||||
# MI GPUs
|
||||
# |-- series: the specific MI series; mi50, mi100, mi200, mi300
|
||||
# |-- architecture: currently, only mi300 gpus hold different architectures
|
||||
# |-- perfmon_config
|
||||
# |-- gpu model
|
||||
# |-- chip_ids: chip id is specific to the environment the gpu is being used on
|
||||
# | -- physical
|
||||
# | -- virtual
|
||||
# |-- partition_mode
|
||||
# | -- compute partition mode
|
||||
# | -- memory partition mode
|
||||
@@ -21,6 +24,17 @@ mi_gpu_spec:
|
||||
- gpu_series: mi50
|
||||
gpu_archs:
|
||||
- gpu_arch: gfx906
|
||||
perfmon_config:
|
||||
SQ: 8
|
||||
TA: 2
|
||||
TD: 2
|
||||
TCP: 4
|
||||
TCC: 4
|
||||
CPC: 2
|
||||
CPF: 2
|
||||
SPI: 2
|
||||
GRBM: 2
|
||||
GDS: 4
|
||||
models:
|
||||
- gpu_model: mi50
|
||||
- gpu_model: mi60
|
||||
@@ -28,6 +42,17 @@ mi_gpu_spec:
|
||||
- gpu_series: mi100
|
||||
gpu_archs:
|
||||
- gpu_arch: gfx908
|
||||
perfmon_config:
|
||||
SQ: 8
|
||||
TA: 2
|
||||
TD: 2
|
||||
TCP: 4
|
||||
TCC: 4
|
||||
CPC: 2
|
||||
CPF: 2
|
||||
SPI: 2
|
||||
GRBM: 2
|
||||
GDS: 4
|
||||
models:
|
||||
- gpu_model: mi100
|
||||
chip_ids:
|
||||
@@ -36,6 +61,17 @@ mi_gpu_spec:
|
||||
- gpu_series: mi200
|
||||
gpu_archs:
|
||||
- gpu_arch: gfx90a
|
||||
perfmon_config:
|
||||
SQ: 8
|
||||
TA: 2
|
||||
TD: 2
|
||||
TCP: 4
|
||||
TCC: 4
|
||||
CPC: 2
|
||||
CPF: 2
|
||||
SPI: 2
|
||||
GRBM: 2
|
||||
GDS: 4
|
||||
models:
|
||||
- gpu_model: mi210
|
||||
chip_ids:
|
||||
@@ -46,12 +82,21 @@ mi_gpu_spec:
|
||||
- gpu_model: mi250x
|
||||
chip_ids:
|
||||
physical: 29704
|
||||
- gpu_model: mi250
|
||||
- gpu_model: mi250x
|
||||
|
||||
- gpu_series: mi300
|
||||
gpu_archs:
|
||||
- gpu_arch: gfx940
|
||||
perfmon_config:
|
||||
SQ: 8
|
||||
TA: 2
|
||||
TD: 2
|
||||
TCP: 4
|
||||
TCC: 4
|
||||
CPC: 2
|
||||
CPF: 2
|
||||
SPI: 2
|
||||
GRBM: 2
|
||||
GDS: 4
|
||||
models:
|
||||
- gpu_model: mi300a_a0
|
||||
partition_mode:
|
||||
@@ -59,11 +104,29 @@ mi_gpu_spec:
|
||||
num_xcds:
|
||||
spx: 6
|
||||
tpx: 2
|
||||
cpx: 1
|
||||
memory_partition_mode:
|
||||
nps4: [tpx]
|
||||
nps1: [spx, tpx]
|
||||
nps4:
|
||||
tpx: 3
|
||||
nps1:
|
||||
spx: 1
|
||||
tpx: 3
|
||||
chip_ids:
|
||||
physical: null
|
||||
virtual: null
|
||||
|
||||
- gpu_arch: gfx941
|
||||
perfmon_config:
|
||||
SQ: 8
|
||||
TA: 2
|
||||
TD: 2
|
||||
TCP: 4
|
||||
TCC: 4
|
||||
CPC: 2
|
||||
CPF: 2
|
||||
SPI: 2
|
||||
GRBM: 2
|
||||
GDS: 4
|
||||
models:
|
||||
- gpu_model: mi300x_a0
|
||||
partition_mode:
|
||||
@@ -74,10 +137,31 @@ mi_gpu_spec:
|
||||
qpx: 2
|
||||
cpx: 1
|
||||
memory_partition_mode:
|
||||
nps4: [qpx, cpx]
|
||||
nps1: [spx, qpx, cpx]
|
||||
nps4:
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
nps2:
|
||||
dpx: 2
|
||||
nps1:
|
||||
spx: 1
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
chip_ids:
|
||||
physical: null
|
||||
virtual: null
|
||||
|
||||
- gpu_arch: gfx942
|
||||
perfmon_config:
|
||||
SQ: 8
|
||||
TA: 2
|
||||
TD: 2
|
||||
TCP: 4
|
||||
TCC: 4
|
||||
CPC: 2
|
||||
CPF: 2
|
||||
SPI: 2
|
||||
GRBM: 2
|
||||
GDS: 4
|
||||
models:
|
||||
- gpu_model: mi300a_a1
|
||||
partition_mode:
|
||||
@@ -85,9 +169,14 @@ mi_gpu_spec:
|
||||
num_xcds:
|
||||
spx: 6
|
||||
tpx: 2
|
||||
cpx: 1
|
||||
memory_partition_mode:
|
||||
nps4: [tpx]
|
||||
nps1: [spx, tpx]
|
||||
nps4:
|
||||
tpx: 3
|
||||
nps1:
|
||||
spx: 1
|
||||
tpx: 3
|
||||
cpx: 8
|
||||
chip_ids:
|
||||
physical: 29856
|
||||
virtual: 29876
|
||||
@@ -101,12 +190,41 @@ mi_gpu_spec:
|
||||
qpx: 2
|
||||
cpx: 1
|
||||
memory_partition_mode:
|
||||
nps4: [qpx, cpx]
|
||||
nps1: [spx, qpx, cpx]
|
||||
nps4:
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
nps2:
|
||||
dpx: 2
|
||||
nps1:
|
||||
spx: 1
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
chip_ids:
|
||||
physical: 29857
|
||||
virtual: 29877
|
||||
|
||||
- gpu_model: mi300xhf
|
||||
partition_mode:
|
||||
compute_partition_mode:
|
||||
num_xcds:
|
||||
spx: 8
|
||||
dpx: 4
|
||||
qpx: 2
|
||||
cpx: 1
|
||||
memory_partition_mode:
|
||||
nps4:
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
nps2:
|
||||
dpx: 2
|
||||
nps1:
|
||||
spx: 1
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
chip_ids:
|
||||
physical: 29865
|
||||
virtual: 29885
|
||||
|
||||
- gpu_model: mi308x
|
||||
partition_mode:
|
||||
compute_partition_mode:
|
||||
@@ -115,12 +233,34 @@ mi_gpu_spec:
|
||||
dpx: 2
|
||||
cpx: 1
|
||||
memory_partition_mode:
|
||||
nps4: [cpx]
|
||||
nps1: [spx, dpx, cpx]
|
||||
nps4:
|
||||
cpx: 8
|
||||
nps1:
|
||||
spx: 1
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
chip_ids:
|
||||
physical: 29858
|
||||
virtual: 29878
|
||||
|
||||
- gpu_model: mi308xhf
|
||||
partition_mode:
|
||||
compute_partition_mode:
|
||||
num_xcds:
|
||||
spx: 4
|
||||
dpx: 2
|
||||
cpx: 1
|
||||
memory_partition_mode:
|
||||
nps4:
|
||||
cpx: 8
|
||||
nps1:
|
||||
spx: 1
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
chip_ids:
|
||||
physical: 29864
|
||||
virtual: 29884
|
||||
|
||||
- gpu_model: mi325x
|
||||
partition_mode:
|
||||
compute_partition_mode:
|
||||
@@ -130,8 +270,15 @@ mi_gpu_spec:
|
||||
qpx: 2
|
||||
cpx: 1
|
||||
memory_partition_mode:
|
||||
nps4: [qpx, cpx]
|
||||
nps1: [spx, qpx, cpx]
|
||||
nps4:
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
nps2:
|
||||
dpx: 2
|
||||
nps1:
|
||||
spx: 1
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
chip_ids:
|
||||
physical: 29861
|
||||
virtual: 29881
|
||||
@@ -139,6 +286,18 @@ mi_gpu_spec:
|
||||
- gpu_series: mi350
|
||||
gpu_archs:
|
||||
- gpu_arch: gfx950
|
||||
perfmon_config:
|
||||
SQ: 8
|
||||
TA: 2
|
||||
TD: 2
|
||||
TCP: 4
|
||||
TCC: 4
|
||||
CPC: 2
|
||||
CPF: 2
|
||||
SPI: 2
|
||||
GRBM: 2
|
||||
GDS: 4
|
||||
TCC_channels: 16
|
||||
models:
|
||||
- gpu_model: mi350
|
||||
partition_mode:
|
||||
@@ -149,7 +308,55 @@ mi_gpu_spec:
|
||||
qpx: 2
|
||||
cpx: 1
|
||||
memory_partition_mode:
|
||||
nps1: [spx, dpx, qpx, cpx]
|
||||
nps4: [qpx, cpx]
|
||||
nps4:
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
nps2:
|
||||
dpx: 2
|
||||
nps1:
|
||||
spx: 1
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
chip_ids:
|
||||
physical: 30112
|
||||
virutal: 30128
|
||||
- gpu_model: mi355
|
||||
partition_mode:
|
||||
compute_partition_mode:
|
||||
num_xcds:
|
||||
spx: 8
|
||||
dpx: 4
|
||||
qpx: 2
|
||||
cpx: 1
|
||||
memory_partition_mode:
|
||||
nps4:
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
nps2:
|
||||
dpx: 2
|
||||
nps1:
|
||||
spx: 1
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
chip_ids:
|
||||
physical: 30115
|
||||
virtual: 30131
|
||||
- gpu_model: mi358
|
||||
partition_mode:
|
||||
compute_partition_mode:
|
||||
num_xcds:
|
||||
spx: 8
|
||||
dpx: 4
|
||||
qpx: 2
|
||||
cpx: 1
|
||||
memory_partition_mode:
|
||||
nps4:
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
nps1:
|
||||
spx: 1
|
||||
qpx: 4
|
||||
cpx: 8
|
||||
chip_ids:
|
||||
physical: 30114
|
||||
virtual: 30130
|
||||
+42
-16
@@ -38,13 +38,7 @@ from pathlib import Path as path
|
||||
import pandas as pd
|
||||
|
||||
import config
|
||||
from utils.logger import (
|
||||
console_debug,
|
||||
console_error,
|
||||
console_log,
|
||||
console_warning,
|
||||
demarcate,
|
||||
)
|
||||
from utils.logger import console_debug, console_error, console_log, console_warning
|
||||
from utils.mi_gpu_spec import mi_gpu_specs
|
||||
from utils.tty import get_table_string
|
||||
from utils.utils import get_version
|
||||
@@ -158,15 +152,40 @@ def generate_machine_specs(args, sysinfo: dict = None):
|
||||
rocm_version = get_rocm_ver().strip()
|
||||
# FIXME: use device
|
||||
|
||||
amd_smi_output = run(["amd-smi", "static"], exit_on_error=True)
|
||||
vbios_pattern = r"PART_NUMBER:\s*(\S+)"
|
||||
compute_partition_pattern = r"COMPUTE_PARTITION:\s*(\S+)"
|
||||
accelerator_partition_pattern = r"ACCELERATOR_PARTITION:\s*(\S+)"
|
||||
memory_partition_pattern = r"MEMORY_PARTITION:\s*(\S+)"
|
||||
|
||||
vbios = search(vbios_pattern, run(["amd-smi", "static"], exit_on_error=True))
|
||||
compute_partition = search(compute_partition_pattern, run(["amd-smi", "static"]))
|
||||
rocm_smi_compute_partition_output = run(
|
||||
["rocm-smi", "--showcomputepartition"], exit_on_error=True
|
||||
)
|
||||
rocm_smi_compute_partition_pattern = r"Compute Partition:\s*(\S+)"
|
||||
|
||||
vbios = search(vbios_pattern, amd_smi_output)
|
||||
# 1. get compute partition from amd-smi
|
||||
compute_partition = search(compute_partition_pattern, amd_smi_output)
|
||||
console_debug(f"amd-smi compute partition: {compute_partition}")
|
||||
# 2. get compute partition from rocm-smi
|
||||
if compute_partition is None:
|
||||
compute_partition = "NA"
|
||||
memory_partition = search(memory_partition_pattern, run(["amd-smi", "static"]))
|
||||
compute_partition = search(
|
||||
rocm_smi_compute_partition_pattern, rocm_smi_compute_partition_output
|
||||
)
|
||||
console_debug(f"rocm-smi compute partition: {compute_partition}")
|
||||
# 3. get compute partition from amd-smi using keyword accelerator
|
||||
if compute_partition is None:
|
||||
compute_partition = search(accelerator_partition_pattern, amd_smi_output)
|
||||
console_debug(f"amd-smi accelerator partition: {compute_partition}")
|
||||
# 4. apply default compute partition
|
||||
if compute_partition is None:
|
||||
console_warning(
|
||||
f"Can not detect compute/accelerator partition from amd-smi and rocm-smi."
|
||||
)
|
||||
console_warning(f"Applying default compute partition: SPX")
|
||||
compute_partition = "SPX"
|
||||
|
||||
memory_partition = search(memory_partition_pattern, amd_smi_output)
|
||||
if memory_partition is None:
|
||||
memory_partition = "NA"
|
||||
|
||||
@@ -216,8 +235,12 @@ def generate_machine_specs(args, sysinfo: dict = None):
|
||||
soc_class = getattr(soc_module, specs.gpu_arch + "_soc")
|
||||
soc_obj = soc_class(args, specs)
|
||||
# Update arch specific specs
|
||||
specs.gpu_model = mi_gpu_specs.get_gpu_model(specs.gpu_arch, specs.gpu_chip_id)
|
||||
specs.num_xcd = mi_gpu_specs.get_num_xcds(
|
||||
specs.gpu_arch, specs.gpu_model, specs.compute_partition
|
||||
)
|
||||
specs.total_l2_chan: str = total_l2_banks(
|
||||
specs.gpu_model, int(specs._l2_banks), specs.compute_partition
|
||||
specs.gpu_arch, specs.gpu_model, specs._l2_banks, specs.compute_partition
|
||||
)
|
||||
specs.num_hbm_channels: str = str(specs.get_hbm_channels())
|
||||
return specs
|
||||
@@ -673,10 +696,13 @@ def total_sqc(archname, numCUs, numSEs):
|
||||
return int(sq_per_se) * int(numSEs)
|
||||
|
||||
|
||||
def total_l2_banks(archname, L2Banks, compute_partition):
|
||||
xcds = mi_gpu_specs.get_num_xcds(archname, compute_partition)
|
||||
totalL2Banks = L2Banks * xcds
|
||||
return totalL2Banks
|
||||
def total_l2_banks(gpu_arch, gpu_model, L2Banks, compute_partition):
|
||||
xcd_count = mi_gpu_specs.get_num_xcds(gpu_arch, gpu_model, compute_partition)
|
||||
|
||||
# TODO: MachineSpecs and OmniSoC mspec should converge...
|
||||
if L2Banks is not None and xcd_count is not None:
|
||||
return int(L2Banks) * int(xcd_count)
|
||||
return None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
+3
-1
@@ -756,7 +756,9 @@ def run_prof(
|
||||
if new_env and not using_v3() and not using_v1():
|
||||
# flatten tcc for applicable mi300 input
|
||||
f = path(workload_dir + "/out/pmc_1/results_" + fbase + ".csv")
|
||||
xcds = mi_gpu_specs.get_num_xcds(mspec.gpu_model, mspec.compute_partition)
|
||||
xcds = mi_gpu_specs.get_num_xcds(
|
||||
mspec.gpu_arch, mspec.gpu_model, mspec.compute_partition
|
||||
)
|
||||
df = flatten_tcc_info_across_xcds(f, xcds, int(mspec._l2_banks))
|
||||
df.to_csv(f, index=False)
|
||||
|
||||
|
||||
+31
-6
@@ -22,6 +22,10 @@ GFX942_CHIP_IDS_TO_NUM_XCDS = {
|
||||
"29878": {"spx": 4, "dpx": 2, "cpx": 1},
|
||||
"29861": {"spx": 8, "dpx": 4, "qpx": 2, "cpx": 1},
|
||||
"29881": {"spx": 8, "dpx": 4, "qpx": 2, "cpx": 1},
|
||||
"29864": {"spx": 4, "dpx": 2, "cpx": 1},
|
||||
"29884": {"spx": 4, "dpx": 2, "cpx": 1},
|
||||
"29865": {"spx": 8, "dpx": 4, "qpx": 2, "cpx": 1},
|
||||
"29885": {"spx": 8, "dpx": 4, "qpx": 2, "cpx": 1},
|
||||
}
|
||||
|
||||
# helper to strip ANSI color codes if your app uses them
|
||||
@@ -91,17 +95,37 @@ def get_num_xcds():
|
||||
if str(chip_id) in GFX942_CHIP_IDS_TO_NUM_XCDS.keys():
|
||||
num_xcds = GFX942_CHIP_IDS_TO_NUM_XCDS[str(chip_id)]
|
||||
|
||||
if num_xcds is None:
|
||||
return
|
||||
|
||||
return num_xcds
|
||||
|
||||
|
||||
def get_gpu_arch():
|
||||
|
||||
rocminfo = str(
|
||||
# decode with utf-8 to account for rocm-smi changes in latest rocm
|
||||
subprocess.run(
|
||||
["rocminfo"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
).stdout.decode("utf-8")
|
||||
)
|
||||
rocminfo = rocminfo.split("\n")
|
||||
|
||||
soc_regex = re.compile(r"^\s*Name\s*:\s+ ([a-zA-Z0-9]+)\s*$", re.MULTILINE)
|
||||
devices = list(filter(soc_regex.match, rocminfo))
|
||||
gpu_arch = devices[0].split()[1]
|
||||
return gpu_arch
|
||||
|
||||
|
||||
@pytest.mark.num_xcds_spec_class
|
||||
def test_num_xcds_spec_class(monkeypatch):
|
||||
num_xcds = get_num_xcds()
|
||||
|
||||
# 1. Check if gfx942 soc
|
||||
if not num_xcds:
|
||||
gpu_arch = get_gpu_arch()
|
||||
if gpu_arch is None or gpu_arch.lower() != "gfx942":
|
||||
pytest.skip("Skipping num xcds test for non-gfx942 socs.")
|
||||
|
||||
num_xcds = get_num_xcds()
|
||||
|
||||
# 2. load machine specs
|
||||
machine_spec = generate_machine_specs(None)
|
||||
|
||||
@@ -114,12 +138,13 @@ def test_num_xcds_spec_class(monkeypatch):
|
||||
|
||||
@pytest.mark.num_xcds_cli_output
|
||||
def test_num_xcds_cli_output():
|
||||
num_xcds = get_num_xcds()
|
||||
|
||||
# 1. Check if gfx942 soc
|
||||
if not num_xcds:
|
||||
gpu_arch = get_gpu_arch()
|
||||
if gpu_arch is None or gpu_arch.lower() != "gfx942":
|
||||
pytest.skip("Skipping num xcds test for non-gfx942 socs.")
|
||||
|
||||
num_xcds = get_num_xcds()
|
||||
|
||||
# 2. Run rocprof-compute -s and grab rocprof-compute num_xcd
|
||||
proc = subprocess.run(
|
||||
["rocprof-compute", "-s"],
|
||||
|
||||
Reference in New Issue
Block a user