introduce a waste_total metric that normalizes CPU and Mem waste
This commit is contained in:
+30
-4
@@ -84,6 +84,7 @@ ALL_COLUMNS = [
|
||||
"Walltime",
|
||||
"Walltime_max",
|
||||
"Time_Eff",
|
||||
"waste_total",
|
||||
"jobname",
|
||||
]
|
||||
|
||||
@@ -157,6 +158,21 @@ PRESET_COLUMNS = {
|
||||
"Mem_Eff",
|
||||
"waste_Mem",
|
||||
"jobname",],
|
||||
"waste": [
|
||||
"username",
|
||||
"JobID",
|
||||
"state",
|
||||
"Count",
|
||||
"NTasks",
|
||||
"CPUs",
|
||||
"Nodes",
|
||||
"CPU_Eff",
|
||||
"Mem_Eff",
|
||||
"Time_Eff",
|
||||
"waste_CPU",
|
||||
"waste_Mem",
|
||||
"waste_total",
|
||||
"jobname",],
|
||||
}
|
||||
|
||||
# One-character aliases for sorting and output format specifications.
|
||||
@@ -176,6 +192,7 @@ ALIASES = {
|
||||
"j": "jobname",
|
||||
"X": "waste_CPU",
|
||||
"Y": "waste_Mem",
|
||||
"T": "waste_total",
|
||||
}
|
||||
|
||||
NUMERIC_COLUMNS = {
|
||||
@@ -195,6 +212,7 @@ NUMERIC_COLUMNS = {
|
||||
"Walltime_max",
|
||||
"waste_CPU",
|
||||
"waste_Mem",
|
||||
"waste_total",
|
||||
}
|
||||
|
||||
state_mappings = {
|
||||
@@ -419,6 +437,7 @@ class OutputRow:
|
||||
walltime_max: float | None # in h
|
||||
waste_CPU: float | None # CPU h
|
||||
waste_Mem: float | None
|
||||
waste_total: float | None
|
||||
_cpu_eff_values: list[float] = field(default_factory=list, repr=False)
|
||||
_mem_eff_values: list[float] = field(default_factory=list, repr=False)
|
||||
_time_eff_values: list[float] = field(default_factory=list, repr=False)
|
||||
@@ -446,6 +465,7 @@ class OutputRow:
|
||||
"jobname": self.jobname,
|
||||
"waste_CPU": self.waste_CPU,
|
||||
"waste_Mem": self.waste_Mem,
|
||||
"waste_total": self.waste_total
|
||||
}
|
||||
if sdev:
|
||||
for col, vals in [
|
||||
@@ -893,12 +913,12 @@ def make_single_row(rec: JobRecord, dflt_mpcpu: float) -> OutputRow:
|
||||
"""Returns an OutputRow based on a single slurm job record."""
|
||||
walltime = rec.elapsed_sec / 3600
|
||||
|
||||
waste_mem = None
|
||||
waste_mem = 0
|
||||
if rec.mem_eff is not None and rec.reqmem_gb is not None:
|
||||
waste_mem = max(0,walltime * (100-rec.mem_eff)/100 \
|
||||
* (rec.reqmem_gb - rec.cpus * dflt_mpcpu))
|
||||
|
||||
waste_cpu = None
|
||||
waste_cpu = 0
|
||||
if rec.cpu_eff is not None:
|
||||
# We count failed jobs as wasted CPU!
|
||||
if rec.state != state_mappings['COMPLETED']:
|
||||
@@ -906,6 +926,8 @@ def make_single_row(rec: JobRecord, dflt_mpcpu: float) -> OutputRow:
|
||||
else:
|
||||
waste_cpu = walltime * (100-rec.cpu_eff)/100 * rec.cpus
|
||||
|
||||
waste_total = waste_cpu + waste_mem/dflt_mpcpu
|
||||
|
||||
jobid = rec.jobidraw
|
||||
if jobid == "":
|
||||
jobid = rec.jobid
|
||||
@@ -932,6 +954,7 @@ def make_single_row(rec: JobRecord, dflt_mpcpu: float) -> OutputRow:
|
||||
walltime_max= walltime,
|
||||
waste_Mem=waste_mem,
|
||||
waste_CPU=waste_cpu,
|
||||
waste_total=waste_total,
|
||||
_cpu_eff_values=[rec.cpu_eff] if rec.cpu_eff is not None else [],
|
||||
_mem_eff_values=[rec.mem_eff] if rec.mem_eff is not None else [],
|
||||
_time_eff_values=[rec.time_eff] if rec.time_eff is not None else [],
|
||||
@@ -960,7 +983,7 @@ def make_aggregate_row(records: list[JobRecord], username: str,
|
||||
memory_efficiency=mean_or_none(mem_eff_vals)
|
||||
count=len(records)
|
||||
|
||||
waste_mem = None
|
||||
waste_mem = 0
|
||||
if (memory_efficiency is not None) and (walltime is not None) \
|
||||
and first.reqmem_gb is not None:
|
||||
waste_mem = max(0,count * walltime * (100-memory_efficiency)/100 \
|
||||
@@ -968,7 +991,7 @@ def make_aggregate_row(records: list[JobRecord], username: str,
|
||||
|
||||
cpu_efficiency = mean_or_none(cpu_eff_vals)
|
||||
|
||||
waste_cpu=None
|
||||
waste_cpu=0
|
||||
if cpu_efficiency is not None and walltime is not None:
|
||||
# We count failed jobs as wasted CPU!
|
||||
if first.state != state_mappings['COMPLETED']:
|
||||
@@ -976,6 +999,8 @@ def make_aggregate_row(records: list[JobRecord], username: str,
|
||||
else:
|
||||
waste_cpu = count * walltime * (100-cpu_efficiency)/100 * first.cpus
|
||||
|
||||
waste_total = waste_cpu + waste_mem/dflt_mpcpu
|
||||
|
||||
return OutputRow(
|
||||
username=username,
|
||||
JobID="",
|
||||
@@ -998,6 +1023,7 @@ def make_aggregate_row(records: list[JobRecord], username: str,
|
||||
walltime_max=max([r.elapsed_sec for r in records if r.elapsed_sec is not None]) / 3600,
|
||||
waste_Mem=waste_mem,
|
||||
waste_CPU=waste_cpu,
|
||||
waste_total=waste_total,
|
||||
_cpu_eff_values=cpu_eff_vals,
|
||||
_mem_eff_values=mem_eff_vals,
|
||||
_time_eff_values=time_eff_vals,
|
||||
|
||||
Reference in New Issue
Block a user