rmbielski commited on
Commit
1d6576d
·
1 Parent(s): 6f73e2e

I changed prep_utils.py (line 266) so every ANTs subprocess now sets:

Browse files

ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS
OMP_NUM_THREADS
OMP_THREAD_LIMIT

Files changed (2) hide show
  1. README.md +5 -0
  2. src/data_prep/prep_utils.py +41 -0
README.md CHANGED
@@ -38,6 +38,11 @@ These defaults can be overridden with:
38
  - `HF_RUNTIME_REPO_ID`
39
  - `HF_RUNTIME_REVISION`
40
 
 
 
 
 
 
41
  ## Experimental Mask Editor
42
 
43
  An isolated post-segmentation mask editor scaffold is available behind the
 
38
  - `HF_RUNTIME_REPO_ID`
39
  - `HF_RUNTIME_REVISION`
40
 
41
+ Registration threading can be controlled with:
42
+
43
+ - `PREP_ANTS_THREADS` to set the exact ANTs/ITK thread count
44
+ - `PREP_ANTS_THREAD_CAP` to cap the automatic count (default: `8`)
45
+
46
  ## Experimental Mask Editor
47
 
48
  An isolated post-segmentation mask editor scaffold is available behind the
src/data_prep/prep_utils.py CHANGED
@@ -263,12 +263,52 @@ def _command_timeout_seconds() -> int | None:
263
  return None if seconds <= 0 else seconds
264
 
265
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  def _run(cmd: list[str]):
267
  cmd_str = " ".join(map(str, cmd))
268
  timeout_sec = _command_timeout_seconds()
269
  timeout_label = f"{timeout_sec}s" if timeout_sec is not None else "disabled"
 
 
270
  print(">>", cmd_str)
271
  print(f"[cmd] timeout={timeout_label}")
 
 
 
 
 
272
  t0 = time.monotonic()
273
  try:
274
  res = subprocess.run(
@@ -277,6 +317,7 @@ def _run(cmd: list[str]):
277
  stderr=subprocess.STDOUT,
278
  text=True,
279
  timeout=timeout_sec,
 
280
  )
281
  except subprocess.TimeoutExpired as exc:
282
  elapsed = time.monotonic() - t0
 
263
  return None if seconds <= 0 else seconds
264
 
265
 
266
+ def _available_cpu_count() -> int:
267
+ try:
268
+ return max(1, len(os.sched_getaffinity(0)))
269
+ except Exception:
270
+ return max(1, os.cpu_count() or 1)
271
+
272
+
273
+ def _ants_thread_count() -> int:
274
+ raw = os.environ.get("PREP_ANTS_THREADS", "").strip()
275
+ if raw:
276
+ try:
277
+ return max(1, int(float(raw)))
278
+ except ValueError:
279
+ print(f"[setup] invalid PREP_ANTS_THREADS={raw!r}; using automatic thread count")
280
+
281
+ cap_raw = os.environ.get("PREP_ANTS_THREAD_CAP", "8").strip()
282
+ try:
283
+ cap = max(1, int(float(cap_raw)))
284
+ except ValueError:
285
+ print(f"[setup] invalid PREP_ANTS_THREAD_CAP={cap_raw!r}; using 8")
286
+ cap = 8
287
+ return max(1, min(_available_cpu_count(), cap))
288
+
289
+
290
+ def _subprocess_env() -> dict[str, str]:
291
+ env = os.environ.copy()
292
+ threads = str(_ants_thread_count())
293
+ env["ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS"] = threads
294
+ env["OMP_NUM_THREADS"] = threads
295
+ env["OMP_THREAD_LIMIT"] = threads
296
+ return env
297
+
298
+
299
  def _run(cmd: list[str]):
300
  cmd_str = " ".join(map(str, cmd))
301
  timeout_sec = _command_timeout_seconds()
302
  timeout_label = f"{timeout_sec}s" if timeout_sec is not None else "disabled"
303
+ env = _subprocess_env()
304
+ threads = env["ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS"]
305
  print(">>", cmd_str)
306
  print(f"[cmd] timeout={timeout_label}")
307
+ print(
308
+ f"[cmd] ants_threads={threads} "
309
+ f"available_cpus={_available_cpu_count()} "
310
+ f"thread_cap={os.environ.get('PREP_ANTS_THREAD_CAP', '8')}"
311
+ )
312
  t0 = time.monotonic()
313
  try:
314
  res = subprocess.run(
 
317
  stderr=subprocess.STDOUT,
318
  text=True,
319
  timeout=timeout_sec,
320
+ env=env,
321
  )
322
  except subprocess.TimeoutExpired as exc:
323
  elapsed = time.monotonic() - t0