From fd5c8a9ab4c6e3997ef74d0cbd83b0cb5c331984 Mon Sep 17 00:00:00 2001 From: Nathan Date: Tue, 23 Dec 2025 17:01:00 -0700 Subject: [PATCH] use over 61 workers --- .../history/2025-12-23_23-54Z-untitled.md | 40 +++++++++++++++++++ compress_pngs.py | 21 +++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 .specstory/history/2025-12-23_23-54Z-untitled.md diff --git a/.specstory/history/2025-12-23_23-54Z-untitled.md b/.specstory/history/2025-12-23_23-54Z-untitled.md new file mode 100644 index 0000000..140f3ab --- /dev/null +++ b/.specstory/history/2025-12-23_23-54Z-untitled.md @@ -0,0 +1,40 @@ + + + + +# Untitled (2025-12-23 23:54Z) + +_**User (2025-12-23 23:54Z)**_ + +it didn't work on the threadripper. additional context: @.specstory/history/2025-12-11_18-21Z-compress-png-sequences-with-multithreading.md + +Mode: Auto-detect bit depth (preserve 16-bit if present) +Input directory: input +Output directory: output +Scanning for image files... +Found 646 JPG/JPEG files - ignoring (skipping) +Found 6371 PNG files to process. +Corrupted files will be moved to: corrupted +Using 64 worker processes for compression... +-------------------------------------------------------------------------------- +Traceback (most recent call last): + File "E:\SequenceCompressor\compress_pngs.py", line 427, in + main() + ~~~~^^ + File "E:\SequenceCompressor\compress_pngs.py", line 328, in main + with ProcessPoolExecutor(max_workers=max_workers) as executor: + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Python314\Lib\concurrent\futures\process.py", line 671, in __init__ + raise ValueError( + f"max_workers must be <= {_MAX_WINDOWS_WORKERS}") +ValueError: max_workers must be <= 61 +Press any key to continue . . . + +--- + +_**Agent (model default, mode Agent)**_ + + + +--- + diff --git a/compress_pngs.py b/compress_pngs.py index 8264be2..1f72ecb 100644 --- a/compress_pngs.py +++ b/compress_pngs.py @@ -7,12 +7,21 @@ Compresses all PNG files in subdirectories with maximum parallelism. import os import sys import argparse +import platform from pathlib import Path from concurrent.futures import ProcessPoolExecutor, as_completed from PIL import Image import multiprocessing import time +# Try to unlock ProcessPoolExecutor on Windows to bypass 61-worker limit +try: + import unlock_processpool + unlock_processpool.please() + UNLOCKED = True +except ImportError: + UNLOCKED = False + def compress_png(input_path, output_path, force_bitdepth=None): """Compress a single PNG file. @@ -311,7 +320,17 @@ def main(): print(f"Corrupted files will be moved to: {corrupted_dir}") # Use all available CPU cores - max_workers = multiprocessing.cpu_count() + cpu_count = multiprocessing.cpu_count() + if platform.system() == 'Windows' and not UNLOCKED: + # Windows ProcessPoolExecutor has a maximum of 61 workers (unless unlocked) + max_workers = min(cpu_count, 61) + if cpu_count > 61: + print(f"Detected {cpu_count} CPU threads, but Windows limits ProcessPoolExecutor to 61 workers.") + print("Install 'unlock-processpool-win' package to use all cores: pip install unlock-processpool-win") + else: + max_workers = cpu_count + if UNLOCKED: + print(f"Using unlock-processpool-win to bypass Windows 61-worker limit") print(f"Using {max_workers} worker processes for compression...") print("-" * 80)