Download tools/runmem_cgroup.py from HelloSun/fint-epqv2: direct link, hf CLI and curl.
- Browser
- Download file 3.01 kB
-
https://huggingface.co/HelloSun/fint-epqv2/resolve/main/tools/runmem_cgroup.py
- Command line
-
hf download hf://HelloSun/fint-epqv2/tools/runmem_cgroup.py
-
curl -L -o runmem_cgroup.py https://huggingface.co/HelloSun/fint-epqv2/resolve/main/tools/runmem_cgroup.py
3.01 kB
| #!/usr/bin/env python3 | |
| """Run a command inside a cgroup-v2 MemoryMax scope and report peak memory.""" | |
| import argparse | |
| import json | |
| import os | |
| import subprocess | |
| import sys | |
| import time | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--limit-gib", type=int, required=True) | |
| parser.add_argument("--timeout", type=float, default=7200) | |
| parser.add_argument("command", nargs=argparse.REMAINDER) | |
| args = parser.parse_args() | |
| command = args.command[1:] if args.command[:1] == ["--"] else args.command | |
| if not command: | |
| parser.error("missing command") | |
| if args.limit_gib not in (2, 4, 8, 16, 32): | |
| parser.error("limit must be 2, 4, 8, 16, or 32 GiB") | |
| unit = f"flint-epq-bench-{os.getpid()}" | |
| runner = [ | |
| "systemd-run", "--quiet", "--wait", "--collect", "--pipe", | |
| "--unit", unit, "--property", f"MemoryMax={args.limit_gib}G", | |
| "--property", "MemorySwapMax=0", "--", *command, | |
| ] | |
| started = time.monotonic() | |
| process = subprocess.Popen(runner, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) | |
| time.sleep(1) | |
| if process.poll() is not None: | |
| output, _ = process.communicate() | |
| if output: | |
| sys.stdout.write(output) | |
| print("UNTESTED: systemd/cgroup MemoryMax unavailable; RLIMIT_DATA is not a substitute", file=sys.stderr) | |
| return 77 | |
| peak = swap_peak = 0 | |
| while process.poll() is None: | |
| try: | |
| cgroup = subprocess.check_output( | |
| ["systemctl", "show", f"{unit}.scope", "-p", "ControlGroup", "--value"], | |
| text=True, stderr=subprocess.DEVNULL, | |
| ).strip() | |
| if cgroup: | |
| path = os.path.join("/sys/fs/cgroup", cgroup.lstrip("/")) | |
| for name, target in (("memory.peak", "peak"), ("memory.swap.peak", "swap")): | |
| try: | |
| with open(os.path.join(path, name), encoding="ascii") as stream: | |
| value = int(stream.read().strip()) | |
| if target == "peak": | |
| peak = max(peak, value) | |
| else: | |
| swap_peak = max(swap_peak, value) | |
| except OSError: | |
| pass | |
| except (OSError, subprocess.CalledProcessError): | |
| pass | |
| if time.monotonic() - started > args.timeout: | |
| process.kill() | |
| break | |
| time.sleep(0.25) | |
| output, _ = process.communicate() | |
| if output: | |
| sys.stdout.write(output) | |
| print("RUNMEM " + json.dumps({ | |
| "limit_gib": args.limit_gib, | |
| "peak_bytes": peak, | |
| "peak_gib": round(peak / (1024 ** 3), 3), | |
| "swap_peak_bytes": swap_peak, | |
| "wall_s": round(time.monotonic() - started, 2), | |
| "exit": process.returncode, | |
| "cmd": command, | |
| "method": "cgroup-v2-MemoryMax", | |
| })) | |
| return process.returncode | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |