1
1
import subprocess
2
2
import sys
3
+ from pathlib import Path
3
4
from unittest .mock import Mock
4
5
5
6
import pytest
13
14
14
15
if _HYDRA_WITH_RUN_PROCESS :
15
16
from hydra .test_utils .test_utils import run_process
17
+ from omegaconf import OmegaConf
16
18
17
19
18
20
# Script to run from command line
@@ -48,7 +50,7 @@ def task_fn(cfg):
48
50
49
51
@RunIf (min_cuda_gpus = 2 , skip_windows = True , standalone = True )
50
52
@pytest .mark .skipif (not _HYDRA_WITH_RUN_PROCESS , reason = str (_HYDRA_WITH_RUN_PROCESS ))
51
- @pytest .mark .parametrize ("subdir" , [None , "dksa" , ".hello" ])
53
+ @pytest .mark .parametrize ("subdir" , [None , "null" , " dksa" , ".hello" ])
52
54
def test_ddp_with_hydra_runjob (subdir , tmpdir , monkeypatch ):
53
55
monkeypatch .chdir (tmpdir )
54
56
@@ -58,11 +60,56 @@ def test_ddp_with_hydra_runjob(subdir, tmpdir, monkeypatch):
58
60
59
61
# Run CLI
60
62
devices = 2
61
- cmd = [sys .executable , "temp.py" , f"+devices={ devices } " , '+strategy="ddp"' ]
63
+ run_dir = Path (tmpdir ) / "hydra_output"
64
+ cmd = [sys .executable , "temp.py" , f"+devices={ devices } " , '+strategy="ddp"' , f"hydra.run.dir={ run_dir } " ]
62
65
if subdir is not None :
63
66
cmd += [f"hydra.output_subdir={ subdir } " ]
64
67
run_process (cmd )
65
68
69
+ # Make sure config.yaml was created for additional processes iff subdir is present.
70
+ saved_confs = list (run_dir .glob ("**/config.yaml" ))
71
+ assert len (saved_confs ) == (0 if subdir == "null" else devices )
72
+
73
+ if saved_confs : # Make sure the parameter was set and used
74
+ cfg = OmegaConf .load (saved_confs [0 ])
75
+ assert cfg .devices == devices
76
+
77
+ # Make sure PL spawned jobs that are logged by Hydra
78
+ logs = list (run_dir .glob ("**/*.log" ))
79
+ assert len (logs ) == devices
80
+
81
+
82
+ @RunIf (min_cuda_gpus = 2 , skip_windows = True , standalone = True )
83
+ @pytest .mark .skipif (not _HYDRA_WITH_RUN_PROCESS , reason = str (_HYDRA_WITH_RUN_PROCESS ))
84
+ @pytest .mark .parametrize ("num_jobs" , [1 , 2 ])
85
+ def test_ddp_with_hydra_multirunjob (tmpdir , num_jobs , monkeypatch ):
86
+ monkeypatch .chdir (tmpdir )
87
+
88
+ # Save script locally
89
+ with open ("temp.py" , "w" ) as fn :
90
+ fn .write (script )
91
+
92
+ # Run CLI
93
+ devices = 2
94
+ sweep_dir = Path (tmpdir ) / "hydra_output"
95
+ command = [sys .executable , "temp.py" , f"+devices={ devices } " , '+strategy="ddp"' , f"hydra.sweep.dir={ sweep_dir } " ]
96
+ command += ["--multirun" , "+foo=" + "," .join (str (i ) for i in range (num_jobs ))] # fake multirun params
97
+ run_process (command )
98
+
99
+ # Make sure config.yaml was created for each job
100
+ saved_confs = list (sweep_dir .glob ("**/config.yaml" ))
101
+ assert len (saved_confs ) == devices * num_jobs
102
+
103
+ # Make sure the parameter was set and used for each job
104
+ for config in saved_confs :
105
+ cfg = OmegaConf .load (config )
106
+ local_rank = int (config .parent .parent .parts [- 1 ])
107
+ assert cfg .devices == devices
108
+ assert cfg .foo == local_rank
109
+
110
+ logs = list (sweep_dir .glob ("**/*.log" ))
111
+ assert len (logs ) == devices * num_jobs
112
+
66
113
67
114
def test_kill ():
68
115
launcher = _SubprocessScriptLauncher (Mock (), 1 , 1 )
0 commit comments