diff --git a/src/vt/configs/debug/debug_colorize.h b/src/vt/configs/debug/debug_colorize.h index d757aefbe3..bce25ab4d5 100644 --- a/src/vt/configs/debug/debug_colorize.h +++ b/src/vt/configs/debug/debug_colorize.h @@ -49,16 +49,14 @@ #include -namespace vt { namespace config { - -inline arguments::AppConfig const* getConfig(); - -}} /* end namespace vt::config */ +namespace vt { namespace debug { +arguments::AppConfig const* preConfig(); +}} /* end namespace vt::debug */ namespace vt { namespace debug { inline bool colorizeOutput() { - return vt::config::getConfig()->colorize_output; + return vt::debug::preConfig()->colorize_output; } inline std::string green() { return colorizeOutput() ? "\033[32m" : ""; } @@ -87,16 +85,6 @@ inline std::string proc(vt::NodeType const& node) { return blue() + "[" + std::to_string(node) + "]" + reset(); } -// static bool ttyi(FILE* stream) { -// struct stat stream_stat; -// if (fstat(fileno(stream), &stream_stat) == 0) { -// if (stream_stat.st_mode & S_IFREG) { -// return true; -// } -// } -// return false; -// } - }} /* end namespace vt::debug */ #endif /*INCLUDED_VT_CONFIGS_DEBUG_DEBUG_COLORIZE_H*/ diff --git a/src/vt/configs/debug/debug_print.h b/src/vt/configs/debug/debug_print.h index f314be96ed..54e69c1580 100644 --- a/src/vt/configs/debug/debug_print.h +++ b/src/vt/configs/debug/debug_print.h @@ -82,10 +82,8 @@ #define vt_proc_print_colorize(proc) \ vt_print_colorize_impl(::vt::debug::blue(), "[" + std::to_string(proc) + "]", "") -#define vt_debug_argument_option(opt) \ - ::vt::config::getConfig()->vt_debug_ ## opt - -#define vt_debug_all_option ::vt::config::getConfig()->vt_debug_all +#define vt_debug_argument_option(opt) \ + ::vt::debug::preConfig()->vt_debug_ ## opt #define vt_debug_print_impl(force, inconfig, inmode, cat, ctx, ...) \ vt::config::ApplyOp< \ @@ -140,7 +138,7 @@ #define vt_print(feature, ...) \ do { \ - if (!::vt::config::getConfig()->vt_quiet) { \ + if (!::vt::debug::preConfig()->vt_quiet) { \ vt_print_force_impl(feature, node, __VA_ARGS__); \ } \ } while(0); @@ -148,26 +146,7 @@ #define vt_option_check_enabled(mode, bit) ((mode & bit) not_eq 0) namespace vt { namespace runtime { - struct Runtime; - -/** - * \brief Test if the runtime configuration is available at this point in - * startup. Convenience function for use in debug printing without including VT - * runtime headers. - * - * \return whether `theConfig()` is available - */ -bool configLive(); - -/** - * \brief Get the runtime config before VT is fully initialized. Convenience - * function for use in debug printing without including VT runtime headers. - * - * \return the app config - */ -arguments::AppConfig const* getRuntimeConfig(); - }} /* end namespace vt::runtime */ namespace vt { @@ -175,29 +154,19 @@ extern runtime::Runtime* curRT; } /* end namespace vt */ namespace vt { namespace debug { +arguments::AppConfig const* preConfig(); NodeType preNode(); }} /* end namespace vt::debug */ namespace vt { namespace config { -/** - * \brief Get the app configuration safely even during startup/shutdown. This - * function will always return a valid pointer if the VT runtime is live even - * when components are not initialized; - * - * \return the app config - */ -inline arguments::AppConfig const* getConfig() { - return runtime::configLive() ? vt::theConfig() : runtime::getRuntimeConfig(); -} - template struct DebugPrintOp; template static inline void debugPrintImpl(NodeType node, Arg&& arg, Args&&... args) { bool const verb = vt_option_check_enabled(mod, ModeEnum::verbose); - if ((verb and getConfig()->vt_debug_verbose) or not verb) { + if ((verb and vt::debug::preConfig()->vt_debug_verbose) or not verb) { auto user = fmt::format(std::forward(arg),std::forward(args)...); fmt::print( "{} {} {} {}", @@ -206,7 +175,7 @@ static inline void debugPrintImpl(NodeType node, Arg&& arg, Args&&... args) { vt_print_colorize_impl(::vt::debug::green(), PrettyPrintCat::print(), ":"), user ); - if (vt_option_check_enabled(mod, ModeEnum::flush) or getConfig()->alwaysFlush()) { + if (vt_option_check_enabled(mod, ModeEnum::flush) or vt::debug::preConfig()->alwaysFlush()) { fflush(stdout); } } @@ -216,7 +185,7 @@ template struct DebugPrintOp { template void operator()(bool const rt_option, Arg&& arg, Args&&... args) { - if (rt_option or getConfig()->vt_debug_all) { + if (rt_option or vt::debug::preConfig()->vt_debug_all) { auto no_node = static_cast(-1); auto node = vt::curRT != nullptr ? vt::debug::preNode() : no_node; debugPrintImpl(node,std::forward(arg),std::forward(args)...); @@ -228,7 +197,7 @@ template struct DebugPrintOp { template void operator()(bool const rt_option, Arg&& arg, Args&&... args) { - if (rt_option or getConfig()->vt_debug_all) { + if (rt_option or vt::debug::preConfig()->vt_debug_all) { debugPrintImpl(-1,std::forward(arg),std::forward(args)...); } } diff --git a/src/vt/runtime/runtime_get.cc b/src/vt/runtime/runtime_get.cc index 58fc6bf1c2..d49f798854 100644 --- a/src/vt/runtime/runtime_get.cc +++ b/src/vt/runtime/runtime_get.cc @@ -142,33 +142,32 @@ trace::Trace* theTrace() { return CUR_RT->theTrace; pmpi::PMPIComponent* thePMPI() { return CUR_RT->thePMPI; } #endif -namespace runtime { +#undef CUR_RT +#undef CUR_RT_SAFE +#undef IS_COMM_THREAD -/** - * \brief Test if the runtime configuration is available at this point in - * startup. Convenience function for use in debug printing without including VT - * runtime headers. - * - * \return whether `theConfig()` is available - */ -bool configLive() { - return curRT->theArgConfig != nullptr; -} +} /* end namespace vt */ + +namespace vt { namespace debug { + +// Dummy config that applies outside of RT initialization, much like preNode. +static arguments::AppConfig preInitAppConfig{}; /** - * \brief Get the runtime config before VT is fully initialized. Convenience - * function for use in debug printing without including VT runtime headers. + * \internal + * \brief Returns the config, accessible OUTSIDE of VT initialization. + * + * Much as preNode, this can be accessed safely in debug* methods. + * This allows such methods to be used in code that is unit-test OK. * - * \return the app config + * \return A configuration; possible a default configuration. */ -arguments::AppConfig const* getRuntimeConfig() { - return curRT->getAppConfig(); +arguments::AppConfig const* preConfig() { + auto const rt = curRT; + if (not rt) + return &preInitAppConfig; + auto const* config = rt->theArgConfig; + return config not_eq nullptr ? &config->config_ : rt->getAppConfig(); } -} /* end namespace runtime */ - -#undef CUR_RT -#undef CUR_RT_SAFE -#undef IS_COMM_THREAD - -} /* end namespace vt */ +}} /* end namespace vt::debug */ diff --git a/src/vt/vrt/collection/balance/baselb/baselb.cc b/src/vt/vrt/collection/balance/baselb/baselb.cc index 54fe2b8941..152777dda7 100644 --- a/src/vt/vrt/collection/balance/baselb/baselb.cc +++ b/src/vt/vrt/collection/balance/baselb/baselb.cc @@ -121,7 +121,7 @@ void BaseLB::importProcessorData( void BaseLB::getArgs(PhaseType phase) { using namespace balance; - bool has_spec = ReadLBSpec::hasSpec(); + bool has_spec = ReadLBSpec::openSpec(theConfig()->vt_lb_file_name); if (has_spec) { auto spec = ReadLBSpec::entry(phase); if (spec) { diff --git a/src/vt/vrt/collection/balance/lb_invoke/lb_manager.cc b/src/vt/vrt/collection/balance/lb_invoke/lb_manager.cc index f802b681db..24da652b47 100644 --- a/src/vt/vrt/collection/balance/lb_invoke/lb_manager.cc +++ b/src/vt/vrt/collection/balance/lb_invoke/lb_manager.cc @@ -106,8 +106,9 @@ LBType LBManager::decideLBToRun(PhaseType phase, bool try_file) { return LBType::NoLB; } - if (theConfig()->vt_lb_file_name != "" and try_file) { - bool const has_spec = ReadLBSpec::hasSpec(); + auto& spec_file = theConfig()->vt_lb_file_name; + if (spec_file != "" and try_file) { + bool const has_spec = ReadLBSpec::openSpec(spec_file); if (has_spec) { the_lb = ReadLBSpec::getLB(phase); } diff --git a/src/vt/vrt/collection/balance/read_lb.cc b/src/vt/vrt/collection/balance/read_lb.cc index bc0917e414..39ee0085d2 100644 --- a/src/vt/vrt/collection/balance/read_lb.cc +++ b/src/vt/vrt/collection/balance/read_lb.cc @@ -57,41 +57,44 @@ namespace vt { namespace vrt { namespace collection { namespace balance { -/*static*/ std::string ReadLBSpec::filename = {}; +/*static*/ std::string ReadLBSpec::open_filename_ = {}; /*static*/ typename ReadLBSpec::SpecMapType ReadLBSpec::spec_mod_ = {}; /*static*/ typename ReadLBSpec::SpecMapType ReadLBSpec::spec_exact_ = {}; /*static*/ std::vector ReadLBSpec::spec_prec_ = {}; /*static*/ bool ReadLBSpec::read_complete_ = false; -/*static*/ bool ReadLBSpec::hasSpec() { - if (read_complete_) { - return true; +/*static*/ bool ReadLBSpec::openSpec(std::string const& filename) { + // No-op if no file specified. Can't be used to clear. + if (filename.empty()) { + return false; } - auto const file_name = theConfig()->vt_lb_file_name; - if (file_name == "") { - return false; + // Ignore attempt to open same spec. + if (not open_filename_.empty() and open_filename_ == filename) { + return true; } - bool good = openFile(file_name); - if (not good) { - auto str = - fmt::format("--vt_lb_file_name={} is not a valid file", file_name); + vtAssert( + open_filename_.empty(), + "Spec already opened. Use clear first to load again." + ); + + // Ensure file can be opened. + std::ifstream file(filename); + if (not file.good()) { + auto str = fmt::format("Unable to open spec file: {}", filename); vtAbort(str); } - return good; -} -/*static*/ bool ReadLBSpec::openFile(std::string const name) { - std::ifstream file(name); - filename = name; - return file.good(); + // Remember loaded file - multiple calls to same file are idempotent. + open_filename_ = filename; + + readFile(filename); + + return true; } /*static*/ LBType ReadLBSpec::getLB(SpecIndex const& idx) { - if (not read_complete_) { - readFile(); - } auto const lb = entry(idx); if (lb) { return lb->getLB(); @@ -133,11 +136,7 @@ int eatWhitespace(std::ifstream& file) { return file.eof() ? 0 : file.peek(); } -/*static*/ void ReadLBSpec::readFile() { - if (read_complete_) { - return; - } - +/*static*/ void ReadLBSpec::readFile(std::string const& filename) { std::ifstream file(filename); vtAssert(file.good(), "must be valid"); @@ -245,7 +244,7 @@ int eatWhitespace(std::ifstream& file) { /*static*/ void ReadLBSpec::clear() { read_complete_ = false; - filename = ""; + open_filename_ = ""; spec_mod_.clear(); spec_exact_.clear(); spec_prec_.clear(); @@ -332,8 +331,9 @@ auto excluded_str = [](SpecIndex idx) -> std::string { /*static*/ std::string ReadLBSpec::toString() { std::stringstream ss; - ReadLBSpec::openFile(theConfig()->vt_lb_file_name); - ReadLBSpec::readFile(); + if (open_filename_.empty()) { + return "[No LB Spec open]"; + } if (not ReadLBSpec::getExactEntries().empty()) { ss << fmt::format("{}\tExact specification lines:\n", vt::debug::vtPre()); diff --git a/src/vt/vrt/collection/balance/read_lb.h b/src/vt/vrt/collection/balance/read_lb.h index d7c2602395..182b4e6d5f 100644 --- a/src/vt/vrt/collection/balance/read_lb.h +++ b/src/vt/vrt/collection/balance/read_lb.h @@ -181,10 +181,20 @@ struct ReadLBSpec { using SpecMapType = std::map; using ParamMapType = std::map; - static bool openFile(std::string const name = ""); - static void readFile(); + /** + * \brief Opens and reads the spec file, if it exists. + * + * This method MUST be called before the other access methods. + * + * \param[in] filename The path to the file to read. + * + * \pre A different spec file is not currently open. + * \pre The filename refers to a valid spec file. + * + * \return True if the spec was opened and can be used. + */ + static bool openSpec(std::string const& filename); - static bool hasSpec(); static SpecIndex numEntries() { return spec_mod_.size() + spec_exact_.size(); } static SpecEntry* entry(SpecIndex const& idx); static LBType getLB(SpecIndex const& idx); @@ -192,12 +202,14 @@ struct ReadLBSpec { static SpecMapType getExactEntries() {return spec_exact_; }; static ParamMapType parseParams(std::vector params); static SpecEntry makeSpecFromParams(std::string params); - static void clear(); static std::string toString(); + static void clear(); private: + static void readFile(std::string const& filename); + static bool read_complete_; - static std::string filename; + static std::string open_filename_; static SpecMapType spec_mod_; static SpecMapType spec_exact_; static std::vector spec_prec_; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 30995ca018..f6e3ec9eef 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -91,7 +91,7 @@ function(add_unit_test sub_dir unit_test_file) ) # Extended tests are designated with an particular extension: *.extended.cc - if(UNIT_TEST_FULL_EXTENSION STREQUAL ".extended.cc") + if(UNIT_TEST_FULL_EXTENSION MATCHES "[.]extended[.]") # message( # STATUS "found extended test >>>> ${UNIT_TEST_FULL_EXTENSION}" # ) @@ -106,6 +106,13 @@ function(add_unit_test sub_dir unit_test_file) set(UNIT_TEST "${UNIT_TEST}_basic") endif() + # Does this test bypass MPI? + set(USES_MPI ON) + if(UNIT_TEST_FULL_EXTENSION MATCHES "[.]nompi[.]") + set(USES_MPI OFF) + set(UNIT_TEST "${UNIT_TEST}_nompi") + endif() + # message( # STATUS "Building unit test >>>> dir=${sub_dir} test=${UNIT_TEST}, " # "path=${unit_test_file}" @@ -129,23 +136,35 @@ function(add_unit_test sub_dir unit_test_file) LINK_GTEST ON ) - foreach(PROC ${PROC_TEST_LIST}) + if(USES_MPI) + foreach(PROC ${PROC_TEST_LIST}) + gtest_add_tests( + TARGET ${UNIT_TEST} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + TEST_SUFFIX _proc_${PROC} + TEST_PREFIX vt: + TEST_LIST ${CUR_TEST_LIST} + EXECUTE_COMMAND ${MPI_RUN_COMMAND} ${MPI_EXTRA_FLAGS} ${MPI_NUMPROC_FLAG} ${PROC} + ) + + set_tests_properties( + ${${CUR_TEST_LIST}} + PROPERTIES TIMEOUT 60 + FAIL_REGULAR_EXPRESSION "FAILED;should be deleted but never is;Segmentation fault" + PASS_REGULAR_EXPRESSION "PASSED" + ) + endforeach() + else() gtest_add_tests( TARGET ${UNIT_TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - TEST_SUFFIX _proc_${PROC} + TEST_SUFFIX _no_mpi TEST_PREFIX vt: TEST_LIST ${CUR_TEST_LIST} - EXECUTE_COMMAND ${MPI_RUN_COMMAND} ${MPI_EXTRA_FLAGS} ${MPI_NUMPROC_FLAG} ${PROC} + EXECUTE_COMMAND ${PROC} ) + endif() - set_tests_properties( - ${${CUR_TEST_LIST}} - PROPERTIES TIMEOUT 60 - FAIL_REGULAR_EXPRESSION "FAILED;should be deleted but never is;Segmentation fault" - PASS_REGULAR_EXPRESSION "PASSED" - ) - endforeach() endfunction() # diff --git a/tests/unit/context/context_vrt_test.extended.cc b/tests/unit/context/context_vrt_test.nompi.extended.cc similarity index 100% rename from tests/unit/context/context_vrt_test.extended.cc rename to tests/unit/context/context_vrt_test.nompi.extended.cc diff --git a/tests/unit/context/context_vrtproxy_test.extended.cc b/tests/unit/context/context_vrtproxy_test.nompi.extended.cc similarity index 100% rename from tests/unit/context/context_vrtproxy_test.extended.cc rename to tests/unit/context/context_vrtproxy_test.nompi.extended.cc diff --git a/tests/unit/epoch/test_epoch.cc b/tests/unit/epoch/test_epoch.nompi.cc similarity index 100% rename from tests/unit/epoch/test_epoch.cc rename to tests/unit/epoch/test_epoch.nompi.cc diff --git a/tests/unit/index/test_index.cc b/tests/unit/index/test_index.nompi.cc similarity index 100% rename from tests/unit/index/test_index.cc rename to tests/unit/index/test_index.nompi.cc diff --git a/tests/unit/index/test_index_linearization.cc b/tests/unit/index/test_index_linearization.nompi.cc similarity index 100% rename from tests/unit/index/test_index_linearization.cc rename to tests/unit/index/test_index_linearization.nompi.cc diff --git a/tests/unit/lb/test_lb_reader.cc b/tests/unit/lb/test_lb_reader.nompi.cc similarity index 96% rename from tests/unit/lb/test_lb_reader.cc rename to tests/unit/lb/test_lb_reader.nompi.cc index 66cd4b1050..884e272b3e 100644 --- a/tests/unit/lb/test_lb_reader.cc +++ b/tests/unit/lb/test_lb_reader.nompi.cc @@ -45,11 +45,11 @@ #include #include -#include "test_parallel_harness.h" +#include "test_harness.h" namespace vt { namespace tests { namespace unit { -using TestLBReader = TestParallelHarness; +using TestLBReader = TestHarness; TEST_F(TestLBReader, test_lb_read_1) { @@ -64,9 +64,9 @@ TEST_F(TestLBReader, test_lb_read_1) { using Spec = vt::vrt::collection::balance::ReadLBSpec; using SpecIdx = vt::vrt::collection::balance::SpecIndex; using SpecLBType = vt::vrt::collection::balance::LBType; + Spec::clear(); - EXPECT_EQ(Spec::openFile(file_name), true); - Spec::readFile(); + Spec::openSpec(file_name); EXPECT_EQ(Spec::numEntries(), 3); EXPECT_EQ(Spec::getExactEntries().size(), 2); @@ -95,7 +95,6 @@ TEST_F(TestLBReader, test_lb_read_1) { } } - theConfig()->colorize_output = false; std::string expected_spec = "vt: \tExact specification lines:\n" "vt: \tRun `NoLB` on phase 0\n" @@ -121,8 +120,7 @@ TEST_F(TestLBReader, test_lb_read_2) { using SpecIdx = vt::vrt::collection::balance::SpecIndex; using SpecLBType = vt::vrt::collection::balance::LBType; Spec::clear(); - Spec::openFile(file_name); - Spec::readFile(); + Spec::openSpec(file_name); EXPECT_EQ(Spec::numEntries(), 5); for (SpecIdx i = 0; i < 121; i++) { @@ -188,7 +186,6 @@ TEST_F(TestLBReader, test_lb_read_2) { } } - theConfig()->colorize_output = false; std::string expected_spec = "vt: \tExact specification lines:\n" "vt: \tRun `NoLB` on phase 0\n" diff --git a/tests/unit/mapping/test_mapping.cc b/tests/unit/mapping/test_mapping.nompi.cc similarity index 100% rename from tests/unit/mapping/test_mapping.cc rename to tests/unit/mapping/test_mapping.nompi.cc diff --git a/tests/unit/tls/test_tls.cc b/tests/unit/tls/test_tls.nompi.cc similarity index 100% rename from tests/unit/tls/test_tls.cc rename to tests/unit/tls/test_tls.nompi.cc diff --git a/tests/unit/utils/test_demangler_utils.cc b/tests/unit/utils/test_demangler_utils.nompi.cc similarity index 100% rename from tests/unit/utils/test_demangler_utils.cc rename to tests/unit/utils/test_demangler_utils.nompi.cc diff --git a/tests/unit/utils/test_histogram_approx.cc b/tests/unit/utils/test_histogram_approx.nompi.cc similarity index 100% rename from tests/unit/utils/test_histogram_approx.cc rename to tests/unit/utils/test_histogram_approx.nompi.cc diff --git a/tests/unit/utils/test_linear_regression.cc b/tests/unit/utils/test_linear_regression.nompi.cc similarity index 100% rename from tests/unit/utils/test_linear_regression.cc rename to tests/unit/utils/test_linear_regression.nompi.cc diff --git a/tests/unit/utils/test_safe_union.cc b/tests/unit/utils/test_safe_union.nompi.cc similarity index 100% rename from tests/unit/utils/test_safe_union.cc rename to tests/unit/utils/test_safe_union.nompi.cc