diff --git a/python/config.cpp b/python/config.cpp index 50fc788e7d3ca23fcd2d23cc38cdbbe3bec0e08e..5b1aa2eb19dfcba36a1413fdaf36ab411dfb63b6 100644 --- a/python/config.cpp +++ b/python/config.cpp @@ -1,9 +1,52 @@ -#include <pybind11/pybind11.h> +#include <arbor/version.hpp> + +#include <sstream> +#include <iomanip> +#include <ios> -#include "config.hpp" +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> namespace pyarb { +// Returns a python dictionary that python users can use to look up +// which options the Arbor library was configured with at compile time. + +pybind11::dict config() { + pybind11::dict dict; +#ifdef ARB_MPI_ENABLED + dict[pybind11::str("mpi")] = pybind11::bool_(true); +#else + dict[pybind11::str("mpi")] = pybind11::bool_(false); +#endif +#ifdef ARB_WITH_MPI4PY + dict[pybind11::str("mpi4py")] = pybind11::bool_(true); +#else + dict[pybind11::str("mpi4py")] = pybind11::bool_(false); +#endif +#ifdef ARB_WITH_GPU + dict[pybind11::str("gpu")] = pybind11::bool_(true); +#else + dict[pybind11::str("gpu")] = pybind11::bool_(false); +#endif + dict[pybind11::str("version")] = pybind11::str(ARB_VERSION); + return dict; +} + +void print_config(const pybind11::dict &d) { + std::stringstream s; + s << "Arbor's configuration:\n"; + + for (auto x: d) { + s << " " + << std::left << std::setw(7) << x.first << ": " + << std::right << std::setw(10) << x.second << "\n"; + } + + pybind11::print(s.str()); +} + +// Register configuration void register_config(pybind11::module &m) { m.def("config", &config, "Get Arbor's configuration.") diff --git a/python/config.hpp b/python/config.hpp deleted file mode 100644 index 57cf085851374b10f4997035ca2858c8d27a3374..0000000000000000000000000000000000000000 --- a/python/config.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include <arbor/version.hpp> - -#include <sstream> -#include <iomanip> -#include <ios> -#include <pybind11/pybind11.h> -#include <pybind11/stl.h> - -namespace pyarb { - -// Create and return a dictionary -pybind11::dict config() { - pybind11::dict dict; - #ifdef ARB_MPI_ENABLED - dict[pybind11::str("mpi")] = pybind11::bool_(true); - #else - dict[pybind11::str("mpi")] = pybind11::bool_(false); - #endif - #ifdef ARB_WITH_MPI4PY - dict[pybind11::str("mpi4py")] = pybind11::bool_(true); - #else - dict[pybind11::str("mpi4py")] = pybind11::bool_(false); - #endif - #ifdef ARB_WITH_GPU - dict[pybind11::str("gpu")] = pybind11::bool_(true); - #else - dict[pybind11::str("gpu")] = pybind11::bool_(false); - #endif - dict[pybind11::str("version")] = pybind11::str(ARB_VERSION); - return dict; -} - -void print_config(const pybind11::dict &d) { - std::stringstream s; - s << "Arbor's configuration:" << std::endl; - - for (auto x: d) { - s << " " - << std::left << std::setw(7) << x.first << ": " - << std::right << std::setw(10) << x.second << "\n"; - } - - pybind11::print(s.str()); -} -} // namespace pyarb diff --git a/python/mpi.cpp b/python/mpi.cpp index f075575758fb2d963a87be1fee037e6c46639681..b6c14c35d5832a5eebb0b0a5577629303927a9bc 100644 --- a/python/mpi.cpp +++ b/python/mpi.cpp @@ -19,30 +19,6 @@ namespace pyarb { -// Some helper functions to determine how Arbor was compiled -bool mpi_compiled() { - #ifdef ARB_MPI_ENABLED - return true; - #else - return false; - #endif -} - -bool mpi4py_compiled() { - #ifdef ARB_WITH_MPI4PY - return true; - #else - return false; - #endif -} - -void register_queryenvvars(pybind11::module& m) { - using namespace std::string_literals; - - m.def("mpi_compiled", &mpi_compiled, "Check if Arbor was compiled with MPI."); - m.def("mpi4py_compiled", &mpi4py_compiled, "Check if Arbor was compiled with MPI4PY."); -} - #ifdef ARB_MPI_ENABLED #ifdef ARB_WITH_MPI4PY @@ -81,7 +57,7 @@ void mpi_finalize() { int mpi_is_initialized() { int initialized; MPI_Initialized(&initialized); - return initialized; + return initialized; } int mpi_is_finalized() { diff --git a/python/pyarb.cpp b/python/pyarb.cpp index a4a897c556b3b9b5381e670566d3fd4eef8252d1..1b9d11b5f337e4195e38303450be4a29e927cb0e 100644 --- a/python/pyarb.cpp +++ b/python/pyarb.cpp @@ -8,7 +8,6 @@ namespace pyarb { void register_config(pybind11::module& m); void register_contexts(pybind11::module& m); -void register_queryenvvars(pybind11::module& m); #ifdef ARB_MPI_ENABLED void register_mpi(pybind11::module& m); #endif @@ -20,7 +19,6 @@ PYBIND11_MODULE(arbor, m) { pyarb::register_config(m); pyarb::register_contexts(m); - pyarb::register_queryenvvars(m); #ifdef ARB_MPI_ENABLED pyarb::register_mpi(m); #endif diff --git a/python/strings.cpp b/python/strings.cpp index f61e7c76b5c41cb97f4636ce267dfbc7656c1dec..cf0e2c100ab277d09072489d0525f189a713745e 100644 --- a/python/strings.cpp +++ b/python/strings.cpp @@ -12,7 +12,7 @@ std::string context_string(const arb::context& c) { const bool gpu = arb::has_gpu(c); const bool mpi = arb::has_mpi(c); s << "<context: threads " << arb::num_threads(c) - << ", gpu " << (gpu? "yes": "None") + << ", gpu " << (gpu? "yes": "None") << ", distributed " << (mpi? "MPI": "Local") << " ranks " << arb::num_ranks(c) << ">"; diff --git a/python/test/unit/test_contexts.py b/python/test/unit/test_contexts.py index b8c6feff4a7702629ea72866fcd6d87f51daa2ee..5e2389e55236c2b437a661dfa235fadef2077268 100644 --- a/python/test/unit/test_contexts.py +++ b/python/test/unit/test_contexts.py @@ -13,7 +13,7 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../. try: import options except ModuleNotFoundError: - from test import options + from test import options """ all tests for non-distributed arb.context diff --git a/python/test/unit_distributed/runner.py b/python/test/unit_distributed/runner.py index afd1276c8cebfc3d2042fa9b1b139e85a6b2d4de..d17c3655a442e232e19d0e76953f9fbe7e39d877 100644 --- a/python/test/unit_distributed/runner.py +++ b/python/test/unit_distributed/runner.py @@ -41,8 +41,8 @@ def suite(): if __name__ == "__main__": - v = options.parse_arguments().verbosity - + v = options.parse_arguments().verbosity + if not arb.mpi_is_initialized(): print(" Runner initializing mpi") arb.mpi_init() diff --git a/python/test/unit_distributed/test_contexts_arbmpi.py b/python/test/unit_distributed/test_contexts_arbmpi.py index e4fca97024671ff77772852b06bef57ae2bbb9cd..85606170de9d7f23ddb747e67231b3ec48635fbb 100644 --- a/python/test/unit_distributed/test_contexts_arbmpi.py +++ b/python/test/unit_distributed/test_contexts_arbmpi.py @@ -3,6 +3,7 @@ # test_contexts_arbmpi.py import unittest +from collections import namedtuple import arbor as arb @@ -15,34 +16,28 @@ try: except ModuleNotFoundError: from test import options +# check Arbor's configuration of mpi +dict = arb.config() +mpi_check = dict["mpi"] + """ all tests for distributed arb.context using arbor mpi wrappers """ -@unittest.skipIf(arb.mpi_compiled() == False, "MPI not enabled!") +@unittest.skipIf(mpi_check == False, "MPI not enabled!") class Contexts_arbmpi(unittest.TestCase): # Initialize mpi only once in this class (when adding classes move initialization to setUpModule() @classmethod def setUpClass(self): - #print("setUp --- TestContextMPI class") self.local_mpi = False if not arb.mpi_is_initialized(): - #print(" Initializing mpi") arb.mpi_init() self.local_mpi = True - #else: - #print(" mpi already initialized") # Finalize mpi only once in this class (when adding classes move finalization to setUpModule() @classmethod def tearDownClass(self): - #print("tearDown --- TestContextMPI class") - #print(" Finalizing mpi") - #if (arb.mpi4py_compiled() == False and arb.mpi_is_finalized() == False): - if self.local_mpi: - #print(" Finalizing mpi") + if self.local_mpi: arb.mpi_finalize() - #else: - #print(" No finalizing due to further testing with mpi4py") - + def test_initialized_arbmpi(self): self.assertTrue(arb.mpi_is_initialized()) @@ -51,7 +46,6 @@ class Contexts_arbmpi(unittest.TestCase): # test that by default communicator is MPI_COMM_WORLD self.assertEqual(str(comm), '<mpi_comm: MPI_COMM_WORLD>') - #print(comm) # test context with mpi alloc = arb.proc_allocation() @@ -59,7 +53,6 @@ class Contexts_arbmpi(unittest.TestCase): self.assertEqual(ctx.threads, alloc.threads) self.assertTrue(ctx.has_mpi) - #print(ctx) def test_finalized_arbmpi(self): self.assertFalse(arb.mpi_is_finalized()) @@ -71,7 +64,7 @@ def suite(): def run(): v = options.parse_arguments().verbosity - + if not arb.mpi_is_initialized(): arb.mpi_init() @@ -79,7 +72,7 @@ def run(): alloc = arb.proc_allocation() ctx = arb.context(alloc, comm) rank = ctx.rank - + if rank == 0: runner = unittest.TextTestRunner(verbosity = v) else: diff --git a/python/test/unit_distributed/test_contexts_mpi4py.py b/python/test/unit_distributed/test_contexts_mpi4py.py index 0d13c8cd2f5471c8c8eefd2584514b99f471e337..42526079067ea163293f72544dbd0e7e36fcd9c6 100644 --- a/python/test/unit_distributed/test_contexts_mpi4py.py +++ b/python/test/unit_distributed/test_contexts_mpi4py.py @@ -3,6 +3,7 @@ # test_contexts_mpi4py.py import unittest +from collections import namedtuple import arbor as arb @@ -15,14 +16,19 @@ try: except ModuleNotFoundError: from test import options -if (arb.mpi4py_compiled() and arb.mpi_compiled()): +# check Arbor's configuration of mpi +dict = arb.config() +config_mpi = dict["mpi"] +config_mpi4py = dict["mpi4py"] + +if (config_mpi and config_mpi4py): import mpi4py.MPI as mpi """ all tests for distributed arb.context using mpi4py """ # Only test class if env var ARB_WITH_MPI4PY=ON -@unittest.skipIf(arb.mpi_compiled() == False or arb.mpi4py_compiled() == False, "MPI/mpi4py not enabled!") +@unittest.skipIf(config_mpi == False or config_mpi4py == False, "MPI/mpi4py not enabled!") class Contexts_mpi4py(unittest.TestCase): def test_initialize_mpi4py(self): # test mpi initialization (automatically when including mpi4py: https://mpi4py.readthedocs.io/en/stable/mpi4py.run.html) @@ -33,7 +39,6 @@ class Contexts_mpi4py(unittest.TestCase): # test that set communicator is MPI_COMM_WORLD self.assertEqual(str(comm), '<mpi_comm: MPI_COMM_WORLD>') - #print(comm) def test_context_mpi4py(self): comm = arb.mpi_comm_from_mpi4py(mpi.COMM_WORLD) @@ -44,7 +49,6 @@ class Contexts_mpi4py(unittest.TestCase): self.assertEqual(ctx.threads, alloc.threads) self.assertTrue(ctx.has_mpi) - #print(ctx) def test_finalize_mpi4py(self): # test mpi finalization (automatically when including mpi4py, but only just before the Python process terminates) @@ -62,11 +66,11 @@ def run(): alloc = arb.proc_allocation() ctx = arb.context(alloc, comm) rank = ctx.rank - + if rank == 0: runner = unittest.TextTestRunner(verbosity = v) else: - sys.stdout = open(os.devnull, 'w') + sys.stdout = open(os.devnull, 'w') runner = unittest.TextTestRunner(stream=sys.stdout) runner.run(suite())