11import pytest
2+ import os
23import time
34
45import numpy as np
1213from wfl .calculators import generic
1314from wfl .autoparallelize import AutoparaInfo
1415
16+ try :
17+ import torch
18+ from mace .calculators .foundations_models import mace_mp
19+ except ImportError :
20+ torch = None
21+
1522
1623def test_empty_iterator (tmp_path ):
1724 co = buildcell .buildcell (range (0 ), OutputSpec (tmp_path / 'dummy.xyz' ), buildcell_cmd = 'dummy' , buildcell_input = 'dummy' )
@@ -35,21 +42,71 @@ def test_autopara_info_dict():
3542def test_pool_speedup ():
3643 np .random .seed (5 )
3744
45+ rng = np .random .default_rng (5 )
3846 ats = []
3947 nconf = 60
48+ at_prim = Atoms ('Al' , cell = [1 , 1 , 1 ], pbc = [True ] * 3 )
4049 for _ in range (nconf ):
41- ats .append (Atoms (['Al' ] * nconf , scaled_positions = np .random .uniform (size = (nconf , 3 )), cell = [10 , 10 , 10 ], pbc = [True ] * 3 ))
50+ ats .append (at_prim * (4 , 4 , 4 ))
51+ ats [- 1 ].rattle (rng = rng )
4252
4353 t0 = time .time ()
44- co = generic .calculate (ConfigSet (ats ), OutputSpec (), EMT (), output_prefix = "_auto_" , autopara_info = AutoparaInfo (num_python_subprocesses = 1 ))
54+ co = generic .calculate (ConfigSet (ats ), OutputSpec (), EMT (), output_prefix = "_auto_" ,
55+ autopara_info = AutoparaInfo (num_python_subprocesses = 1 ,
56+ num_inputs_per_python_subprocess = 30 ))
4557 dt_1 = time .time () - t0
4658
4759 t0 = time .time ()
48- co = generic .calculate (ConfigSet (ats ), OutputSpec (), EMT (), output_prefix = "_auto_" , autopara_info = AutoparaInfo (num_python_subprocesses = 2 ))
60+ co = generic .calculate (ConfigSet (ats ), OutputSpec (), EMT (), output_prefix = "_auto_" ,
61+ autopara_info = AutoparaInfo (num_python_subprocesses = 2 ,
62+ num_inputs_per_python_subprocess = 30 ))
4963 dt_2 = time .time () - t0
5064
5165 print ("time ratio" , dt_2 / dt_1 )
52- assert dt_2 < dt_1 * (2 / 3 )
66+ assert dt_2 / dt_1 < 0.75
67+
68+
69+ @pytest .mark .skipif (torch is None or not torch .cuda .is_available () or os .environ .get ("WFL_TORCH_N_GPUS" ) is None , reason = "No torch CUDA devices available, or WFL_TORCH_N_GPUS isn't set" )
70+ @pytest .mark .perf
71+ def test_pool_speedup_GPU (monkeypatch ):
72+ np .random .seed (5 )
73+
74+ rng = np .random .default_rng (5 )
75+ ats = []
76+ nconf = 60
77+ at_prim = Atoms ('Al' , cell = [1 , 1 , 1 ], pbc = [True ] * 3 )
78+ for _ in range (nconf ):
79+ ats .append (at_prim * (5 , 5 , 5 ))
80+ ats [- 1 ].rattle (rng = rng )
81+
82+ calc = (mace_mp , ["small-omat-0" ], {"device" : "cuda" })
83+
84+ req_n_gpus = os .environ ["WFL_TORCH_N_GPUS" ]
85+ if len (req_n_gpus ) == 0 :
86+ req_n_gpus = str (len (os .environ ["CUDA_VISIBLE_DEVICES" ].split ("," )))
87+
88+ if "WFL_TORCH_N_GPUS" in os .environ :
89+ monkeypatch .delenv ("WFL_TORCH_N_GPUS" )
90+
91+ t0 = time .time ()
92+ co = generic .calculate (ConfigSet (ats ), OutputSpec (), calc , output_prefix = "_auto_" ,
93+ autopara_info = AutoparaInfo (num_python_subprocesses = 1 ,
94+ num_inputs_per_python_subprocess = 30 ))
95+ dt_1 = time .time () - t0
96+
97+ monkeypatch .setenv ("WFL_TORCH_N_GPUS" , req_n_gpus )
98+
99+ t0 = time .time ()
100+ co = generic .calculate (ConfigSet (ats ), OutputSpec (), calc , output_prefix = "_auto_" ,
101+ autopara_info = AutoparaInfo (num_python_subprocesses = 2 ,
102+ num_inputs_per_python_subprocess = 30 ))
103+ dt_2 = time .time () - t0
104+
105+ monkeypatch .delenv ("WFL_TORCH_N_GPUS" )
106+
107+ print ("time ratio" , dt_2 / dt_1 )
108+ assert dt_2 / dt_1 < 0.75
109+
53110
54111def test_outputspec_overwrite (tmp_path ):
55112 with open (tmp_path / "ats.xyz" , "w" ) as fout :
0 commit comments