diff --git a/tests/unit/main.cc b/tests/unit/main.cc index 117a3f8448..cdc515174a 100644 --- a/tests/unit/main.cc +++ b/tests/unit/main.cc @@ -42,6 +42,7 @@ */ #include +#include #include "test_harness.h" @@ -72,5 +73,14 @@ int main(int argc, char** argv) { TestHarness::store_cmdline_args(test_argc, test_argv); - return RUN_ALL_TESTS(); + auto ret = RUN_ALL_TESTS(); + + // if this was a parallel test, finalize MPI + int init = 0; + MPI_Initialized(&init); + if (init) { + MPI_Finalize(); + } + + return ret; } diff --git a/tests/unit/mpi_singleton.h b/tests/unit/mpi_singleton.h deleted file mode 100644 index 96eed1d08c..0000000000 --- a/tests/unit/mpi_singleton.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// mpi_singleton.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_UNIT_MPI_SINGLETON_H -#define INCLUDED_UNIT_MPI_SINGLETON_H - -#include -#include - -namespace vt { namespace tests { namespace unit { - -extern int test_argc; -extern char** test_argv; - -/* - * gtest runs many tests in the same binary, but there is no way to know when - * to call MPI_Finalize, which can only be called once (when it's called - * MPI_Init can't be called again)! This singleton uses static initialization - * to init/finalize exactly once - */ -struct MPISingletonMultiTest { - MPISingletonMultiTest(int& argc, char**& argv) { - MPI_Init(&argc, &argv); - comm_ = MPI_COMM_WORLD; - - MPI_Comm_size(comm_, &num_ranks_); - MPI_Barrier(comm_); - } - - virtual ~MPISingletonMultiTest() { - MPI_Barrier(comm_); - MPI_Finalize(); - } - -public: - static MPISingletonMultiTest* Get() { - static std::unique_ptr mpi_singleton = nullptr; - - if (!mpi_singleton) { - mpi_singleton = - std::make_unique(test_argc, test_argv); - } - - return mpi_singleton.get(); - } - - MPI_Comm getComm() { return comm_; } - int getNumRanks() { return num_ranks_; } - -private: - MPI_Comm comm_; - int num_ranks_; -}; - -}}} // namespace vt::tests::unit - -#endif /* INCLUDED_UNIT_MPI_SINGLETON_H */ diff --git a/tests/unit/runtime/test_initialization.cc b/tests/unit/runtime/test_initialization.cc index 29eca73dc2..6ab4899e3e 100644 --- a/tests/unit/runtime/test_initialization.cc +++ b/tests/unit/runtime/test_initialization.cc @@ -54,7 +54,7 @@ namespace vt { namespace tests { namespace unit { struct TestInitialization : TestParallelHarness { }; TEST_F(TestInitialization, test_initialize_with_args) { - MPI_Comm comm = MPISingletonMultiTest::Get()->getComm(); + MPI_Comm comm = MPI_COMM_WORLD; static char prog_name[]{"vt_program"}; static char cli_argument[]{"--cli_argument=100"}; @@ -83,7 +83,7 @@ TEST_F(TestInitialization, test_initialize_with_args) { } TEST_F(TestInitialization, test_initialize_with_appconfig) { - MPI_Comm comm = MPISingletonMultiTest::Get()->getComm(); + MPI_Comm comm = MPI_COMM_WORLD; static char prog_name[]{"vt_program"}; static char cli_argument[]{"--cli_argument=100"}; @@ -120,7 +120,7 @@ TEST_F(TestInitialization, test_initialize_with_appconfig) { } TEST_F(TestInitialization, test_initialize_with_args_and_appconfig) { - MPI_Comm comm = MPISingletonMultiTest::Get()->getComm(); + MPI_Comm comm = MPI_COMM_WORLD; static char prog_name[]{"vt_program"}; static char cli_argument[]{"--cli_argument=100"}; @@ -164,7 +164,7 @@ TEST_F(TestInitialization, test_initialize_with_args_and_appconfig) { } TEST_F(TestInitialization, test_initialize_with_file_and_args) { - MPI_Comm comm = MPISingletonMultiTest::Get()->getComm(); + MPI_Comm comm = MPI_COMM_WORLD; static char prog_name[]{"vt_program"}; static char cli_argument[]{"--cli_argument=100"}; @@ -207,7 +207,7 @@ TEST_F(TestInitialization, test_initialize_with_file_and_args) { } TEST_F(TestInitialization, test_initialize_with_file_args_and_appconfig) { - MPI_Comm comm = MPISingletonMultiTest::Get()->getComm(); + MPI_Comm comm = MPI_COMM_WORLD; static char prog_name[]{"vt_program"}; static char cli_argument[]{"--cli_argument=100"}; diff --git a/tests/unit/test_helpers.h b/tests/unit/test_helpers.h index b27e3a8aea..9fc1e422ed 100644 --- a/tests/unit/test_helpers.h +++ b/tests/unit/test_helpers.h @@ -44,12 +44,15 @@ #if !defined INCLUDED_UNIT_TEST_HELPERS_H #define INCLUDED_UNIT_TEST_HELPERS_H -#include "mpi_singleton.h" #include "vt/context/context.h" +#include #include namespace vt { namespace tests { namespace unit { +extern int test_argc; +extern char** test_argv; + /** * Maximum number of ranks/nodes detected by CMake on this machine. * Defaults to number of processors detected on the host system. @@ -61,7 +64,15 @@ constexpr NodeType CMAKE_DETECTED_MAX_NUM_NODES = vt_detected_max_num_nodes; * This is using MPI because it can be used before vt initializes. */ inline bool isOversubscribed() { - return MPISingletonMultiTest::Get()->getNumRanks() > CMAKE_DETECTED_MAX_NUM_NODES; + // be sure to only call this from parallel tests + int init = 0; + MPI_Initialized(&init); + if (!init) { + MPI_Init(&test_argc, &test_argv); + } + int num_ranks = 0; + MPI_Comm_size(MPI_COMM_WORLD, &num_ranks); + return num_ranks > CMAKE_DETECTED_MAX_NUM_NODES; } /** diff --git a/tests/unit/test_parallel_harness.h b/tests/unit/test_parallel_harness.h index 95319c9624..6c93dc437d 100644 --- a/tests/unit/test_parallel_harness.h +++ b/tests/unit/test_parallel_harness.h @@ -45,10 +45,10 @@ #define INCLUDED_UNIT_TEST_PARALLEL_HARNESS_H #include +#include #include "test_config.h" #include "test_harness.h" -#include "mpi_singleton.h" #include "vt/collective/collective_ops.h" #include "vt/scheduler/scheduler.h" @@ -73,8 +73,13 @@ struct TestParallelHarnessAny : TestHarnessAny { static char throw_on_abort[]{"--vt_throw_on_abort=1"}; addArgs(throw_on_abort); - // communicator is duplicated. - MPI_Comm comm = MPISingletonMultiTest::Get()->getComm(); + // initialize MPI if it hasn't already happened + int init = 0; + MPI_Initialized(&init); + if (!init) { + MPI_Init(&test_argc, &test_argv); + } + MPI_Comm comm = MPI_COMM_WORLD; auto const new_args = injectAdditionalArgs(test_argc, test_argv); auto custom_argc = new_args.first; auto custom_argv = new_args.second; @@ -82,6 +87,7 @@ struct TestParallelHarnessAny : TestHarnessAny { custom_argv[custom_argc] == nullptr, "The value of argv[argc] should always be 0" ); + // communicator is duplicated. CollectiveOps::initialize(custom_argc, custom_argv, no_workers, true, &comm); #if DEBUG_TEST_HARNESS_PRINT