added bin cache metadata info show. Get all states by default

This commit is contained in:
2026-06-29 09:09:01 +02:00
parent 0c120b55ad
commit 29126cdb36
+49 -20
View File
@@ -29,6 +29,7 @@ import statistics
import subprocess
import sys
import signal
import time
from collections import defaultdict
from dataclasses import dataclass, field, fields, asdict
from pathlib import Path
@@ -38,7 +39,7 @@ from typing import Any, Iterable, Mapping
import msgpack
import gzip
VERSION=0.2
VERSION=0.21
# Default GB per CPUs for the cluster
default_mempercpu_gb = 2.0
@@ -608,11 +609,30 @@ def write_binary_cache(records: list[JobRecord], filename):
cache = [asdict(r) for r in records]
cache_blob = {
"slurm_eff_version": VERSION,
"cmdline": " ".join(sys.argv),
"created": time.time(),
"records": cache
}
with gzip.open(filename, "wb") as f:
msgpack.pack(cache_blob, f)
def read_binary_cache(filename: str) -> dict[str, str or list[JobRecord]]:
result = {}
with gzip.open(filename, "rb") as f:
blob = msgpack.unpack(f, raw=False)
for mdfield in ['slurm_eff_version', 'cmdline', 'created']:
result[mdfield] = blob.get(mdfield,'undefined')
if result['slurm_eff_version'] != VERSION:
sys.stderr.write(f"WARNING: cache was written by version f{result['slurm_eff_version']}, but we are running version {VERSION}\n")
result['records'] = [JobRecord(**d) for d in blob["records"]]
return result
def show_cache_info(filename: str):
cache = read_binary_cache(filename)
for mdfield in ['slurm_eff_version', 'cmdline', 'created']:
print(f'{mdfield}: {cache[mdfield]}')
def base_job_id(jobid: str) -> str:
return re.split(r"[._]", jobid, maxsplit=1)[0]
@@ -1051,21 +1071,30 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
Examples:
# first get an overview (-U/--aggr-user) and write a cachefile
slurm-eff-tool -O sacct.cache -U
slurm-eff-tool -B sacct.cache -U
slurm-eff-tool.py -B sacct.cache --start 2026-05-01 --end 2026-05-22 -U
slurm-eff-tool.py -B sacct.cache --start 2026-05-01 --end now -U
# now you can read the cachefile for later runs and e.g. sort based on waste_Mem
slurm-eff-tool -F sacct.cache -U -s=-Y
slurm-eff-tool -L sacct.cache -U -s=-waste_mem
# only list a specific user's summary lines
slurm-eff-tool.py -L sacct.cache -U -u dfeich
# list that user's single jobs
slurm-eff-tool.py -L sacct.cache -u dfeich
slurm-eff-tool.py -F sacct.cache --start 2026-05-01 --end 2026-05-22 -u dfeich
slurm-eff-tool.py -F sacct.cache -S 2026-05-01 -E now -u dfeich
# supports multiple sort keys
slurm-eff-tool.py -F sacct.cache --aggr-user --sdev -s cpu,-mem,time
# cluster jobs by Regexps
slurm-eff-tool.py -F sacct.cache -u dfeich -R '^vasp','^gromacs' --json
slurm-eff-tool.py -L sacct.cache --aggr-user --sdev -s cpu,-mem,time
# you can cluster jobs by Regexps applying to the job names
slurm-eff-tool.py -L sacct.cache -u dfeich -R '^vasp','^gromacs'
# supports flexibel output formatting
slurm-eff-tool.py -F sacct.cache -o username,Y
# only print rows that evaluate to true based on expression
slurm-eff-tool.py -F sacct.cache -U --expr "(waste_Mem > 2000 and Mem_Eff < 20) and MaxRSS_max/AllocMem < 0.5"
"""
slurm-eff-tool.py -L sacct.cache -o username,Y
# only print rows that evaluate to true based on arithmetic expressions
slurm-eff-tool.py -L sacct.cache -U --expr "(waste_Mem > 2000 and Mem_Eff < 20) and MaxRSS_max/AllocMem < 0.5"
"""
)
p.add_argument("-S", "--start", help="sacct start time, passed to sacct -S",
@@ -1074,13 +1103,14 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
default="now")
p.add_argument("-u", "--user", help="restrict to one user; passed as sacct -u unless reading from cache")
p.add_argument("--state", "--job-state", dest="state",
default="COMPLETED",
default=None,
help="sacct state filter, e.g. COMPLETED,FAILED,TIMEOUT")
p.add_argument("-O", "--output-raw", help="write raw sacct output cache to this file")
p.add_argument("-F", "--from-raw", help="read raw sacct output cache from this file instead of running sacct")
p.add_argument("-B", "--write-binary-cache", help="write a binary cache file in msgpack format")
p.add_argument("-L", "--load-binary-cache", help="load a binary cache file in msgpack format")
p.add_argument("-i", "--info", help="show information for the given binary cache file")
p.add_argument("-U", "--aggr-user", action="store_true", help="aggregate jobs by user, CPUs, nodes, ReqMem, and timelimit")
p.add_argument(
"-R",
@@ -1118,6 +1148,10 @@ def main(argv: list[str] | None = None) -> int:
args = parse_args(argv or sys.argv[1:])
if args.info:
show_cache_info(args.info)
sys.exit(0)
output_columns = PRESET_COLUMNS["default"]
if args.preset:
output_columns = PRESET_COLUMNS[args.preset]
@@ -1131,13 +1165,8 @@ def main(argv: list[str] | None = None) -> int:
# CREATE RECORDS FROM SACCT QUERY OR FILE, OR LOAD PROCESSED RECORDS FROM BINARY CACHE
if args.load_binary_cache:
with gzip.open(args.load_binary_cache, "rb") as f:
blob = msgpack.unpack(f, raw=False)
version_str = blob["slurm_eff_version"]
if version_str != VERSION:
sys.stderr.write(f"WARNING: cache was written by version f{version_str}, but this is version {VERSION}\n")
# print(f"DEBUG: Loading from a binary cache created by version {version_str}")
records = [JobRecord(**d) for d in blob["records"]]
cache = read_binary_cache(args.load_binary_cache)
records = cache['records']
else:
if args.from_raw:
rows = read_cache_raw(args.from_raw)