From 08beb6d51325a609048eeb7501171e4130cecd20 Mon Sep 17 00:00:00 2001 From: Emily Howell Date: Thu, 23 Jan 2025 15:20:58 -0800 Subject: [PATCH] Adding handling for ascent logging actions for MPI and testing --- .../ascent/runtimes/ascent_main_runtime.cpp | 19 +++- src/tests/ascent/t_ascent_logging.cpp | 5 +- .../ascent/t_ascent_mpi_ascent_runtime.cpp | 103 ++++++++++++++++++ 3 files changed, 123 insertions(+), 4 deletions(-) diff --git a/src/libs/ascent/runtimes/ascent_main_runtime.cpp b/src/libs/ascent/runtimes/ascent_main_runtime.cpp index 5bf34e0ad..289f1e052 100644 --- a/src/libs/ascent/runtimes/ascent_main_runtime.cpp +++ b/src/libs/ascent/runtimes/ascent_main_runtime.cpp @@ -1952,9 +1952,24 @@ AscentRuntime::BuildGraph(const conduit::Node &actions) ascent::Logger::instance().set_log_threshold(ascent::Logger::LOG_DEBUG_ID); } - std::string file_pattern = action.has_path("file_pattern") ? + #if defined(ASCENT_MPI_ENABLED) + std::string file_pattern = action.has_path("file_pattern") ? + action["file_pattern"].as_string() : "ascent_log_output_rank_{rank:05d}.yaml"; + + int comm_id = flow::Workspace::default_mpi_comm(); + MPI_Comm mpi_comm = MPI_Comm_f2c(comm_id); + int comm_size = 1; + MPI_Comm_size(mpi_comm, &comm_size); + ASCENT_LOG_OPEN_RANK( file_pattern, m_rank ); + ASCENT_LOG_DEBUG(conduit_fmt::format("mpi info: rank={}, size={}", + m_rank, + comm_size)); + #else + std::string file_pattern = action.has_path("file_pattern") ? action["file_pattern"].as_string() : "ascent_log_output.yaml"; - ASCENT_LOG_OPEN(file_pattern); + ASCENT_LOG_OPEN(file_pattern); + ASCENT_LOG_DEBUG("MPI not enabled"); + #endif } else if(action_name == "flush_log") { diff --git a/src/tests/ascent/t_ascent_logging.cpp b/src/tests/ascent/t_ascent_logging.cpp index faa035b57..f494678e7 100644 --- a/src/tests/ascent/t_ascent_logging.cpp +++ b/src/tests/ascent/t_ascent_logging.cpp @@ -224,9 +224,10 @@ TEST(ascent_logging, test_logging_actions) // check that the log file has the expected number of logs in it (1 open, 3 execution, 1 close) conduit::Node log_file_contents; log_file_contents.load(log_file); - EXPECT_EQ(log_file_contents.number_of_children(), 5); + EXPECT_EQ(log_file_contents.number_of_children(), 6); } +//----------------------------------------------------------------------------- TEST(ascent_logging, test_logging_actions_threshold) { Node n; @@ -307,5 +308,5 @@ TEST(ascent_logging, test_logging_actions_threshold) // check that the log file has the expected number of logs in it (1 open, 3 execution, 1 close) conduit::Node log_file_contents; log_file_contents.load(log_file); - EXPECT_EQ(log_file_contents.number_of_children(), 2); + EXPECT_EQ(log_file_contents.number_of_children(), 3); } diff --git a/src/tests/ascent/t_ascent_mpi_ascent_runtime.cpp b/src/tests/ascent/t_ascent_mpi_ascent_runtime.cpp index 8232b4b1d..3c9992151 100644 --- a/src/tests/ascent/t_ascent_mpi_ascent_runtime.cpp +++ b/src/tests/ascent/t_ascent_mpi_ascent_runtime.cpp @@ -262,6 +262,109 @@ TEST(ascent_mpi_runtime, test_mpi_logs) EXPECT_TRUE(conduit::utils::is_file(log_base + "_c_01.yaml")); } +//----------------------------------------------------------------------------- +TEST(ascent_mpi_runtime, test_logging_actions_mpi) +{ + + Node n; + ascent::about(n); + // only run this test if ascent was built with vtkm support + if(n["runtimes/ascent/vtkm/status"].as_string() == "disabled") + { + ASCENT_INFO("Ascent vtkm support disabled, skipping test"); + return; + } + + // + // Set Up MPI + // + int par_rank; + int par_size; + MPI_Comm comm = MPI_COMM_WORLD; + MPI_Comm_rank(comm, &par_rank); + MPI_Comm_size(comm, &par_size); + + // + // Create an example mesh. + // + Node data, verify_info; + conduit::blueprint::mesh::examples::braid("hexs", + 5, + 5, + 5, + data); + EXPECT_TRUE(conduit::blueprint::mesh::verify(data,verify_info)); + + string output_path = ""; + if(par_rank == 0) + { + output_path = prepare_output_dir(); + } + else + { + output_path = output_dir(); + } + string output_file = conduit::utils::join_file_path(output_path,"tout_logging_render4_"); + string log_base = conduit::utils::join_file_path(output_path,"ascent_action_log_mpi_"); + string log_file = log_base +"{rank:05d}.yaml"; + + // remove old images/log files before rendering + if(par_rank == 0) + { + remove_test_image(output_file); + conduit::utils::remove_path_if_exists(log_base + "00000.yaml"); + } + + conduit::Node actions; + conduit::Node &add_scenes= actions.append(); + add_scenes["action"] = "add_scenes"; + conduit::Node &scenes = add_scenes["scenes"]; + scenes["s1/plots/p1/type"] = "pseudocolor"; + scenes["s1/plots/p1/field"] = "braid"; + scenes["s1/image_prefix"] = output_file; + + conduit::Node actions_begin_logs; + conduit::Node &begin_logs= actions_begin_logs.append(); + begin_logs["action"] = "open_log"; + begin_logs["file_pattern"] = log_file; + begin_logs["log_threshold"] = "all"; + + conduit::Node actions_flush_logs; + conduit::Node &flush_logs= actions_flush_logs.append(); + flush_logs["action"] = "flush_log"; + + conduit::Node actions_close_logs; + conduit::Node &close_logs= actions_close_logs.append(); + close_logs["action"] = "close_log"; + + // + // Run Ascent + // + + Ascent ascent; + + Node ascent_opts; + ascent_opts["mpi_comm"] = MPI_Comm_c2f(comm); + ascent_opts["runtime"] = "ascent"; + ascent.open(ascent_opts); + + ascent.publish(data); + ascent.execute(actions_begin_logs); + ascent.execute(actions); + ascent.execute(actions_flush_logs); + ascent.execute(actions_close_logs); + ascent.close(); + + // check that the log file exists + MPI_Barrier(comm); + EXPECT_TRUE(conduit::utils::is_file(log_base + "00000.yaml")); + + // check that the log file has the expected number of logs in it (1 open, 3 execution, 1 close) + conduit::Node log_file_contents; + log_file_contents.load(log_base + "00000.yaml"); + EXPECT_EQ(log_file_contents.number_of_children(), 6); +} + //----------------------------------------------------------------------------- int main(int argc, char* argv[])