enriched the description of each config in stdout

- the config description is now displayed in the form of a table. This allows to add the useful indicators:
   - amount of cache per core
   - ram per core
   - population of dimms

work related to [https://bugzilla.ipr.univ-rennes.fr/show_bug.cgi?id=4171]
This commit is contained in:
Guillaume Raffy 2025-10-23 15:56:48 +02:00
parent a99a69f7db
commit 40ec1807fd
2 changed files with 98 additions and 5 deletions

View File

@ -108,7 +108,7 @@ class Cpu(Item):
def __init__(self, proc_id: CpuId):
super().__init__(proc_id)
cpuTable = numpy.genfromtxt('catalogs/cpu_table.tsv', dtype=("|U32", float, int, float, float, float, int, int), names=True, delimiter='\t')
cpuTable = numpy.genfromtxt('catalogs/cpu_table.tsv', dtype=("|U32", float, int, float, float, float, int, float), names=True, delimiter='\t')
for cpu_id, clock, num_cores, max_cpus, tdp, cpumark, l3_cache_mb in zip(cpuTable['id'], cpuTable['clock'], cpuTable['num_cores'], cpuTable['max_cpus'], cpuTable['tdp'], cpuTable['cpumark_1_cpu'], cpuTable['l3_cache_mb']):
# print(cpu_id)
if cpu_id == proc_id:
@ -122,6 +122,17 @@ class Cpu(Item):
self.cpumark = cpumark
self.l3_cache_mb = l3_cache_mb
def as_dict(self) -> Dict:
return {
'uid': self.uid,
'clock': self.clock,
'num_cores': self.num_cores,
'max_cpus': self.max_cpus,
'tdp': self.tdp,
'cpumark': self.cpumark,
'l3_cache_mb': self.l3_cache_mb
}
@property
def architecture(self) -> CpuArchitecture:
proc_id = self.uid
@ -437,6 +448,28 @@ class Config():
def __repr__(self) -> str:
return f'Config(cpu={self.cpu.uid if self.cpu else None}, num_servers={self.num_servers}, num_cpu_per_server={self.num_cpu_per_server}, ram_size={self.ram_size} GiB)'
def as_dict(self) -> Dict:
return {
'cpu': self.cpu.as_dict(),
'num_servers': self.num_servers,
'num_cpu_per_server': self.num_cpu_per_server,
'ram_size_gib': self.ram_size,
'cpu_slots_mem': [
{
'mem_channels': [
{
'dimms': [
dimm.uid if dimm is not None else None
for dimm in mem_channel.dimms
]
}
for mem_channel in cpu_slot_mem.mem_channels
]
}
for cpu_slot_mem in self.cpu_slots_mem
]
}
@property
def chassis(self) -> ItemUid:
return self.configurator.chassis.item
@ -611,6 +644,20 @@ class Config():
def num_cpus(self) -> int:
return self.num_cpu_per_server * self.num_servers
@property
def ram_modules_per_server(self) -> Dict[Dimm, int]:
num_dimms: Dict[Dimm, int] = {}
for cpu_slot_mem in self.cpu_slots_mem:
for mem_channel in cpu_slot_mem.mem_channels:
for dimm_slot_index in range(self.configurator.chassis.item.num_dimm_slots_per_channel):
slot_dimm = mem_channel.dimms[dimm_slot_index]
if slot_dimm is not None:
if slot_dimm not in num_dimms:
num_dimms[slot_dimm] = 0
num_dimms[slot_dimm] += 1
# assert dimm.uid == slot_dimm.uid, 'different dimms found in the configuration: %s and %s in config: %s' % (dimm.uid, slot_dimm.uid, self.as_dict())
return num_dimms
class Configurator():
modules: Dict[ComponentId, Module]

View File

@ -14,6 +14,7 @@ import hashlib
from concho.config import Cpu, MemSize, Configurator, Config
# from concho import dell
from pathlib import Path
import pandas
import logging
markerTypes = [',', '+', '.', '^', 'v', '<', '>', 'o', '*', '1', '2', '3', '4', '8', 's', 'p', 'h', 'H', 'x', 'X', 'D', 'd', '|', '_']
@ -133,6 +134,9 @@ def plot_configs(configs: List[Config], xaxis_def: ConfigAxisDef, yaxis_def: Con
def GHzToMHz(frequency):
return frequency * 1000.0
def ByteToMib(mem_size: MemSize) -> float:
return float(mem_size) / (1024 * 1024)
def getColorCodeFromItemLabel(label):
# generation = label[-1]
(num_servers, model, num_cpus, proc_id, ram_size) = re.split('_', label)
@ -211,16 +215,23 @@ def plot_configs(configs: List[Config], xaxis_def: ConfigAxisDef, yaxis_def: Con
x1 = xaxis_def.get_value_for_config(config)
y1 = yaxis_def.get_value_for_config(config)
logging.info(f'config {config_label}: x={x1}, y={y1}')
if y1 > 0.0001:
color = getColorCodeFromItemLabel(config_label)
# marker = markersCycler.next()
# marker = get_marker_from_label( label )
# print(x1, y1)
marker = create_unique_marker(config_index)
short_label = config_label.replace('dell-poweredge-', '').replace('intel-xeon-', '').replace('hpe-proliant-', '').replace('-gen', '-g')
short_label = config_label
short_label = short_label.replace('dell-poweredge-', '')
short_label = short_label.replace('intel-xeon-', '')
short_label = short_label.replace('silver-', '')
short_label = short_label.replace('gold-', '')
short_label = short_label.replace('platinum-', '')
short_label = short_label.replace('performance-', '')
short_label = short_label.replace('hpe-proliant-', '')
short_label = short_label.replace('-gen', '-g')
plt.scatter(x1, y1, facecolors=color, s=(markerSize * len(marker)), marker=r'$\mathrm{%s}$' % marker, label=short_label)
legend[marker] = short_label
legend[marker] = config, x1, y1
if False: # y1 > 5.0e16:
plt.annotate(u'%s' % short_label,
xy=(x1, y1), xytext=(x1 * 4.0, (y1 - 5.2e16) * 7.1),
@ -239,8 +250,43 @@ def plot_configs(configs: List[Config], xaxis_def: ConfigAxisDef, yaxis_def: Con
plt.grid(visible=True, which='minor', color='b', linestyle='-', linewidth=0.2)
plt.legend(bbox_to_anchor=(1.1, 1.1), ncol=2)
plt.draw()
sheet = {
'conf': [],
'n_servers': [],
'Chassis': [],
'CPU ID': [],
'cpufreq_mhz': [],
'ncpu/ser': [],
'Dimms per Server': [],
'ram/ser_gb': [],
'Total Cores': [],
'ram/core_gb': [],
'cache/core_mb': [],
'Price (€)': [],
'score/1e16': []
}
for marker in legend:
logging.info(f'config {marker}: {legend[marker]}')
config, x, y = legend[marker]
num_cores = config.cpu.num_cores * config.num_cpu_per_server * config.num_servers
cpu: Cpu = config.cpu
assert cpu.l3_cache_mb > 0, 'no cache info for cpu %s in config %s' % (cpu.uid, config.as_dict())
cache_per_core = float(cpu.l3_cache_mb) / cpu.num_cores
sheet['conf'].append(marker)
sheet['n_servers'].append(config.num_servers)
sheet['Chassis'].append(config.chassis.uid)
sheet['CPU ID'].append(cpu.uid)
sheet['cpufreq_mhz'].append(GHzToMHz(cpu.clock))
sheet['ncpu/ser'].append(config.num_cpu_per_server)
num_dimms = config.ram_modules_per_server
sheet['Dimms per Server'].append(' + '.join([f'{num_dimms[dimm]} x {dimm.num_gb} Gb' for dimm in num_dimms]))
sheet['ram/ser_gb'].append(float(config.ram_size / config.num_servers))
sheet['Total Cores'].append(num_cores)
sheet['ram/core_gb'].append(float(config.ram_size) / float(num_cores))
sheet['cache/core_mb'].append(cache_per_core)
sheet['Price (€)'].append(config.get_price())
sheet['score/1e16'].append(y / 1.e16)
df = pandas.DataFrame(sheet)
logging.info('\n' + df.to_string(index=False))
if figure_file_path:
plt.savefig(figure_file_path)
else: