mpinoseutils -- Utilities for using nose and mpi4py together
What you need is included in the module
__init__.py is provided in case you want to use
to make this a sub-package of your own projects. Distribution with
your own projects is encouraged at this time, perhaps once the project
is mature it can become a dependency instead.
Write tests like this:
from mpinoseutils import * @mpitest(4) # argument is number of ranks needed for test def test_demo(comm): assert comm.Get_size() == 4 # meq_: Different expected result for each rank meq_(comm, [0, 1, 2, 3], comm.Get_rank()) allranks = comm.allgather(comm.Get_rank()) # mprint: collective non-garbled printing mprint(comm, 'allranks == ', allranks) assert_eq_across_ranks(comm, allranks)
Running in non-collective mode
Run the test with
nosetests as usual. When the test is run, the
decorator will spawn MPI subprocesses using
communicate with rank 0 using ZeroMQ in order to execute the function
and report the results.
For each module containing tests, a new, isolated set of MPI processes are spawned. The workers are reused for all tests in a test module.
Running in collective mode
Alternatively, by using
you can run all the MPI processes through all the tests:
mpiexec -np 10 python runtests.py [args-to-nose]
The number of ranks should be the maximum of the ranks needed in
individual tests (i.e., the
@mpitest decorator creates a
sub-communicator with the right number of ranks).
runtests.py rather than
nosetests will silence nose
printing from every rank but the 0-rank. After each
@mpitest-decorated test has run, the results are gathered
to rank 0, which will raise errors on behalf of the other ranks.
Test fixtures (
teardown() etc.) are not supported yet;
they may work accidentally but it's not tested. Module initialization
code should be run once per test module per process.