From 3a33f6f2eb631c44d24d4ac3d6324235001ae412 Mon Sep 17 00:00:00 2001 From: Caleb Schilly Date: Wed, 10 Jul 2024 11:19:12 -0400 Subject: [PATCH] #2175: reorder precedence so args overwrite yaml --- src/vt/configs/arguments/args.cc | 37 ++++++++++++++------ tests/unit/runtime/test_initialization.cc | 42 +++++++++++------------ 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/src/vt/configs/arguments/args.cc b/src/vt/configs/arguments/args.cc index 87bd7c69dd..9a6e9c6b96 100644 --- a/src/vt/configs/arguments/args.cc +++ b/src/vt/configs/arguments/args.cc @@ -268,35 +268,50 @@ std::tuple parseArguments( app.allow_extras(false); // Build string-vector and reverse order to parse (CLI quirk) - std::vector args_to_parse; + std::vector args_to_parse, yaml_input_arg; for (auto it = vt_args.crbegin(); it != vt_args.crend(); ++it) { - args_to_parse.push_back(*it); + if (util::demangle::DemanglerUtils::splitString(*it,'=')[0] == "--vt_input_config_yaml") { + yaml_input_arg.push_back(*it); + } else { + args_to_parse.push_back(*it); + } } // Allow a input config file app.set_config( "--vt_input_config", "", // no default file name - "Read in an ini config file for VT", + "Read in an ini or toml config file for VT", false // not required ); + // Identify input YAML file first, if present + if (!yaml_input_arg.empty()) { + try { + app.parse(yaml_input_arg); + } catch (CLI::Error &ex) { + // Return exit code and message, delaying logic processing of such. + // The default exit code for 'help' is 0. + std::stringstream yaml_message_stream; + int yaml_result = app.exit(ex, yaml_message_stream, yaml_message_stream); + return std::make_tuple(yaml_result, yaml_message_stream.str()); + } + } + + // Parse the YAML parameters + if (appConfig.vt_input_config_yaml != "") { + parseYaml(appConfig, appConfig.vt_input_config_yaml); + } + + // Then parse the remaining arguments try { app.parse(args_to_parse); } catch (CLI::Error &ex) { - // Return exit code and message, delaying logic processing of such. - // The default exit code for 'help' is 0. std::stringstream message_stream; int result = app.exit(ex, message_stream, message_stream); - return std::make_tuple(result, message_stream.str()); } - // YAML input will overwrite command line arguments - if (appConfig.vt_input_config_yaml != "") { - parseYaml(appConfig, appConfig.vt_input_config_yaml); - } - // If the user specified to output the full configuration, save it in a string // so node 0 can output in the runtime once MPI is init'ed if (appConfig.vt_output_config) { diff --git a/tests/unit/runtime/test_initialization.cc b/tests/unit/runtime/test_initialization.cc index d79cfe1ab8..172905b3a1 100644 --- a/tests/unit/runtime/test_initialization.cc +++ b/tests/unit/runtime/test_initialization.cc @@ -586,7 +586,7 @@ TEST_F(TestInitialization, test_initialize_without_restart_reader) { TEST_F(TestInitialization, test_initialize_with_lb_data_in) { MPI_Comm comm = MPI_COMM_WORLD; - // Preapre data files + // Prepare data files auto prefix = getUniqueFilenameWithRanks(); prepareLBDataFiles(prefix); @@ -619,11 +619,11 @@ TEST_F(TestInitialization, test_initialize_with_lb_data_in) { TEST_F(TestInitialization, test_initialize_with_lb_data_and_config_offline_lb) { MPI_Comm comm = MPI_COMM_WORLD; - // Preapre data files + // Prepare data files auto prefix = getUniqueFilenameWithRanks(); prepareLBDataFiles(prefix); - // Preapre configuration file + // Prepare configuration file std::string file_name = getUniqueFilenameWithRanks(".txt"); std::ofstream out(file_name); out << "0 OfflineLB\n"; @@ -660,11 +660,11 @@ TEST_F(TestInitialization, test_initialize_with_lb_data_and_config_offline_lb) { TEST_F(TestInitialization, test_initialize_with_lb_data_and_no_lb) { MPI_Comm comm = MPI_COMM_WORLD; - // Preapre data files + // Prepare data files auto prefix = getUniqueFilenameWithRanks(); prepareLBDataFiles(prefix); - // Preapre configuration file + // Prepare configuration file std::string file_name = getUniqueFilenameWithRanks(".txt"); std::ofstream out(file_name); out << "0 NoLB\n"; @@ -701,7 +701,7 @@ TEST_F(TestInitialization, test_initialize_with_lb_data_and_no_lb) { TEST_F(TestInitialization, test_initialize_with_lb_data_and_offline_lb) { MPI_Comm comm = MPI_COMM_WORLD; - // Preapre data files + // Prepare data files auto prefix = getUniqueFilenameWithRanks(); prepareLBDataFiles(prefix); @@ -737,11 +737,11 @@ TEST_F(TestInitialization, test_initialize_with_lb_data_and_offline_lb) { TEST_F(TestInitialization, test_initialize_with_lb_data_and_config_no_lb) { MPI_Comm comm = MPI_COMM_WORLD; - // Preapre data files + // Prepare data files auto prefix = getUniqueFilenameWithRanks(); prepareLBDataFiles(prefix); - // Preapre configuration file + // Prepare configuration file std::string file_name = getUniqueFilenameWithRanks(".txt"); std::ofstream out(file_name); out << "0 NoLB\n"; @@ -780,15 +780,11 @@ TEST_F(TestInitialization, test_initialize_with_yaml_toml_and_args) { // Set command line arguments static char prog_name[]{"vt_program"}; - static char vt_color[]{"--vt_color"}; - static char vt_no_terminate[]{"--vt_no_terminate"}; - static char vt_lb_name[]{"--vt_lb_name=RotateLB"}; + static char vt_debug_level[]{"--vt_debug_level=verbose"}; std::vector custom_args; custom_args.emplace_back(prog_name); - custom_args.emplace_back(vt_color); - custom_args.emplace_back(vt_lb_name); - custom_args.emplace_back(vt_no_terminate); + custom_args.emplace_back(vt_debug_level); // Set TOML config file std::string toml_config_file(getUniqueFilenameWithRanks(".toml")); @@ -802,9 +798,8 @@ TEST_F(TestInitialization, test_initialize_with_yaml_toml_and_args) { if (this_rank == 0) { std::ofstream toml_cfg_file_{toml_config_file.c_str(), std::ofstream::out | std::ofstream::trunc}; - toml_cfg_file_ << "vt_lb_name = RandomLB\n" - << "vt_color = False\n" - << "vt_quiet = True"; + toml_cfg_file_ << "vt_debug_level = terse\n" + << "vt_color = False"; toml_cfg_file_.close(); } MPI_Barrier(comm); @@ -823,8 +818,11 @@ TEST_F(TestInitialization, test_initialize_with_yaml_toml_and_args) { if (this_rank == 0) { std::ofstream yaml_cfg_file_{yaml_config_file.c_str(), std::ofstream::out | std::ofstream::trunc}; yaml_cfg_file_ << R"( - Load Balancing: - Name: NoLB + Output Control: + Color: True + Quiet: True + Debug Print Configuration: + Level: normal )"; yaml_cfg_file_.close(); } @@ -836,9 +834,9 @@ TEST_F(TestInitialization, test_initialize_with_yaml_toml_and_args) { // Test that everything was read in correctly EXPECT_EQ(theConfig()->prog_name, "vt_program"); - EXPECT_EQ(theConfig()->vt_quiet, true); // Original TOML - EXPECT_EQ(theConfig()->vt_color, true); // CLI overwrote TOML - EXPECT_EQ(theConfig()->vt_lb_name, "NoLB"); // YAML overwrote everything + EXPECT_EQ(theConfig()->vt_quiet, true); // yaml + EXPECT_EQ(theConfig()->vt_color, false); // toml overwrites yaml + EXPECT_EQ(theConfig()->vt_debug_level, "verbose"); // args overwrites everything } }}} // end namespace vt::tests::unit