added bin cache metadata info show. Get all states by default
This commit is contained in:
+49
-20
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user