From 39e89e5cd06111e65e592d49230e6574d24f1b42 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 4 Apr 2024 11:21:16 +0200 Subject: [PATCH 1/6] added requirements with versions for python3.6 --- requirements36.txt | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 requirements36.txt diff --git a/requirements36.txt b/requirements36.txt new file mode 100644 index 000000000..8324ade61 --- /dev/null +++ b/requirements36.txt @@ -0,0 +1,44 @@ +appdirs==1.4.4 +attrs==22.2.0 +certifi==2024.2.2 +charset-normalizer==2.0.12 +click==8.0.4 +cloudpickle==2.2.1 +commonmark==0.9.1 +docker-pycreds==0.4.0 +editdistance==0.6.2 +gitdb==4.0.9 +GitPython==3.1.18 +idna==3.6 +importlib-metadata==4.8.3 +iniconfig==1.1.1 +joblib==1.1.1 +numpy +packaging==21.3 +pathtools==0.1.2 +Pillow==8.4.0 +pluggy==1.0.0 +protobuf==3.19.6 +psutil==5.9.8 +py==1.11.0 +Pygments==2.14.0 +pyparsing==3.1.2 +pytest==7.0.1 +PyYAML==6.0.1 +requests==2.27.1 +rich==12.6.0 +scikit-learn==0.24.2 +scipy==1.5.4 +sentry-sdk==1.44.1 +setproctitle==1.2.3 +six==1.16.0 +smmap==5.0.0 +submitit==1.4.6 +threadpoolctl==3.1.0 +tomli==1.2.3 +torch==1.10.2 +torchvision==0.11.3 +typing_extensions==4.1.1 +urllib3==1.26.18 +wandb==0.15.12 +zipp==3.6.0 \ No newline at end of file From 2b76b79c5c6d7dcea9a2cc8fab03aa53ef5a5186 Mon Sep 17 00:00:00 2001 From: kaulson Date: Thu, 4 Apr 2024 12:07:20 +0200 Subject: [PATCH 2/6] changed handeling of stdout and stderr in ConcurrentWrapper --- egg/nest/wrappers.py | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/egg/nest/wrappers.py b/egg/nest/wrappers.py index 7f966b465..9dd9628cb 100644 --- a/egg/nest/wrappers.py +++ b/egg/nest/wrappers.py @@ -40,18 +40,26 @@ def __init__(self, runnable, log_dir, job_id): def __call__(self, args): stdout_path = pathlib.Path(self.log_dir) / f"{self.job_id}.out" - self.stdout = open(stdout_path, "w") - stderr_path = pathlib.Path(self.log_dir) / f"{self.job_id}.err" - self.stderr = open(stderr_path, "w") - - sys.stdout = self.stdout - sys.stderr = self.stderr - cuda_id = -1 - n_devices = torch.cuda.device_count() - if n_devices > 0: - cuda_id = self.job_id % n_devices - print(f"# {json.dumps(args)}", flush=True) - - with torch.cuda.device(cuda_id): - self.runnable(args) + + with open(stdout_path, "w") as self.stdout, open(stderr_path, "w") as self.stderr: + original_stdout = sys.stdout + original_stderr = sys.stderr + sys.stdout = self.stdout + sys.stderr = self.stderr + + cuda_id = -1 + n_devices = torch.cuda.device_count() + if n_devices > 0: + cuda_id = self.job_id % n_devices + + print(f"# {json.dumps(args)}", flush=True) + + with torch.cuda.device(cuda_id): + self.runnable(args) + + sys.stdout.flush() + sys.stderr.flush() + + sys.stdout = original_stdout + sys.stderr = original_stderr From 71786f656aff68da0d65e49b0d77ff7b137d3790 Mon Sep 17 00:00:00 2001 From: kaulson Date: Thu, 4 Apr 2024 12:11:27 +0200 Subject: [PATCH 3/6] removed unnecessary requirements file --- requirements36.txt | 44 -------------------------------------------- 1 file changed, 44 deletions(-) delete mode 100644 requirements36.txt diff --git a/requirements36.txt b/requirements36.txt deleted file mode 100644 index 8324ade61..000000000 --- a/requirements36.txt +++ /dev/null @@ -1,44 +0,0 @@ -appdirs==1.4.4 -attrs==22.2.0 -certifi==2024.2.2 -charset-normalizer==2.0.12 -click==8.0.4 -cloudpickle==2.2.1 -commonmark==0.9.1 -docker-pycreds==0.4.0 -editdistance==0.6.2 -gitdb==4.0.9 -GitPython==3.1.18 -idna==3.6 -importlib-metadata==4.8.3 -iniconfig==1.1.1 -joblib==1.1.1 -numpy -packaging==21.3 -pathtools==0.1.2 -Pillow==8.4.0 -pluggy==1.0.0 -protobuf==3.19.6 -psutil==5.9.8 -py==1.11.0 -Pygments==2.14.0 -pyparsing==3.1.2 -pytest==7.0.1 -PyYAML==6.0.1 -requests==2.27.1 -rich==12.6.0 -scikit-learn==0.24.2 -scipy==1.5.4 -sentry-sdk==1.44.1 -setproctitle==1.2.3 -six==1.16.0 -smmap==5.0.0 -submitit==1.4.6 -threadpoolctl==3.1.0 -tomli==1.2.3 -torch==1.10.2 -torchvision==0.11.3 -typing_extensions==4.1.1 -urllib3==1.26.18 -wandb==0.15.12 -zipp==3.6.0 \ No newline at end of file From 39dc7c96124032fb98c59fe5e66be32b0e8160b6 Mon Sep 17 00:00:00 2001 From: kaulson Date: Thu, 4 Apr 2024 12:43:00 +0200 Subject: [PATCH 4/6] added tests for ConcurrentWrapper --- tests/test_concurrent_wrapper.py | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/test_concurrent_wrapper.py diff --git a/tests/test_concurrent_wrapper.py b/tests/test_concurrent_wrapper.py new file mode 100644 index 000000000..20815a14b --- /dev/null +++ b/tests/test_concurrent_wrapper.py @@ -0,0 +1,46 @@ +import json +import sys + +import pytest + +from egg.nest.wrappers import ConcurrentWrapper + + +def dummy_runnable(args): + print("Running dummy_runnable") + print(json.dumps(args), file=sys.stderr) + + +def test_file_descriptor_closure(tmp_path): + """ + Test to check if file descriptors are closed. + Attempting to write to a closed file should raise a ValueError + """ + runnable = dummy_runnable + log_dir = tmp_path + job_id = 1 + + wrapper = ConcurrentWrapper(runnable, log_dir, job_id) + wrapper({"key": "value"}) + + with pytest.raises(ValueError): + wrapper.stdout.write("This should fail if the file is closed.") + + with pytest.raises(ValueError): + wrapper.stderr.write("This should fail if the file is closed.") + + +def test_stdout_stderr_restoration(tmp_path): + """Test to ensure sys.stdout and sys.stderr are restored""" + original_stdout = sys.stdout + original_stderr = sys.stderr + + runnable = dummy_runnable + log_dir = tmp_path + job_id = 2 + + wrapper = ConcurrentWrapper(runnable, log_dir, job_id) + wrapper({"another_key": "another_value"}) + + assert sys.stdout == original_stdout + assert sys.stderr == original_stderr From d8e916307a5d184005afdcc2e7803487ac566671 Mon Sep 17 00:00:00 2001 From: kaulson Date: Thu, 4 Apr 2024 13:07:38 +0200 Subject: [PATCH 5/6] added a test for delayed output of a runnable used with ConcurrentWrapper --- tests/test_concurrent_wrapper.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/test_concurrent_wrapper.py b/tests/test_concurrent_wrapper.py index 20815a14b..d19740f2d 100644 --- a/tests/test_concurrent_wrapper.py +++ b/tests/test_concurrent_wrapper.py @@ -1,10 +1,17 @@ import json +import multiprocessing +import pathlib import sys +import time import pytest from egg.nest.wrappers import ConcurrentWrapper +multiprocessing.set_start_method( + "spawn", force=True +) # avoiding issue with CUDA re-initialization in a forked subprocess + def dummy_runnable(args): print("Running dummy_runnable") @@ -44,3 +51,26 @@ def test_stdout_stderr_restoration(tmp_path): assert sys.stdout == original_stdout assert sys.stderr == original_stderr + + +def delayed_print_runnable(args): + print("This is a test.") + time.sleep(0.1) # Introduce a slight delay + + +def test_delayed_output_capture(tmp_path): + log_dir = tmp_path + job_id = 1 + + runner = ConcurrentWrapper( + runnable=delayed_print_runnable, log_dir=log_dir, job_id=job_id + ) + + runner([]) + + stdout_path = pathlib.Path(log_dir) / f"{job_id}.out" + + with open(stdout_path, "r") as f: + output = f.read() + + assert "This is a test." in output, "Expected output was not captured in the file." From c334d669198bd33edc3544fb85762d68af325b57 Mon Sep 17 00:00:00 2001 From: kaulson Date: Thu, 4 Apr 2024 13:07:59 +0200 Subject: [PATCH 6/6] formatting fixes --- egg/nest/wrappers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/egg/nest/wrappers.py b/egg/nest/wrappers.py index 9dd9628cb..ace4d02e6 100644 --- a/egg/nest/wrappers.py +++ b/egg/nest/wrappers.py @@ -42,7 +42,9 @@ def __call__(self, args): stdout_path = pathlib.Path(self.log_dir) / f"{self.job_id}.out" stderr_path = pathlib.Path(self.log_dir) / f"{self.job_id}.err" - with open(stdout_path, "w") as self.stdout, open(stderr_path, "w") as self.stderr: + with open(stdout_path, "w") as self.stdout, open( + stderr_path, "w" + ) as self.stderr: original_stdout = sys.stdout original_stderr = sys.stderr sys.stdout = self.stdout