1 # The myplugin module must be locatable by Python.
2 # If you configured CMake in the build directory ``/path/to/repo/build`` then,
3 # assuming you are in ``/path/to/repo``, run the tests with something like
4 # PYTHONPATH=./cmake-build-debug/src/pythonmodule mpiexec -n 2 python -m mpi4py -m pytest tests/
6 # This test is not currently run automatically in any way. Build the module, point your PYTHONPATH at it,
7 # and run pytest in the tests directory.
13 import mpi4py.MPI as _MPI
14 except (ImportError, ModuleNotFoundError):
18 from gmxapi.simulation.context import Context
19 from gmxapi.simulation.workflow import WorkElement, from_tpr
20 from gmxapi import version as gmx_version
23 # create console handler
24 ch = logging.StreamHandler()
25 ch.setLevel(logging.DEBUG)
26 # create formatter and add it to the handler
27 formatter = logging.Formatter('%(asctime)s:%(name)s:%(levelname)s: %(message)s')
28 ch.setFormatter(formatter)
29 # add the handlers to the logger
30 logging.getLogger().addHandler(ch)
32 logger = logging.getLogger()
36 # Suppress inspection warning outside of testing context.
37 # noinspection PyUnresolvedReferences
42 @pytest.mark.usefixtures("cleandir")
43 def test_binding_protocol(spc_water_box, mdrun_kwargs):
44 """Test that gmxapi successfully attaches MD plugins."""
48 _size = _MPI.COMM_WORLD.Get_size()
49 _rank = _MPI.COMM_WORLD.Get_rank()
54 tpr_filename = spc_water_box
55 logger.info("Testing plugin potential with input file {}".format(os.path.abspath(tpr_filename)))
57 assert gmx.version.api_is_at_least(0, 2, 1)
58 md = from_tpr([tpr_filename] * _size, append_output=False, **mdrun_kwargs)
60 potential = WorkElement(namespace="myplugin",
61 operation="null_restraint",
62 params={'sites': [1, 4]})
63 potential.name = "null restraint"
64 md.add_dependency(potential)
68 with context as session:
71 # See also #3038, #3145, #4079
72 assert isinstance(context.potentials, list)
73 assert len(context.potentials) > 0
74 for restraint in context.potentials:
75 if isinstance(restraint, myplugin.NullRestraint):
76 assert gmx.version.api_is_at_least(0, 2, 1)
77 assert restraint.count() > 1
80 @pytest.mark.usefixtures("cleandir")
81 def test_ensemble_potential_nompi(spc_water_box, mdrun_kwargs):
82 """Test ensemble potential without an ensemble.
84 tpr_filename = spc_water_box
85 logger.info("Testing plugin potential with input file {}".format(os.path.abspath(tpr_filename)))
87 assert gmx.version.api_is_at_least(0, 0, 5)
88 md = from_tpr([tpr_filename], append_output=False, **mdrun_kwargs)
90 # Create a WorkElement for the potential
91 params = {'sites': [1, 4],
96 'experimental': [1.] * 10,
98 'sample_period': 0.001,
102 potential = WorkElement(namespace="myplugin",
103 operation="ensemble_restraint",
105 # Note that we could flexibly capture accessor methods as workflow elements, too. Maybe we can
106 # hide the extra Python bindings by letting myplugin.HarmonicRestraint automatically convert
107 # to a WorkElement when add_dependency is called on it.
108 potential.name = "ensemble_restraint"
109 md.add_dependency(potential)
111 context = Context(md)
113 with context as session:
117 @pytest.mark.withmpi_only
118 @pytest.mark.usefixtures("cleandir")
119 def test_ensemble_potential_withmpi(spc_water_box, mdrun_kwargs):
120 tpr_filename = spc_water_box
122 logger.info("Testing plugin potential with input file {}".format(os.path.abspath(tpr_filename)))
124 assert gmx_version.api_is_at_least(0, 0, 5)
125 md = from_tpr([tpr_filename, tpr_filename], append_output=False, **mdrun_kwargs)
127 # Create a WorkElement for the potential
128 params = {'sites': [1, 4],
133 'experimental': [0.5] * 10,
135 'sample_period': 0.001,
140 potential = WorkElement(namespace="myplugin",
141 operation="ensemble_restraint",
143 # Note that we could flexibly capture accessor methods as workflow elements, too. Maybe we can
144 # hide the extra Python bindings by letting myplugin.HarmonicRestraint automatically convert
145 # to a WorkElement when add_dependency is called on it.
146 potential.name = "ensemble_restraint"
147 md.add_dependency(potential)
149 context = Context(md)
150 with context as session: