Reorganize the specs module to reduce duplicate code

Signed-off-by: colramos-amd <colramos@amd.com>


[ROCm/rocprofiler-compute commit: 3b1b8d7b5b]
このコミットが含まれているのは:
colramos-amd
2024-02-20 13:34:56 -06:00
committed by Cole Ramos
コミット 5352eafde4
20個のファイルの変更495行の追加781行の削除
+1 -5
ファイルの表示
@@ -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")
+8 -16
ファイルの表示
@@ -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,
)
+1 -1
ファイルの表示
@@ -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
# -----------------------------------------------------
-1
ファイルの表示
@@ -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)
+175 -304
ファイルの表示
@@ -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())
+25 -91
ファイルの表示
@@ -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"]
)