Re-implementing HBM stack / XCD info for incoming product sku
Co-authored-by: Nicholas Curtis <nicholas.curtis@amd.com> Signed-off-by: coleramos425 <colramos@amd.com>
This commit is contained in:
+25
-53
@@ -37,7 +37,7 @@ from math import ceil
|
||||
from dataclasses import dataclass, field, fields
|
||||
from pathlib import Path as path
|
||||
from utils.utils import (
|
||||
get_hbm_stack_num,
|
||||
total_xcds,
|
||||
get_version,
|
||||
console_error,
|
||||
console_warning,
|
||||
@@ -184,7 +184,7 @@ def generate_machine_specs(args, sysinfo: dict = None):
|
||||
soc_obj = soc_class(args, specs)
|
||||
# Update arch specific specs
|
||||
specs.total_l2_chan: str = total_l2_banks(
|
||||
specs.gpu_model, int(specs._l2_banks), specs.memory_partition
|
||||
specs.gpu_model, int(specs._l2_banks), specs.compute_partition
|
||||
)
|
||||
specs.hbm_bw: str = str(int(specs.max_mclk) / 1000 * 32 * specs.get_hbm_channels())
|
||||
return specs
|
||||
@@ -480,7 +480,7 @@ class MachineSpecs:
|
||||
"doc": "The peak theoretical HBM bandwidth for the accelerators/GPUs in the system. On systems with\n"
|
||||
"configurable partitioning, (e.g., MI300) this is the peak theoretical HBM bandwidth for a partition.",
|
||||
"name": "HBM BW",
|
||||
"unit": "MB/s",
|
||||
"unit": "GB/s",
|
||||
},
|
||||
)
|
||||
num_xcd: str = field(
|
||||
@@ -489,17 +489,26 @@ class MachineSpecs:
|
||||
"doc": "The total number of accelerator complex dies in a compute partition on the accelerators/GPUs in the\n"
|
||||
"system. For accelerators without partitioning (i.e., pre-MI300), this is considered to be one.",
|
||||
"name": "Num XCDs",
|
||||
"unit": "MB/s",
|
||||
"unit": "XCDs",
|
||||
},
|
||||
)
|
||||
|
||||
def get_hbm_channels(self):
|
||||
hbmchannels = int(self.total_l2_chan)
|
||||
if (
|
||||
self.gpu_model.lower() == "mi300a_a0" or self.gpu_model.lower() == "mi300a_a1"
|
||||
) and self.memory_partition.lower() == "nps1":
|
||||
# we have an extra 32 channels for the CCD
|
||||
hbmchannels += 32
|
||||
# check MI300 has a valid compute partition
|
||||
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":
|
||||
hbmchannels /= 2
|
||||
elif self.memory_partition.lower() == "nps4":
|
||||
hbmchannels /= 4
|
||||
elif self.memory_partition.lower() == "nps8":
|
||||
hbmchannels /= 8
|
||||
return int(hbmchannels)
|
||||
else:
|
||||
hbmchannels = int(self.total_l2_chan)
|
||||
return hbmchannels
|
||||
|
||||
def get_class_members(self):
|
||||
@@ -618,17 +627,6 @@ def search(pattern, string):
|
||||
return None
|
||||
|
||||
|
||||
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 str(totalL2Banks)
|
||||
|
||||
|
||||
def total_sqc(archname, numCUs, numSEs):
|
||||
cu_per_se = float(numCUs) / float(numSEs)
|
||||
sq_per_se = cu_per_se / 2
|
||||
@@ -638,38 +636,12 @@ def total_sqc(archname, numCUs, numSEs):
|
||||
return int(sq_per_se) * int(numSEs)
|
||||
|
||||
|
||||
def total_xcds(archname, compute_partition):
|
||||
# check MI300 has a valid compute partition
|
||||
mi300a_archs = ["mi300a_a0", "mi300a_a1"]
|
||||
mi300x_archs = ["mi300x_a0", "mi300x_a1"]
|
||||
if archname.lower() in mi300a_archs + mi300x_archs and compute_partition == "NA":
|
||||
console_error("Invalid compute partition found for {}".format(archname))
|
||||
if archname.lower() not in mi300a_archs + mi300x_archs:
|
||||
return 1
|
||||
# from the whitepaper
|
||||
# https://www.amd.com/content/dam/amd/en/documents/instinct-tech-docs/white-papers/amd-cdna-3-white-paper.pdf
|
||||
if compute_partition.lower() == "spx":
|
||||
if archname.lower() in mi300a_archs:
|
||||
return 6
|
||||
if archname.lower() in mi300x_archs:
|
||||
return 8
|
||||
if compute_partition.lower() == "tpx":
|
||||
if archname.lower() in mi300a_archs:
|
||||
return 2
|
||||
if compute_partition.lower() == "dpx":
|
||||
if archname.lower() in mi300x_archs:
|
||||
return 4
|
||||
if compute_partition.lower() == "qpx":
|
||||
if archname.lower() in mi300x_archs:
|
||||
return 2
|
||||
if compute_partition.lower() == "cpx":
|
||||
if archname.lower() in mi300x_archs:
|
||||
return 2
|
||||
console_error(
|
||||
"Unknown compute partition / arch found for {} / {}".format(
|
||||
compute_partition, archname
|
||||
)
|
||||
)
|
||||
def total_l2_banks(archname, L2Banks, compute_partition):
|
||||
# Fixme: support all supported partitioning mode
|
||||
# Fixme: "name" is a bad name!
|
||||
totalL2Banks = L2Banks
|
||||
xcds = total_xcds(archname, compute_partition)
|
||||
return L2Banks * xcds
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
+45
-35
@@ -285,8 +285,8 @@ def run_prof(fname, profiler_options, workload_dir, mspec, loglevel):
|
||||
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(mspec.gpu_model, mspec.memory_partition)
|
||||
df = flatten_tcc_info_across_hbm_stacks(f, hbm_stack_num, int(mspec._l2_banks))
|
||||
xcds = total_xcds(mspec.gpu_model, mspec.compute_partition)
|
||||
df = flatten_tcc_info_across_xcds(f, xcds, int(mspec._l2_banks))
|
||||
df.to_csv(f, index=False)
|
||||
|
||||
if os.path.exists(workload_dir + "/out"):
|
||||
@@ -492,9 +492,9 @@ def mibench(args, mspec):
|
||||
)
|
||||
|
||||
|
||||
def flatten_tcc_info_across_hbm_stacks(file, stack_num, tcc_channel_per_stack):
|
||||
def flatten_tcc_info_across_xcds(file, xcds, tcc_channel_per_xcd):
|
||||
"""
|
||||
Flatten TCC per channel counters across all HBM stacks in used.
|
||||
Flatten TCC per channel counters across all XCDs in partition.
|
||||
NB: This func highly depends on the default behavior of rocprofv2 on MI300,
|
||||
which might be broken anytime in the future!
|
||||
"""
|
||||
@@ -513,22 +513,22 @@ def flatten_tcc_info_across_hbm_stacks(file, stack_num, tcc_channel_per_stack):
|
||||
|
||||
cols = non_tcc_cols_orig
|
||||
tcc_cols_in_group = {}
|
||||
for i in range(0, stack_num):
|
||||
for i in range(0, xcds):
|
||||
tcc_cols_in_group[i] = []
|
||||
|
||||
for col in tcc_cols_orig:
|
||||
for i in range(0, stack_num):
|
||||
for i in range(0, xcds):
|
||||
# filter the channel index only
|
||||
p = re.compile(r"\[(\d+)\]")
|
||||
# pick up the 1st element only
|
||||
r = (
|
||||
lambda match: "["
|
||||
+ str(int(match.group(1)) + i * tcc_channel_per_stack)
|
||||
+ str(int(match.group(1)) + i * tcc_channel_per_xcd)
|
||||
+ "]"
|
||||
)
|
||||
tcc_cols_in_group[i].append(re.sub(pattern=p, repl=r, string=col))
|
||||
|
||||
for i in range(0, stack_num):
|
||||
for i in range(0, xcds):
|
||||
# print(tcc_cols_in_group[i])
|
||||
cols += tcc_cols_in_group[i]
|
||||
# print(cols)
|
||||
@@ -537,7 +537,7 @@ def flatten_tcc_info_across_hbm_stacks(file, stack_num, tcc_channel_per_stack):
|
||||
### Rearrange data with extended column names
|
||||
|
||||
# print(len(df_orig.index))
|
||||
for idx in range(0, len(df_orig.index), stack_num):
|
||||
for idx in range(0, len(df_orig.index), xcds):
|
||||
# assume the front none TCC columns are the same for all XCCs
|
||||
df_non_tcc = df_orig.iloc[idx].filter(regex=r"^(?!.*TCC).*$")
|
||||
# display(df_non_tcc)
|
||||
@@ -545,7 +545,7 @@ def flatten_tcc_info_across_hbm_stacks(file, stack_num, tcc_channel_per_stack):
|
||||
|
||||
# extract all tcc from one dispatch
|
||||
# NB: assuming default contiguous order might not be safe!
|
||||
df_tcc_all = df_orig.iloc[idx : (idx + stack_num)].filter(regex="TCC")
|
||||
df_tcc_all = df_orig.iloc[idx : (idx + xcds)].filter(regex="TCC")
|
||||
# display(df_tcc_all)
|
||||
|
||||
for idx, row in df_tcc_all.iterrows():
|
||||
@@ -557,36 +557,46 @@ def flatten_tcc_info_across_hbm_stacks(file, stack_num, tcc_channel_per_stack):
|
||||
return df
|
||||
|
||||
|
||||
def get_hbm_stack_num(gpu_name, memory_partition):
|
||||
"""
|
||||
Get total HBM stack numbers based on memory partition for MI300.
|
||||
"""
|
||||
|
||||
# TODO:
|
||||
# - better err log
|
||||
if gpu_name.lower() == "mi300a_a0" or gpu_name.lower() == "mi300a_a1":
|
||||
if memory_partition.lower() == "nps1":
|
||||
def total_xcds(archname, compute_partition):
|
||||
# check MI300 has a valid compute partition
|
||||
mi300a_archs = ["mi300a_a0", "mi300a_a1"]
|
||||
mi300x_archs = ["mi300x_a0", "mi300x_a1"]
|
||||
mi308x_archs = ["mi308x"]
|
||||
if archname.lower() in mi300a_archs + mi300x_archs + mi308x_archs and compute_partition == "NA":
|
||||
console_error("Invalid compute partition found for {}".format(archname))
|
||||
if archname.lower() not in mi300a_archs + mi300x_archs + mi308x_archs:
|
||||
return 1
|
||||
# from the whitepaper
|
||||
# https://www.amd.com/content/dam/amd/en/documents/instinct-tech-docs/white-papers/amd-cdna-3-white-paper.pdf
|
||||
if compute_partition.lower() == "spx":
|
||||
if archname.lower() in mi300a_archs:
|
||||
return 6
|
||||
elif memory_partition.lower() == "nps4":
|
||||
return 2
|
||||
elif memory_partition.lower() == "nps8":
|
||||
return 1
|
||||
else:
|
||||
console_error("Invalid MI300A memory partition mode!")
|
||||
elif gpu_name.lower() == "mi300x_a0" or gpu_name.lower() == "mi300x_a1":
|
||||
if memory_partition.lower() == "nps1":
|
||||
if archname.lower() in mi300x_archs:
|
||||
return 8
|
||||
elif memory_partition.lower() == "nps2":
|
||||
if archname.lower() in mi308x_archs:
|
||||
return 4
|
||||
elif memory_partition.lower() == "nps4":
|
||||
if compute_partition.lower() == "tpx":
|
||||
if archname.lower() in mi300a_archs:
|
||||
return 2
|
||||
elif memory_partition.lower() == "nps8":
|
||||
if compute_partition.lower() == "dpx":
|
||||
if archname.lower() in mi300x_archs:
|
||||
return 4
|
||||
if archname.lower() in mi308x_archs:
|
||||
return 2
|
||||
if compute_partition.lower() == "qpx":
|
||||
if archname.lower() in mi300x_archs:
|
||||
return 2
|
||||
if compute_partition.lower() == "cpx":
|
||||
if archname.lower() in mi300x_archs:
|
||||
return 2
|
||||
if archname.lower() in mi308x_archs:
|
||||
return 1
|
||||
else:
|
||||
console_error("Invalid MI300X memory partition mode!")
|
||||
else:
|
||||
# Fixme: add proper numbers for other archs
|
||||
return -1
|
||||
# TODO implement other archs here as needed
|
||||
console_error(
|
||||
"Unknown compute partition / arch found for {} / {}".format(
|
||||
compute_partition, archname
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def get_submodules(package_name):
|
||||
|
||||
Reference in New Issue
Block a user