Reorganize the specs module to reduce duplicate code
Signed-off-by: colramos-amd <colramos@amd.com>
[ROCm/rocprofiler-compute commit: 3b1b8d7b5b]
このコミットが含まれているのは:
@@ -54,11 +54,7 @@ class DatabaseConnector:
|
||||
self.client: MongoClient = None
|
||||
|
||||
@demarcate
|
||||
def prep_import(self, profile_and_export=False):
|
||||
if profile_and_export:
|
||||
self.connection_info["workload"] = os.path.join(
|
||||
self.connection_info["workload"], self.args.target
|
||||
)
|
||||
def prep_import(self):
|
||||
|
||||
# Extract SoC and workload name from sysinfo.csv
|
||||
sys_info = os.path.join(self.connection_info["workload"], "sysinfo.csv")
|
||||
|
||||
@@ -663,7 +663,7 @@ def build_metric_value_string(dfs, dfs_type, normal_unit):
|
||||
# print(tabulate(df, headers='keys', tablefmt='fancy_grid'))
|
||||
|
||||
|
||||
def eval_metric(dfs, dfs_type, sys_info, soc_spec, raw_pmc_df, debug):
|
||||
def eval_metric(dfs, dfs_type, sys_info, raw_pmc_df, debug):
|
||||
"""
|
||||
Execute the expr string for each metric in the df.
|
||||
"""
|
||||
@@ -679,25 +679,18 @@ def eval_metric(dfs, dfs_type, sys_info, soc_spec, raw_pmc_df, debug):
|
||||
print("WARNING: Dectected GRBM_GUI_ACTIVE == 0\nHaulting execution.")
|
||||
sys.exit(1)
|
||||
|
||||
# NB:
|
||||
# Following with Omniperf 0.2.0, we are using HW spec from sys_info instead.
|
||||
# The soc_spec is not in using right now, but can be used to do verification
|
||||
# against sys_info, forced theoretical evaluation, or supporting tool-chains
|
||||
# broken.
|
||||
ammolite__numSE = sys_info.numSE
|
||||
ammolite__numSE = sys_info.SE
|
||||
ammolite__numPipes = sys_info.numPipes
|
||||
ammolite__numCU = sys_info.numCU
|
||||
ammolite__numSIMD = sys_info.numSIMD
|
||||
ammolite__numWavesPerCU = sys_info.maxWavesPerCU # todo: check do we still need it
|
||||
ammolite__numCU = sys_info.CU
|
||||
ammolite__numSIMD = sys_info.SIMD
|
||||
ammolite__numWavesPerCU = sys_info.max_waves_per_cu # todo: check do we still need it
|
||||
ammolite__numSQC = sys_info.numSQC
|
||||
ammolite__L2Banks = sys_info.L2Banks
|
||||
ammolite__LDSBanks = soc_spec[
|
||||
"LDSBanks"
|
||||
] # todo: eventually switch this over to sys_info. its a new spec so trying not to break compatibility
|
||||
ammolite__LDSBanks = sys_info.LDSBanks
|
||||
ammolite__freq = sys_info.cur_sclk # todo: check do we still need it
|
||||
ammolite__mclk = sys_info.cur_mclk
|
||||
ammolite__sclk = sys_info.sclk
|
||||
ammolite__maxWavesPerCU = sys_info.maxWavesPerCU
|
||||
ammolite__sclk = sys_info.max_sclk
|
||||
ammolite__maxWavesPerCU = sys_info.max_waves_per_cu
|
||||
ammolite__hbmBW = sys_info.hbmBW
|
||||
ammolite__totalL2Banks = calc_builtin_var("$totalL2Banks", sys_info)
|
||||
|
||||
@@ -947,7 +940,6 @@ def load_table_data(workload, dir, is_gui, debug, verbose, skipKernelTop=False):
|
||||
workload.dfs,
|
||||
workload.dfs_type,
|
||||
workload.sys_info.iloc[0],
|
||||
workload.soc_spec,
|
||||
apply_filters(workload, dir, is_gui, debug),
|
||||
debug,
|
||||
)
|
||||
|
||||
@@ -474,7 +474,7 @@ def calc_ai(sort_type, ret_df):
|
||||
|
||||
|
||||
def constuct_roof(roofline_parameters, dtype):
|
||||
benchmark_results = os.path.join(roofline_parameters["path_to_dir"], "roofline.csv")
|
||||
benchmark_results = os.path.join(roofline_parameters["workload_dir"], "roofline.csv")
|
||||
# -----------------------------------------------------
|
||||
# Initialize roofline data dictionary from roofline.csv
|
||||
# -----------------------------------------------------
|
||||
|
||||
@@ -59,7 +59,6 @@ class ArchConfig:
|
||||
@dataclass
|
||||
class Workload:
|
||||
sys_info: pd.DataFrame = None
|
||||
soc_spec: dict = None # TODO: might move it to ArchConfig
|
||||
raw_pmc: pd.DataFrame = None
|
||||
dfs: Dict[int, pd.DataFrame] = field(default_factory=dict)
|
||||
dfs_type: Dict[int, str] = field(default_factory=dict)
|
||||
|
||||
@@ -31,46 +31,158 @@ import socket
|
||||
import subprocess
|
||||
import importlib
|
||||
import logging
|
||||
import pandas as pd
|
||||
|
||||
from datetime import datetime
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path as path
|
||||
from textwrap import dedent
|
||||
from utils.utils import error, get_hbm_stack_num
|
||||
|
||||
VERSION_LOC = [
|
||||
"version",
|
||||
"version-dev",
|
||||
"version-hip-libraries",
|
||||
"version-hiprt",
|
||||
"version-hiprt-devel",
|
||||
"version-hip-sdk",
|
||||
"version-libs",
|
||||
"version-utils",
|
||||
]
|
||||
|
||||
@dataclass
|
||||
class MachineSpecs:
|
||||
hostname: str
|
||||
CPU: str
|
||||
sbios: str
|
||||
kernel_version: str
|
||||
ram: str
|
||||
distro: str
|
||||
rocm_version: str
|
||||
GPU: str
|
||||
arch: str
|
||||
vbios: str
|
||||
L1: str
|
||||
L2: str
|
||||
CU: str
|
||||
SIMD: str
|
||||
SE: str
|
||||
wave_size: str
|
||||
workgroup_max_size: str
|
||||
max_sclk: str
|
||||
max_mclk: str
|
||||
cur_sclk: str
|
||||
cur_mclk: str
|
||||
max_waves_per_cu: str
|
||||
L2Banks: str
|
||||
totalL2Banks: str
|
||||
LDSBanks: str
|
||||
numSQC: str
|
||||
numPipes: str
|
||||
hbmBW: str
|
||||
compute_partition: str
|
||||
memory_partition: str
|
||||
def __init__(self, args, sysinfo=None):
|
||||
if not sysinfo is None:
|
||||
self.arch = sysinfo.iloc[0]["arch"]
|
||||
return
|
||||
# read timestamp info
|
||||
now = datetime.now()
|
||||
local_now = now.astimezone()
|
||||
local_tz = local_now.tzinfo
|
||||
local_tzname = local_tz.tzname(local_now)
|
||||
self.timestamp = now.strftime("%c") + " (" + local_tzname + ")"
|
||||
|
||||
# read rocminfo
|
||||
rocminfo_full = run(["rocminfo"])
|
||||
self._rocminfo = rocminfo_full.split("\n")
|
||||
|
||||
##########################################
|
||||
## A. Machine Specs
|
||||
##########################################
|
||||
cpuinfo = path("/proc/cpuinfo").read_text()
|
||||
meminfo = path("/proc/meminfo").read_text()
|
||||
version = path("/proc/version").read_text()
|
||||
os_release = path("/etc/os-release").read_text()
|
||||
|
||||
self.hostname: str = socket.gethostname()
|
||||
self.CPU: str = search(r"^model name\s*: (.*?)$", cpuinfo)
|
||||
self.sbios: str = (
|
||||
path("/sys/class/dmi/id/bios_vendor").read_text().strip()
|
||||
+ path("/sys/class/dmi/id/bios_version").read_text().strip()
|
||||
)
|
||||
self.kernel_version: str = search(r"version (\S*)", version)
|
||||
self.ram: str = search(r"MemTotal:\s*(\S*)", meminfo)
|
||||
self.distro: str = search(r'PRETTY_NAME="(.*?)"', os_release)
|
||||
if self.distro is None:
|
||||
self.distro = ""
|
||||
self.rocm_version: str = get_rocm_ver().strip()
|
||||
#FIXME: use device
|
||||
self.vbios: str = search(
|
||||
r"VBIOS version: (.*?)$", run(["rocm-smi", "-v"], exit_on_error=True)
|
||||
)
|
||||
self.compute_partition: str = search(
|
||||
r"Compute Partition:\s*(\w+)", run(["rocm-smi", "--showcomputepartition"])
|
||||
)
|
||||
if self.compute_partition is None:
|
||||
self.compute_partition = "NA"
|
||||
self.memory_partition: str = search(
|
||||
r"Memory Partition:\s*(\w+)", run(["rocm-smi", "--showmemorypartition"])
|
||||
)
|
||||
if self.memory_partition is None:
|
||||
self.memory_partition = "NA"
|
||||
|
||||
##########################################
|
||||
## B. SoC Specs
|
||||
##########################################
|
||||
self.arch: str = self.detect_arch()[0]
|
||||
self.L1: str = None
|
||||
self.L2: str = None
|
||||
self.CU: str = None
|
||||
self.SIMD: str = None
|
||||
self.SE: str = None
|
||||
self.wave_size: str = None
|
||||
self.workgroup_max_size: str = None
|
||||
self.max_sclk: str = None
|
||||
self.max_mclk: str = None
|
||||
self.cur_sclk: str = None
|
||||
self.cur_mclk: str = None
|
||||
self.max_waves_per_cu: str = None
|
||||
self.GPU: str = None
|
||||
self.L2Banks: str = None
|
||||
self.LDSBanks: str = None
|
||||
self.numSQC: str = None
|
||||
self.numPipes: str = None
|
||||
self.totalL2Banks: str = None
|
||||
self.hbmBW: str = None
|
||||
# Load above SoC specs via module import
|
||||
try:
|
||||
soc_module = importlib.import_module('omniperf_soc.soc_'+ self.arch)
|
||||
except ModuleNotFoundError as e:
|
||||
error("Arch %s marked as supported, but couldn't find class implementation %s." % (self.arch, e))
|
||||
soc_class = getattr(soc_module, self.arch+'_soc')
|
||||
self._rocminfo = self._rocminfo[self.detect_arch()[1] + 1 :] # update rocminfo for target section
|
||||
soc_obj = soc_class(args, self)
|
||||
# Update arch specific specs
|
||||
self.totalL2Banks: str = total_l2_banks(
|
||||
self.GPU, int(self.L2Banks), self.memory_partition
|
||||
)
|
||||
self.hbmBW: str = str(int(self.max_mclk) / 1000 * 32 * self.get_hbm_channels())
|
||||
|
||||
|
||||
def detect_arch(self):
|
||||
from omniperf_base import SUPPORTED_ARCHS
|
||||
|
||||
for idx1, linetext in enumerate(self._rocminfo):
|
||||
gpu_arch = search(r"^\s*Name\s*:\s+ ([a-zA-Z0-9]+)\s*$", linetext)
|
||||
if gpu_arch in SUPPORTED_ARCHS.keys():
|
||||
break
|
||||
if str(gpu_arch) in SUPPORTED_ARCHS.keys():
|
||||
gpu_arch = str(gpu_arch)
|
||||
break
|
||||
if not gpu_arch in SUPPORTED_ARCHS.keys():
|
||||
error("[profiling] Cannot find a supported arch in rocminfo")
|
||||
else:
|
||||
return (gpu_arch, idx1)
|
||||
|
||||
def get_hbm_channels(self):
|
||||
hbmchannels = int(self.totalL2Banks)
|
||||
if (
|
||||
self.GPU.lower() == "mi300a_a0"
|
||||
or self.GPU.lower() == "mi300a_a1"
|
||||
) and self.memory_partition.lower() == "nps1":
|
||||
# we have an extra 32 channels for the CCD
|
||||
hbmchannels += 32
|
||||
return hbmchannels
|
||||
|
||||
def get_class_members(self):
|
||||
all_populated = True
|
||||
data = {}
|
||||
# dataclass uses an OrderedDict for member variables, ensuring order consistency
|
||||
for attr_name in self.__dict__.keys():
|
||||
if not attr_name.startswith("_"):
|
||||
attr_value = getattr(self, attr_name)
|
||||
if attr_value is None:
|
||||
#TODO: use proper logging function when that's merged
|
||||
logging.warning(f"WARNING: Incomplete class definition for {self.arch}. Expecting populated {attr_name} but detected None.")
|
||||
all_populated = False
|
||||
data[attr_name] = attr_value
|
||||
|
||||
if not all_populated:
|
||||
error("Missing specs fields for %s" % self.arch)
|
||||
return pd.DataFrame(data, index=[0])
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return dedent(
|
||||
f"""\
|
||||
@@ -110,145 +222,27 @@ class MachineSpecs:
|
||||
)
|
||||
|
||||
|
||||
def gpuinfo():
|
||||
from omniperf_base import SUPPORTED_ARCHS
|
||||
|
||||
gpu_info = {
|
||||
"gpu_name": None,
|
||||
"gpu_arch": None,
|
||||
"L1": None,
|
||||
"L2": None,
|
||||
"max_sclk": None,
|
||||
"max_mclk": None,
|
||||
"num_CU": None,
|
||||
"num_SIMD": None,
|
||||
"numPipes": None,
|
||||
"num_SE": None,
|
||||
"wave_size": None,
|
||||
"grp_size": None,
|
||||
"max_waves_per_cu": None,
|
||||
"L2Banks": None,
|
||||
"LDSBanks": None,
|
||||
"numSQC": None,
|
||||
"compute_partition": None,
|
||||
"memory_partition": None,
|
||||
}
|
||||
|
||||
# Fixme: find better way to differentiate cards, GPU vs APU, etc.
|
||||
rocminfo_full = run(["rocminfo"])
|
||||
rocminfo = rocminfo_full.split("\n")
|
||||
|
||||
for idx1, linetext in enumerate(rocminfo):
|
||||
gpu_arch = search(r"^\s*Name\s*:\s+ ([a-zA-Z0-9]+)\s*$", linetext)
|
||||
if gpu_arch in SUPPORTED_ARCHS.keys():
|
||||
break
|
||||
if str(gpu_arch) in SUPPORTED_ARCHS.keys():
|
||||
gpu_arch = str(gpu_arch)
|
||||
break
|
||||
if not gpu_arch in SUPPORTED_ARCHS.keys():
|
||||
return gpu_info
|
||||
|
||||
gpu_info["L1"], gpu_info["L1"] = "", ""
|
||||
for idx2, linetext in enumerate(rocminfo[idx1 + 1 :]):
|
||||
key = search(r"^\s*L1:\s+ ([a-zA-Z0-9]+)\s*", linetext)
|
||||
if key != None:
|
||||
gpu_info["L1"] = key
|
||||
continue
|
||||
|
||||
key = search(r"^\s*L2:\s+ ([a-zA-Z0-9]+)\s*", linetext)
|
||||
if key != None:
|
||||
gpu_info["L2"] = key
|
||||
continue
|
||||
|
||||
key = search(r"^\s*Max Clock Freq\. \(MHz\):\s+([0-9]+)", linetext)
|
||||
if key != None:
|
||||
gpu_info["max_sclk"] = key
|
||||
continue
|
||||
|
||||
key = search(r"^\s*Compute Unit:\s+ ([a-zA-Z0-9]+)\s*", linetext)
|
||||
if key != None:
|
||||
gpu_info["num_CU"] = key
|
||||
continue
|
||||
|
||||
key = search(r"^\s*SIMDs per CU:\s+ ([a-zA-Z0-9]+)\s*", linetext)
|
||||
if key != None:
|
||||
gpu_info["num_SIMD"] = key
|
||||
continue
|
||||
|
||||
key = search(r"^\s*Shader Engines:\s+ ([a-zA-Z0-9]+)\s*", linetext)
|
||||
if key != None:
|
||||
gpu_info["num_SE"] = key
|
||||
continue
|
||||
|
||||
key = search(r"^\s*Wavefront Size:\s+ ([a-zA-Z0-9]+)\s*", linetext)
|
||||
if key != None:
|
||||
gpu_info["wave_size"] = key
|
||||
continue
|
||||
|
||||
key = search(r"^\s*Workgroup Max Size:\s+ ([a-zA-Z0-9]+)\s*", linetext)
|
||||
if key != None:
|
||||
gpu_info["grp_size"] = key
|
||||
continue
|
||||
|
||||
key = search(r"^\s*Max Waves Per CU:\s+ ([a-zA-Z0-9]+)\s*", linetext)
|
||||
if key != None:
|
||||
gpu_info["max_waves_per_cu"] = key
|
||||
break
|
||||
|
||||
try:
|
||||
soc_module = importlib.import_module("omniperf_soc.soc_" + gpu_arch)
|
||||
except ModuleNotFoundError as e:
|
||||
error(
|
||||
"Arch %s marked as supported, but couldn't find class implementation %s."
|
||||
% (gpu_arch, e)
|
||||
)
|
||||
|
||||
# load arch specific info
|
||||
try:
|
||||
gpu_name = list(SUPPORTED_ARCHS[gpu_arch].keys())[0].upper()
|
||||
gpu_info["L2Banks"] = str(soc_module.SOC_PARAM["L2Banks"])
|
||||
gpu_info["numSQC"] = str(soc_module.SOC_PARAM["numSQC"])
|
||||
gpu_info["LDSBanks"] = str(soc_module.SOC_PARAM["LDSBanks"])
|
||||
gpu_info["numPipes"] = str(soc_module.SOC_PARAM["numPipes"])
|
||||
except KeyError as e:
|
||||
error(
|
||||
"Incomplete class definition for %s. Expected a field for %s in SOC_PARAM."
|
||||
% (gpu_arch, e)
|
||||
)
|
||||
|
||||
# we get the max mclk from rocm-smi --showmclkrange
|
||||
rocm_smi_mclk = run(["rocm-smi", "--showmclkrange"], exit_on_error=True)
|
||||
gpu_info["max_mclk"] = search(r"(\d+)Mhz\s*$", rocm_smi_mclk)
|
||||
# check that we got the mclk from smi
|
||||
if gpu_info["max_mclk"] is None:
|
||||
if gpu_name == "MI100":
|
||||
# hardcoded due to rocm-smi limitation
|
||||
gpu_info["max_mclk"] = str(1200)
|
||||
else:
|
||||
error(
|
||||
"Could not obtain maximum mclk from rocm-smi for GPU: {}".format(gpu_info)
|
||||
def get_rocm_ver():
|
||||
rocm_found = False
|
||||
for itr in VERSION_LOC:
|
||||
_path = os.path.join(os.getenv("ROCM_PATH", "/opt/rocm"), ".info", itr)
|
||||
if os.path.exists(_path):
|
||||
rocm_ver = path(_path).read_text()
|
||||
rocm_found = True
|
||||
break
|
||||
if not rocm_found:
|
||||
# check if ROCM_VER is supplied externally
|
||||
ROCM_VER_USER = os.getenv("ROCM_VER")
|
||||
if ROCM_VER_USER is not None:
|
||||
logging.info(
|
||||
"Overriding missing ROCm version detection with ROCM_VER = %s"
|
||||
% ROCM_VER_USER
|
||||
)
|
||||
|
||||
# specify gpu name for gfx942 hardware
|
||||
if gpu_name == "MI300":
|
||||
gpu_name = list(SUPPORTED_ARCHS[gpu_arch].values())[0][0]
|
||||
if (gpu_info["gpu_arch"] == "gfx942") and ("MI300A" in rocminfo_full):
|
||||
gpu_name = "MI300A_A1"
|
||||
if (gpu_arch == "gfx942") and ("MI300A" not in rocminfo_full):
|
||||
gpu_name = "MI300X_A1"
|
||||
|
||||
gpu_info["gpu_name"] = gpu_name
|
||||
gpu_info["gpu_arch"] = gpu_arch
|
||||
gpu_info["compute_partition"] = ""
|
||||
gpu_info["memory_partition"] = ""
|
||||
|
||||
# verify all fields are filled
|
||||
for key, value in gpu_info.items():
|
||||
if value is None:
|
||||
logging.info("Warning: %s is missing from gpu_info dictionary." % key)
|
||||
|
||||
return gpu_info
|
||||
|
||||
rocm_ver = ROCM_VER_USER
|
||||
else:
|
||||
_rocm_path = os.getenv("ROCM_PATH", "/opt/rocm")
|
||||
error("Unable to detect a complete local ROCm installation.\nThe expected %s/.info/ versioning directory is missing. Please ensure you have valid ROCm installation." % _rocm_path)
|
||||
return rocm_ver
|
||||
|
||||
def run(cmd, exit_on_error=False):
|
||||
p = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
@@ -275,143 +269,20 @@ def total_l2_banks(archname, L2Banks, memory_partition):
|
||||
# Fixme: support all supported partitioning mode
|
||||
# Fixme: "name" is a bad name!
|
||||
totalL2Banks = L2Banks
|
||||
if archname.lower() == "mi300a_a0" or archname.lower() == "mi300a_a1":
|
||||
totalL2Banks = L2Banks * get_hbm_stack_num(archname, memory_partition)
|
||||
elif archname.lower() == "mi300x_a0" or archname.lower() == "mi300x_a1":
|
||||
totalL2Banks = L2Banks * get_hbm_stack_num(archname, memory_partition)
|
||||
return totalL2Banks
|
||||
|
||||
|
||||
def get_machine_specs(devicenum):
|
||||
cpuinfo = path("/proc/cpuinfo").read_text()
|
||||
meminfo = path("/proc/meminfo").read_text()
|
||||
version = path("/proc/version").read_text()
|
||||
os_release = path("/etc/os-release").read_text()
|
||||
|
||||
version_loc = [
|
||||
"version",
|
||||
"version-dev",
|
||||
"version-hip-libraries",
|
||||
"version-hiprt",
|
||||
"version-hiprt-devel",
|
||||
"version-hip-sdk",
|
||||
"version-libs",
|
||||
"version-utils",
|
||||
]
|
||||
|
||||
rocmFound = False
|
||||
for itr in version_loc:
|
||||
_path = os.path.join(os.getenv("ROCM_PATH", "/opt/rocm"), ".info", itr)
|
||||
if os.path.exists(_path):
|
||||
rocm_ver = path(_path).read_text()
|
||||
rocmFound = True
|
||||
break
|
||||
|
||||
if not rocmFound:
|
||||
# check if ROCM_VER is supplied externally
|
||||
ROCM_VER_USER = os.getenv("ROCM_VER")
|
||||
if ROCM_VER_USER is not None:
|
||||
print(
|
||||
"Overriding missing ROCm version detection with ROCM_VER = %s"
|
||||
% ROCM_VER_USER
|
||||
)
|
||||
rocm_ver = ROCM_VER_USER
|
||||
else:
|
||||
_rocm_path = os.getenv("ROCM_PATH", "/opt/rocm")
|
||||
print("Error: Unable to detect a complete local ROCm installation.")
|
||||
print(
|
||||
"\nThe expected %s/.info/ versioning directory is missing. Please"
|
||||
% _rocm_path
|
||||
)
|
||||
print("ensure you have valid ROCm installation.")
|
||||
sys.exit(1)
|
||||
|
||||
gpu_info = gpuinfo()
|
||||
|
||||
rocm_smi = run(["rocm-smi"], exit_on_error=True)
|
||||
|
||||
device = rf"^\s*{devicenum}(.*)"
|
||||
|
||||
hostname = socket.gethostname()
|
||||
sbios = (
|
||||
path("/sys/class/dmi/id/bios_vendor").read_text().strip()
|
||||
+ path("/sys/class/dmi/id/bios_version").read_text().strip()
|
||||
)
|
||||
CPU = search(r"^model name\s*: (.*?)$", cpuinfo)
|
||||
kernel_version = search(r"version (\S*)", version)
|
||||
ram = search(r"MemTotal:\s*(\S*)", meminfo)
|
||||
distro = search(r'PRETTY_NAME="(.*?)"', os_release)
|
||||
if distro is None:
|
||||
distro = ""
|
||||
|
||||
rocm_version = rocm_ver.strip()
|
||||
|
||||
# these are just max's now, because the parsing was broken and this was inconsistent
|
||||
# with how we use the clocks elsewhere (all max, all the time)
|
||||
cur_sclk = gpu_info["max_sclk"]
|
||||
cur_mclk = gpu_info["max_mclk"]
|
||||
|
||||
# FIXME with device
|
||||
vbios = search(r"VBIOS version: (.*?)$", run(["rocm-smi", "-v"], exit_on_error=True))
|
||||
|
||||
compute_partition = search(
|
||||
r"Compute Partition:\s*(\w+)", run(["rocm-smi", "--showcomputepartition"])
|
||||
)
|
||||
if compute_partition == None:
|
||||
compute_partition = "NA"
|
||||
|
||||
memory_partition = search(
|
||||
r"Memory Partition:\s*(\w+)", run(["rocm-smi", "--showmemorypartition"])
|
||||
)
|
||||
if memory_partition == None:
|
||||
memory_partition = "NA"
|
||||
|
||||
totalL2Banks = total_l2_banks(
|
||||
gpu_info["gpu_name"], int(gpu_info["L2Banks"]), memory_partition
|
||||
)
|
||||
hbmchannels = totalL2Banks
|
||||
if (
|
||||
gpu_info["gpu_name"].lower() == "mi300a_a0"
|
||||
or gpu_info["gpu_name"].lower() == "mi300a_a1"
|
||||
) and memory_partition.lower() == "nps1":
|
||||
# we have an extra 32 channels for the CCD
|
||||
hbmchannels += 32
|
||||
hbmBW = str(int(gpu_info["max_mclk"]) / 1000 * 32 * hbmchannels)
|
||||
totalL2Banks = str(totalL2Banks)
|
||||
|
||||
return MachineSpecs(
|
||||
hostname,
|
||||
CPU,
|
||||
sbios,
|
||||
kernel_version,
|
||||
ram,
|
||||
distro,
|
||||
rocm_version,
|
||||
gpu_info["gpu_name"],
|
||||
gpu_info["gpu_arch"],
|
||||
vbios,
|
||||
gpu_info["L1"],
|
||||
gpu_info["L2"],
|
||||
gpu_info["num_CU"],
|
||||
gpu_info["num_SIMD"],
|
||||
gpu_info["num_SE"],
|
||||
gpu_info["wave_size"],
|
||||
gpu_info["grp_size"],
|
||||
gpu_info["max_sclk"],
|
||||
gpu_info["max_mclk"],
|
||||
cur_sclk,
|
||||
cur_mclk,
|
||||
gpu_info["max_waves_per_cu"],
|
||||
gpu_info["L2Banks"],
|
||||
totalL2Banks,
|
||||
gpu_info["LDSBanks"],
|
||||
gpu_info["numSQC"],
|
||||
gpu_info["numPipes"],
|
||||
hbmBW,
|
||||
compute_partition,
|
||||
memory_partition,
|
||||
)
|
||||
archname.lower() == "mi300a_a0"
|
||||
or archname.lower() == "mi300a_a1"
|
||||
):
|
||||
totalL2Banks = L2Banks * get_hbm_stack_num(
|
||||
archname, memory_partition)
|
||||
elif (
|
||||
archname.lower() == "mi300x_a0"
|
||||
or archname.lower() == "mi300x_a1"
|
||||
):
|
||||
totalL2Banks = L2Banks * get_hbm_stack_num(
|
||||
archname, memory_partition)
|
||||
return str(totalL2Banks)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(get_machine_specs(0))
|
||||
print(MachineSpecs())
|
||||
|
||||
@@ -198,12 +198,10 @@ def capture_subprocess_output(subprocess_args, new_env=None):
|
||||
|
||||
return (success, output)
|
||||
|
||||
|
||||
def run_prof(fname, profiler_options, target, workload_dir):
|
||||
def run_prof(fname, profiler_options, workload_dir, mspec):
|
||||
|
||||
fbase = os.path.splitext(os.path.basename(fname))[0]
|
||||
m_specs = specs.get_machine_specs(0)
|
||||
|
||||
|
||||
logging.debug("pmc file: %s" % str(os.path.basename(fname)))
|
||||
|
||||
# standard rocprof options
|
||||
@@ -212,12 +210,7 @@ def run_prof(fname, profiler_options, target, workload_dir):
|
||||
|
||||
# set required env var for mi300
|
||||
new_env = None
|
||||
if (
|
||||
target.lower() == "mi300x_a0"
|
||||
or target.lower() == "mi300x_a1"
|
||||
or target.lower() == "mi300a_a0"
|
||||
or target.lower() == "mi300a_a1"
|
||||
) and (
|
||||
if (mspec.GPU.lower() == "mi300x_a0" or mspec.GPU.lower() == "mi300x_a1" or mspec.GPU.lower() == "mi300a_a0" or mspec.GPU.lower() == "mi300a_a1") and (
|
||||
os.path.basename(fname) == "pmc_perf_13.txt"
|
||||
or os.path.basename(fname) == "pmc_perf_14.txt"
|
||||
or os.path.basename(fname) == "pmc_perf_15.txt"
|
||||
@@ -239,8 +232,10 @@ def run_prof(fname, profiler_options, target, workload_dir):
|
||||
if new_env:
|
||||
# flatten tcc for applicable mi300 input
|
||||
f = path(workload_dir + "/out/pmc_1/results_" + fbase + ".csv")
|
||||
hbm_stack_num = get_hbm_stack_num(target, m_specs.memory_partition)
|
||||
df = flatten_tcc_info_across_hbm_stacks(f, hbm_stack_num, int(m_specs.L2Banks))
|
||||
hbm_stack_num = get_hbm_stack_num(mspec.GPU, mspec.memory_partition)
|
||||
df = flatten_tcc_info_across_hbm_stacks(
|
||||
f, hbm_stack_num, int(mspec.L2Banks)
|
||||
)
|
||||
df.to_csv(f, index=False)
|
||||
|
||||
if os.path.exists(workload_dir + "/out"):
|
||||
@@ -300,88 +295,27 @@ def replace_timestamps(workload_dir):
|
||||
)
|
||||
logging.warning(warning + "\n")
|
||||
|
||||
|
||||
def gen_sysinfo(workload_name, workload_dir, ip_blocks, app_cmd, skip_roof, roof_only):
|
||||
# Record system information
|
||||
mspec = specs.get_machine_specs(0)
|
||||
sysinfo = open(workload_dir + "/" + "sysinfo.csv", "w")
|
||||
|
||||
# write header
|
||||
header = "workload_name,"
|
||||
header += "command,"
|
||||
header += "host_name,host_cpu,sbios,host_distro,host_kernel,host_rocmver,date,"
|
||||
header += "gpu_soc,vbios,numSE,numCU,numSIMD,waveSize,maxWavesPerCU,maxWorkgroupSize,"
|
||||
header += "L1,L2,sclk,mclk,cur_sclk,cur_mclk,L2Banks,totalL2Banks,LDSBanks,name,numSQC,numPipes,"
|
||||
header += "hbmBW,compute_partition,memory_partition,"
|
||||
header += "ip_blocks\n"
|
||||
sysinfo.write(header)
|
||||
|
||||
# timestamp
|
||||
now = datetime.now()
|
||||
local_now = now.astimezone()
|
||||
local_tz = local_now.tzinfo
|
||||
local_tzname = local_tz.tzname(local_now)
|
||||
timestamp = now.strftime("%c") + " (" + local_tzname + ")"
|
||||
# host info
|
||||
param = [workload_name]
|
||||
param += ['"' + app_cmd + '"']
|
||||
param += [
|
||||
mspec.hostname,
|
||||
mspec.CPU,
|
||||
'"' + mspec.sbios + '"',
|
||||
mspec.distro,
|
||||
mspec.kernel_version,
|
||||
mspec.rocm_version,
|
||||
timestamp,
|
||||
]
|
||||
|
||||
# GPU info
|
||||
param += [
|
||||
mspec.arch,
|
||||
mspec.vbios,
|
||||
mspec.SE,
|
||||
mspec.CU,
|
||||
mspec.SIMD,
|
||||
mspec.wave_size,
|
||||
mspec.max_waves_per_cu,
|
||||
mspec.workgroup_max_size,
|
||||
]
|
||||
param += [
|
||||
mspec.L1,
|
||||
mspec.L2,
|
||||
mspec.max_sclk,
|
||||
mspec.max_mclk,
|
||||
mspec.cur_sclk,
|
||||
mspec.cur_mclk,
|
||||
mspec.L2Banks,
|
||||
mspec.totalL2Banks,
|
||||
mspec.LDSBanks,
|
||||
mspec.GPU,
|
||||
mspec.numSQC,
|
||||
mspec.numPipes,
|
||||
mspec.hbmBW,
|
||||
mspec.compute_partition,
|
||||
mspec.memory_partition,
|
||||
]
|
||||
|
||||
def gen_sysinfo(workload_name, workload_dir, ip_blocks, app_cmd, skip_roof, roof_only, mspec):
|
||||
df = mspec.get_class_members()
|
||||
|
||||
# Append workload information to machine specs
|
||||
df.insert(0, 'command', app_cmd)
|
||||
df.insert(0,'workload_name', workload_name)
|
||||
|
||||
blocks = []
|
||||
if mspec.arch == "gfx90a" and (not skip_roof):
|
||||
blocks.append("roofline")
|
||||
|
||||
# ip block info
|
||||
if ip_blocks == None:
|
||||
t = ["SQ", "LDS", "SQC", "TA", "TD", "TCP", "TCC", "SPI", "CPC", "CPF"]
|
||||
blocks += t
|
||||
else:
|
||||
blocks += ip_blocks
|
||||
param.append("|".join(blocks))
|
||||
if mspec.arch == "gfx90a" and (not skip_roof):
|
||||
blocks.append("roofline")
|
||||
df['ip_blocks'] = "|".join(blocks)
|
||||
|
||||
sysinfo.write(",".join(param))
|
||||
sysinfo.close()
|
||||
# Save csv
|
||||
df.to_csv(workload_dir + "/" + "sysinfo.csv", index=False)
|
||||
|
||||
|
||||
def detect_roofline():
|
||||
mspec = specs.get_machine_specs(0)
|
||||
def detect_roofline(mspec):
|
||||
rocm_ver = mspec.rocm_version[:1]
|
||||
|
||||
os_release = path("/etc/os-release").read_text()
|
||||
@@ -446,13 +380,13 @@ def run_rocscope(args, fname):
|
||||
logging.error(result.stderr.decode("ascii"))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def mibench(args):
|
||||
"""Run roofline microbenchmark to generate peak BW and FLOP measurements."""
|
||||
def mibench(args, mspec):
|
||||
"""Run roofline microbenchmark to generate peak BW and FLOP measurements.
|
||||
"""
|
||||
logging.info("[roofline] No roofline data found. Generating...")
|
||||
distro_map = {"platform:el8": "rhel8", "15.3": "sle15sp3", "20.04": "ubuntu20_04"}
|
||||
|
||||
target_binary = detect_roofline()
|
||||
target_binary = detect_roofline(mspec)
|
||||
if target_binary["rocm_ver"] == "override":
|
||||
path_to_binary = target_binary["path"]
|
||||
else:
|
||||
@@ -462,7 +396,7 @@ def mibench(args):
|
||||
+ "-"
|
||||
+ distro_map[target_binary["distro"]]
|
||||
+ "-"
|
||||
+ args.target.lower()
|
||||
+ mspec.GPU.lower()
|
||||
+ "-rocm"
|
||||
+ target_binary["rocm_ver"]
|
||||
)
|
||||
|
||||
新しいイシューから参照
ユーザーをブロックする