From 816dd8e9348c86729a7bdad0dd03e15403d2bfbf Mon Sep 17 00:00:00 2001 From: Cyrus Harrison Date: Thu, 24 Aug 2023 10:36:10 -0700 Subject: [PATCH 1/7] fix zlib download dir (#1195) --- scripts/build_ascent/build_ascent.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_ascent/build_ascent.sh b/scripts/build_ascent/build_ascent.sh index eb638a322..1b43c9d7b 100755 --- a/scripts/build_ascent/build_ascent.sh +++ b/scripts/build_ascent/build_ascent.sh @@ -169,7 +169,7 @@ if [ ! -d ${zlib_install_dir} ]; then if ${build_zlib}; then if [ ! -d ${zlib_src_dir} ]; then echo "**** Downloading ${zlib_tarball}" - curl -L https://www.zlib.net/zlib-${zlib_version}.tar.gz -o ${zlib_tarball} + curl -L https://github.com/madler/zlib/releases/download/v${zlib_version}/zlib-${zlib_version}.tar.gz -o ${zlib_tarball} tar -xzf ${zlib_tarball} fi From e52b7bb8c9fd131f2fd49edf58037cc5ef77a166 Mon Sep 17 00:00:00 2001 From: Cyrus Harrison Date: Fri, 25 Aug 2023 09:05:31 -0700 Subject: [PATCH 2/7] api and include changes for vtk-m 2.1 (#1194) * api and include changes for vtk-m 2.1 * keep version specific logic --- src/libs/rover/ray_generators/camera_generator.cpp | 3 +++ src/libs/rover/ray_generators/visit_generator.cpp | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/libs/rover/ray_generators/camera_generator.cpp b/src/libs/rover/ray_generators/camera_generator.cpp index 95def9855..e54468df8 100644 --- a/src/libs/rover/ray_generators/camera_generator.cpp +++ b/src/libs/rover/ray_generators/camera_generator.cpp @@ -40,6 +40,9 @@ // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// #include + +#include + namespace rover { CameraGenerator::CameraGenerator() diff --git a/src/libs/rover/ray_generators/visit_generator.cpp b/src/libs/rover/ray_generators/visit_generator.cpp index e6e67390e..bda016027 100644 --- a/src/libs/rover/ray_generators/visit_generator.cpp +++ b/src/libs/rover/ray_generators/visit_generator.cpp @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include namespace rover { @@ -75,7 +77,15 @@ VisitGenerator::gen_rays(vtkmRayTracing::Ray &rays) const int size = m_width * m_height; - rays.Resize(size, vtkm::cont::DeviceAdapterTagSerial()); +#if (VTKM_VERSION_MAJOR >= 2) && (VTKM_VERSION_MINOR >= 1) + vtkm::rendering::raytracing::RayOperations::Resize(rays, + size); +#else + vtkm::rendering::raytracing::RayOperations::Resize(rays, + size, + vtkm::cont::DeviceAdapterTagSerial()); +#endif + vtkm::Vec view_side; From 0aa0f18573cc8cece5d5d56638875cc883bb2182 Mon Sep 17 00:00:00 2001 From: Nicole Date: Fri, 22 Sep 2023 10:52:12 -0600 Subject: [PATCH 3/7] global unique domain id check (#1196) * Add check for domain ID uniqueness --- CHANGELOG.md | 1 + .../ascent/runtimes/ascent_main_runtime.cpp | 147 ++++++++++++++++- src/tests/ascent/CMakeLists.txt | 3 +- src/tests/ascent/t_ascent_mpi_unique_ids.cpp | 149 ++++++++++++++++++ 4 files changed, 296 insertions(+), 4 deletions(-) create mode 100644 src/tests/ascent/t_ascent_mpi_unique_ids.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 33a5d9ac1..caf0cee85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project aspires to adhere to [Semantic Versioning](https://semver.org/s ### Added - Added parameters to control HDF5 compression options to the Relay Extract. +- Added check to make sure all domain IDs are unique ### Changed - Changed the Data Binning filter to accept a `reduction_field` parameter (instead of `var`), and similarly the axis parameters to take `field` (instead of `var`). The `var` style parameters are still accepted, but deprecated and will be removed in a future release. diff --git a/src/libs/ascent/runtimes/ascent_main_runtime.cpp b/src/libs/ascent/runtimes/ascent_main_runtime.cpp index 5fa53f81b..6a2358515 100644 --- a/src/libs/ascent/runtimes/ascent_main_runtime.cpp +++ b/src/libs/ascent/runtimes/ascent_main_runtime.cpp @@ -63,7 +63,6 @@ using namespace conduit; using namespace std; - //----------------------------------------------------------------------------- // -- begin ascent:: -- //----------------------------------------------------------------------------- @@ -553,6 +552,22 @@ AscentRuntime::Publish(const conduit::Node &data) void AscentRuntime::EnsureDomainIds() { + //add debug timing file in case these checks + //add a lot of overhead +#define _DEBUG 0 + +#if _DEBUG + std::stringstream log_name; + std::string log_prefix = "EnsureDomainIDs_times_"; +#ifdef ASCENT_MPI_ENABLED + log_name << log_prefix << m_rank<<".csv"; +#else + log_name << log_prefix << "0.csv"; +#endif + std::ofstream stream; + stream.open(log_name.str().c_str(),std::ofstream::app); + conduit::utils::Timer ensureDomainIDsTimer; +#endif // if no domain ids were provided add them now int num_domains = 0; bool has_ids = true; @@ -573,7 +588,6 @@ AscentRuntime::EnsureDomainIds() } } - #ifdef ASCENT_MPI_ENABLED int comm_id = flow::Workspace::default_mpi_comm(); @@ -616,6 +630,11 @@ AscentRuntime::EnsureDomainIds() } int domain_offset = 0; + +#if _DEBUG + conduit::utils::Timer local_check_timer; +#endif + #ifdef ASCENT_MPI_ENABLED int *domains_per_rank = new int[comm_size]; MPI_Allgather(&num_domains, 1, MPI_INT, domains_per_rank, 1, MPI_INT, mpi_comm); @@ -623,17 +642,139 @@ AscentRuntime::EnsureDomainIds() { domain_offset += domains_per_rank[i]; } + int total_domains = 0; + for(int i = 0; i < comm_size; i++) + { + total_domains += domains_per_rank[i]; + } delete[] domains_per_rank; #endif + + std::unordered_set local_unique_ids; for(int i = 0; i < num_domains; ++i) { conduit::Node &dom = m_source.child(i); if(!dom.has_path("state/domain_id")) { - dom["state/domain_id"] = domain_offset + i; + dom["state/domain_id"] = domain_offset + i; + local_unique_ids.insert(domain_offset + i); + } + else + { + local_unique_ids.insert(dom["state/domain_id"].to_int32()); } } + + int unique_ids = 1; + if(local_unique_ids.size() != num_domains) + { + unique_ids = 0; + } +#ifdef ASCENT_MPI_ENABLED + conduit::Node n_ids; + n_ids.set(DataType::c_int(comm_size)); + int *unique_ids_array = n_ids.value();//new int[comm_size]; + MPI_Allgather(&unique_ids, 1, MPI_INT, unique_ids_array, 1, MPI_INT, mpi_comm); + std::stringstream ss; + for(int i = 0; i < comm_size; i++) + { + if(unique_ids_array[i] == 0) + { + unique_ids = 0; + ss << i << " "; + } + } + + if(!unique_ids) + ASCENT_ERROR("Local Domain IDs are not unique on ranks: " << ss.str()); +#else + if(!unique_ids) + ASCENT_ERROR("Local Domain IDs are not unique "); +#endif +#if _DEBUG + float local_check_timer_time = local_check_timer.elapsed(); + std::stringstream local_check_timer_log; + local_check_timer_log << "Local Uniqueness Check: " << local_check_timer_time << "\n"; + stream << local_check_timer_log.str(); +#endif + + +#ifdef ASCENT_MPI_ENABLED + +#if _DEBUG + conduit::utils::Timer global_check_timer; +#endif + conduit::Node n_dom_ids; + conduit::Node n_global_dom_ids; + conduit::Node n_dom_rank; + conduit::Node n_global_dom_rank; + n_dom_ids.set(DataType::c_int(total_domains)); + n_global_dom_ids.set(DataType::c_int(total_domains)); + n_dom_rank.set(DataType::c_int(total_domains)); + n_global_dom_rank.set(DataType::c_int(total_domains)); + int *domain_ids_per_rank = n_dom_ids.value(); + int *global_domain_ids = n_global_dom_ids.value(); + int *domain_rank = n_dom_rank.value(); + int *global_domain_rank = n_global_dom_rank.value(); + + for(int i = 0; i < total_domains; i++) + { + domain_ids_per_rank[i] = -1; + domain_rank[i] = -1; + } + for(int i = 0; i < num_domains; ++i) + { + conduit::Node &dom = m_source.child(i); + domain_ids_per_rank[domain_offset + i] = dom["state/domain_id"].to_int32(); + domain_rank[domain_offset + i] = m_rank; + } + + MPI_Allreduce(domain_ids_per_rank, global_domain_ids, total_domains, MPI_INT, MPI_MAX, mpi_comm); + MPI_Allreduce(domain_rank, global_domain_rank, total_domains, MPI_INT, MPI_MAX, mpi_comm); + + std::unordered_set global_ids; + for(int i = 0; i < total_domains; i++) + { + global_ids.insert(global_domain_ids[i]); + } + + if(global_ids.size() != total_domains) + { + std::map> map_global_ids; + for(int i = 0; i < total_domains; i++) + { + map_global_ids[global_domain_ids[i]].push_back(global_domain_rank[i]); + } + for(auto itr = map_global_ids.begin(); itr != map_global_ids.end(); ++itr) + { + if(itr->second.size() > 1) + { + ss << "domain: " << itr->first << " on ranks: "; + for(auto iitr = itr->second.begin(); iitr != itr->second.end(); ++iitr) + { + ss << *iitr << " "; + } + ss << "\n"; + } + } + ASCENT_ERROR("Global Domain IDs are not unique for " << ss.str()); + } +#if _DEBUG + float global_check_timer_time = global_check_timer.elapsed(); + std::stringstream global_check_timer_log; + global_check_timer_log << "Global Uniqueness Check: " << global_check_timer_time << "\n"; + stream << global_check_timer_log.str(); +#endif +#endif + +#if _DEBUG + float ensureDomainIDs_time = ensureDomainIDsTimer.elapsed(); + std::stringstream ensureDomainIDs_log; + ensureDomainIDs_log << "AscentRuntime::EnsureDomainIDs [TOTAL]: " << ensureDomainIDs_time << "\n"; + stream << ensureDomainIDs_log.str(); + stream.close(); +#endif } //----------------------------------------------------------------------------- diff --git a/src/tests/ascent/CMakeLists.txt b/src/tests/ascent/CMakeLists.txt index 41e53bd95..58a00f8c8 100644 --- a/src/tests/ascent/CMakeLists.txt +++ b/src/tests/ascent/CMakeLists.txt @@ -90,7 +90,8 @@ set(MPI_TESTS t_ascent_mpi_smoke t_ascent_mpi_render_3d t_ascent_mpi_statistics t_ascent_mpi_multi_topo - t_ascent_mpi_slice) + t_ascent_mpi_slice + t_ascent_mpi_unique_ids) # t_ascent_hola_mpi uses 8 mpi tasks, so its added manually # same for t_ascent_babelflow_pmt_mpi and t_ascent_babelflow_comp_mpi diff --git a/src/tests/ascent/t_ascent_mpi_unique_ids.cpp b/src/tests/ascent/t_ascent_mpi_unique_ids.cpp new file mode 100644 index 000000000..05557db66 --- /dev/null +++ b/src/tests/ascent/t_ascent_mpi_unique_ids.cpp @@ -0,0 +1,149 @@ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Copyright (c) Lawrence Livermore National Security, LLC and other Ascent +// Project developers. See top-level LICENSE AND COPYRIGHT files for dates and +// other details. No copyright assignment is required to contribute to Ascent. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + +//----------------------------------------------------------------------------- +/// +/// file: t_ascent_partition.cpp +/// +//----------------------------------------------------------------------------- + + +#include "gtest/gtest.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "t_config.hpp" +#include "t_utils.hpp" + + +using namespace std; +using namespace conduit; +using namespace ascent; + +//----------------------------------------------------------------------------- +TEST(ascent_partition, test_indiv_rank_non_unique) +{ + Node n; + ascent::about(n); + + // + // Create an example mesh. + // + Node data, verify_info; + + // + //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); + + // use spiral , with 20 domains + conduit::blueprint::mpi::mesh::examples::spiral_round_robin(20,data,comm); + + EXPECT_TRUE(conduit::blueprint::mesh::verify(data,verify_info)); + + int root = 0; + if(par_rank == root) + ASCENT_INFO("Testing local non unique IDs"); + + int num_domains = data.number_of_children(); + for(int i = 0; i < num_domains; i++) + { + conduit::Node &dom = data.child(i); + dom["state/domain_id"] = 0; + } + + // + // Run Ascent + // + + Ascent ascent; + + Node ascent_opts; + ascent_opts["runtime"] = "ascent"; + ascent_opts["mpi_comm"] = MPI_Comm_c2f(comm); + ascent_opts["exceptions"] = "forward"; + ascent.open(ascent_opts); + + EXPECT_THROW(ascent.publish(data),conduit::Error); +} +//----------------------------------------------------------------------------- +TEST(ascent_partition, test_global_ranks_non_unique) +{ + Node n; + ascent::about(n); + + // + // Create an example mesh. + // + Node data, verify_info; + + // + //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); + + // use spiral , with 20 domains + conduit::blueprint::mpi::mesh::examples::spiral_round_robin(20,data,comm); + + EXPECT_TRUE(conduit::blueprint::mesh::verify(data,verify_info)); + + int root = 0; + if(par_rank == root) + ASCENT_INFO("Testing global non unique IDs"); + + int num_domains = data.number_of_children(); + for(int i = 0; i < num_domains; i++) + { + conduit::Node &dom = data.child(i); + dom["state/domain_id"] = i; + } + + // + // Run Ascent + // + + Ascent ascent; + + Node ascent_opts; + ascent_opts["runtime"] = "ascent"; + ascent_opts["mpi_comm"] = MPI_Comm_c2f(comm); + ascent_opts["exceptions"] = "forward"; + ascent.open(ascent_opts); + + EXPECT_THROW(ascent.publish(data),conduit::Error); +} + +//----------------------------------------------------------------------------- +int main(int argc, char* argv[]) +{ + int result = 0; + + ::testing::InitGoogleTest(&argc, argv); + MPI_Init(&argc, &argv); + + result = RUN_ALL_TESTS(); + MPI_Finalize(); + return result; +} + + From 883aef9525b9f83cf025748c6685814912d563bf Mon Sep 17 00:00:00 2001 From: Will Trojak Date: Thu, 5 Oct 2023 19:09:50 +0100 Subject: [PATCH 4/7] Added generalisation of png metadata handler (#1199) * Added generialisation of png metadata handler * Added check allowing any domain to set metadata --- .../ascent/runtimes/ascent_main_runtime.cpp | 61 +++++++++---------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/src/libs/ascent/runtimes/ascent_main_runtime.cpp b/src/libs/ascent/runtimes/ascent_main_runtime.cpp index 6a2358515..1a82408df 100644 --- a/src/libs/ascent/runtimes/ascent_main_runtime.cpp +++ b/src/libs/ascent/runtimes/ascent_main_runtime.cpp @@ -325,7 +325,7 @@ AscentRuntime::Initialize(const conduit::Node &options) } if(options.has_path("ghost_field_names")) - { + { if(!options["ghost_field_names"].dtype().is_list()) { ASCENT_ERROR("ghost_field_names is not a list"); @@ -432,7 +432,7 @@ AscentRuntime::AddPublishedMeshInfo() #ifdef ASCENT_MPI_ENABLED int comm_id = flow::Workspace::default_mpi_comm(); MPI_Comm mpi_comm = MPI_Comm_f2c(comm_id); - + Node n_src, n_reduce; n_src = src_tbytes; // all reduce to get total number of bytes across mpi tasks @@ -509,33 +509,6 @@ AscentRuntime::Cleanup() void AscentRuntime::Publish(const conduit::Node &data) { - // Process the comments. - m_comments.reset(); - if(data.has_path("state/software")) - { - m_comments.append() = "Software"; - m_comments.append() = data["state/software"].as_string(); - } - if(data.has_path("state/source")) - { - m_comments.append() = "Source"; - m_comments.append() = data["state/source"].as_string(); - } - if(data.has_path("state/title")) - { - m_comments.append() = "Title"; - m_comments.append() = data["state/title"].as_string(); - } - if(data.has_path("state/info")) - { - m_comments.append() = "Description"; - m_comments.append() = data["state/info"].as_string(); - } - if(data.has_path("state/comment")) - { - m_comments.append() = "Comment"; - m_comments.append() = data["state/comment"].as_string(); - } blueprint::mesh::to_multi_domain(data, m_source); EnsureDomainIds(); @@ -1387,10 +1360,35 @@ AscentRuntime::PopulateMetadata() const int num_domains = m_source.number_of_children(); int cycle = -1; float time = -1.f; + bool metadata_set = false; for(int i = 0; i < num_domains; ++i) { const conduit::Node &dom = m_source.child(i); + if (!metadata_set && dom.has_path("state")) + { + m_comments.reset(); + conduit::NodeConstIterator itr = dom["state"].children(); + + while(itr.has_next()) + { + const conduit::Node &cld = itr.next(); + if(cld.has_path("keyword") && cld.has_path("data")) + { + metadata_set = true; + m_comments.append() = cld["keyword"].as_string(); + try + { + m_comments.append() = cld["data"].as_string(); + } + catch(const conduit::Error) + { + m_comments.append() = cld["data"].to_string(); + } + } + } + } + if(dom.has_path("state/cycle")) { cycle = dom["state/cycle"].to_int32(); @@ -1401,7 +1399,6 @@ AscentRuntime::PopulateMetadata() } } - if(cycle != -1) { Metadata::n_metadata["cycle"] = cycle; @@ -2062,7 +2059,7 @@ AscentRuntime::Execute(const conduit::Node &actions) { SaveInfo(); } - + } // --- close try --- // @@ -2180,7 +2177,7 @@ void AscentRuntime::SourceFieldFilter() // if all fields were removed - also remove the fields node // or else blueprint verify will fail - // + // // (this can happen when some domains do not have selected fields) // if(dom["fields"].number_of_children() == 0) From b68e7150a38199ed1ec028aa9a5c30a35a2012f0 Mon Sep 17 00:00:00 2001 From: Cyrus Harrison Date: Thu, 12 Oct 2023 14:55:44 -0700 Subject: [PATCH 5/7] read the docs healing (#1201) --- .readthedocs.yaml | 6 ++++++ src/docs/sphinx/requirements.txt | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index f155c81b0..680858dad 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -14,6 +14,12 @@ build: # Build documentation in the docs/ directory with Sphinx sphinx: configuration: src/docs/sphinx/conf.py + # If using Sphinx, optionally build your docs in additional formats such as PDF # formats: # - pdf + +# Set requirements required to build your docs +python: + install: + - requirements: src/docs/sphinx/requirements.txt \ No newline at end of file diff --git a/src/docs/sphinx/requirements.txt b/src/docs/sphinx/requirements.txt index c896d4dff..09e5b504b 100644 --- a/src/docs/sphinx/requirements.txt +++ b/src/docs/sphinx/requirements.txt @@ -1 +1,3 @@ -docutils<0.18 \ No newline at end of file +docutils +sphinx==6.2.1 +sphinx-rtd-theme==1.2.2 \ No newline at end of file From fb4694cfe5e5e0268b7953101167f4ef81aaf040 Mon Sep 17 00:00:00 2001 From: Nicole Date: Tue, 17 Oct 2023 21:51:48 -0600 Subject: [PATCH 6/7] set background/foreground color before blend (#1204) if all annotations are turned off user specified background and foregrounds do not get set --- src/libs/vtkh/rendering/Render.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libs/vtkh/rendering/Render.cpp b/src/libs/vtkh/rendering/Render.cpp index 4ece529cb..9350d6f42 100644 --- a/src/libs/vtkh/rendering/Render.cpp +++ b/src/libs/vtkh/rendering/Render.cpp @@ -275,7 +275,12 @@ Render::Print() const void Render::RenderBackground() { - if(m_render_background) m_canvas.BlendBackground(); + if(m_render_background) + { + m_canvas.SetBackgroundColor(m_bg_color); + m_canvas.SetForegroundColor(m_fg_color); + m_canvas.BlendBackground(); + } } Render::vtkmCanvas From dfd6a2eec4fe424fc8e327693e5e700cc5ff2478 Mon Sep 17 00:00:00 2001 From: Nicole Date: Tue, 24 Oct 2023 13:59:42 -0600 Subject: [PATCH 7/7] fix broken unit test link in docs (#1209) auto camera unit test was moved from vtkh to ascent in a reorg --- src/docs/sphinx/Actions/Scenes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docs/sphinx/Actions/Scenes.rst b/src/docs/sphinx/Actions/Scenes.rst index 73c985492..61466eb8f 100644 --- a/src/docs/sphinx/Actions/Scenes.rst +++ b/src/docs/sphinx/Actions/Scenes.rst @@ -464,7 +464,7 @@ The code below creates a pipeline that first applies a contour filter and then a :align: center The camera placement chosen by the VQ metric DDS Entropy for this example. - This example and implementation of the other VQ metrics can be found in `auto_camera test `_. + This example and implementation of the other VQ metrics can be found in `auto_camera test `_. .. _actions_cinema: