From 18ae6a330ad3d854606943c8e83a3b348dd00031 Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 13 Nov 2024 17:28:56 -0800 Subject: [PATCH 01/27] add tests to build up to eventual use case --- src/axom/sidre/tests/CMakeLists.txt | 1 + .../sidre_read_write_userdefined_data.cpp | 346 ++++++++++++++++++ 2 files changed, 347 insertions(+) create mode 100644 src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp diff --git a/src/axom/sidre/tests/CMakeLists.txt b/src/axom/sidre/tests/CMakeLists.txt index f264f36589..ad0f9a1671 100644 --- a/src/axom/sidre/tests/CMakeLists.txt +++ b/src/axom/sidre/tests/CMakeLists.txt @@ -24,6 +24,7 @@ set(gtest_sidre_tests sidre_native_layout.cpp sidre_attribute.cpp sidre_mcarray.cpp + sidre_read_write_userdefined_data.cpp ) set(gtest_sidre_C_tests diff --git a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp new file mode 100644 index 0000000000..a0496e9107 --- /dev/null +++ b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp @@ -0,0 +1,346 @@ +// Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and +// other Axom Project Developers. See the top-level LICENSE file for details. +// +// SPDX-License-Identifier: (BSD-3-Clause) + +#include "gtest/gtest.h" +#include "axom/sidre.hpp" + +using axom::sidre::DataStore; +using axom::sidre::Group; +using axom::sidre::View; +using axom::sidre::indexIsValid; +using axom::sidre::IndexType; +using axom::sidre::InvalidIndex; +using axom::sidre::InvalidName; +using axom::sidre::nameIsValid; + +//-----Mock Serac Structs------------------------------------------------------ + +template +bool check(const T&, double) +{ + SLIC_ERROR("You didn't implement a specialization for check"); + return false; +} + +template +void fill(T&, double) +{ + SLIC_ERROR("You didn't implement a specialization for fill"); +} + +//--------------------- + +template +class Tensor { +public: + // Constructor to initialize all elements to a specific value + Tensor(const T& value = T()) { + for (auto& row : data) { + row.fill(value); + } + } + + // Constructor to initialize from an initializer list + Tensor(std::initializer_list> init) { + size_t row = 0; + for (auto& rowData : init) { + size_t col = 0; + for (auto& element : rowData) { + data[row][col++] = element; + } + row++; + } + } + + // Accessor for elements (read/write) + T& at(size_t row, size_t col) { + return data[row][col]; + } + + // Const accessor for elements (read-only) + const T& at(size_t row, size_t col) const { + return data[row][col]; + } + + // Get tensor dimensions + std::pair dimensions() const { + return {Rows, Cols}; + } + + // Print the tensor for demonstration purposes + void print() const { + for (const auto& row : data) { + for (const auto& element : row) { + std::cout << element << " "; + } + std::cout << "\n"; + } + } + +private: + std::array, Rows> data; +}; + +//--------------------- + +template <> +bool check(const double& state, double value) +{ + SLIC_INFO(axom::fmt::format("{} == {}", state, value)); + return state == value; +} + +template <> +void fill(double& state, double value) +{ + state = value; +} + +//--------------------- + +struct StateOne { + double x; +}; + +template <> +bool check(const StateOne& state, double value) +{ + SLIC_INFO(axom::fmt::format("{} == {}", state.x, value)); + return state.x == value; +} + +template <> +void fill(StateOne& state, double value) +{ + state.x = value; +} + +//--------------------- + +struct StateTwo { + double x; + double y; +}; + +template <> +bool check(const StateTwo& state, double value) +{ + return (state.x == value) && (state.y == (value + 1)); +} + +template <> +void fill(StateTwo& state, double value) +{ + state.x = value; + state.y = value + 1; +} + +//--------------------- + +struct StateThree { + double x; + double y; + double z; +}; + +template <> +bool check(const StateThree& state, double value) +{ + return (state.x == value) && (state.y == (value + 1)) && (state.z == (value + 2)); +} + +template <> +void fill(StateThree& state, double value) +{ + state.x = value; + state.y = value + 1; + state.z = value + 2; +} + +//--------------------- + +struct StateTensor { + Tensor t; + double x; +}; + +template <> +bool check(const StateTensor& state, double value) +{ + return (state.t.at(0,0) == value) && (state.t.at(0,1) == (value + 1)) && + (state.t.at(1,0) == (value + 2)) && (state.t.at(1,1) == (value + 3)) && + (state.x == (value + 4)); +} + +template <> +void fill(StateTensor& state, double value) +{ + state.t = {{value, value + 1}, {value + 2, value + 3}}; + state.x = value + 4; +} + +//--------------------- + +template +using QuadratureData1D = axom::Array; +template +using QuadratureData2D = axom::Array; + +//------------------------------------------------------------------------------ + +template +void test_user_defined_data() +{ + // populate data + constexpr IndexType size = 10; + QuadratureData1D states(size, size); + IndexType i = 0; + for(auto& state: states){ + fill(state, i++); + } + + // Create datastore + DataStore ds; + Group* qd_group = ds.getRoot()->createGroup("quadraturedata"); + + // get size + auto num_states = static_cast(states.size()); + auto state_size = static_cast(sizeof(states[0])); + auto total_size = num_states * state_size; + + // write shape + qd_group->createViewScalar("num_states", num_states); + qd_group->createViewScalar("state_size", state_size); + qd_group->createViewScalar("total_size", total_size); + + // write data to datastore as bytes + View* data_view = qd_group->createViewAndAllocate("states", + axom::sidre::UINT8_ID, + total_size); + std::uint8_t* sidre_state_data = data_view->getData(); + memcpy(sidre_state_data, states.data(), static_cast(total_size)); + + // mess with data before overriding it back to original in sidre + fill(states[0], 123); + fill(states[size/2], 456); + fill(states[size-1], 789); + + // Copy original data back over local data + memcpy(states.data(), sidre_state_data, static_cast(total_size)); + + // Test data is back to original + i = 0; + for(auto& state: states){ + EXPECT_TRUE(check(state, i++)); + } +} + +template +void test_external_user_defined_data() +{ + // populate data + constexpr IndexType size = 10; + QuadratureData1D states(size, size); + IndexType i = 0; + for(auto& state: states){ + fill(state, i++); + } + + // Create datastore + DataStore ds; + Group* qd_group = ds.getRoot()->createGroup("quadraturedata"); + + // get size + auto num_states = static_cast(states.size()); + auto state_size = static_cast(sizeof(states[0])); + auto total_size = num_states * state_size; + auto num_uint8s = total_size / sizeof(axom::sidre::UINT8_ID); + + // write shape + qd_group->createViewScalar("num_states", num_states); + qd_group->createViewScalar("state_size", state_size); + qd_group->createViewScalar("total_size", total_size); + + // Add states as an external buffer + View* states_view = qd_group->createView("states"); + states_view->setExternalDataPtr(axom::sidre::UINT8_ID, num_uint8s, states.data()); + + // Save the array data in to a file + std::string filename = "sidre_external_quadraturedata"; + qd_group->save(filename); + + // Create new array to fill with saved data + QuadratureData1D saved_states(size, size); + for(auto& state: saved_states){ + fill(state, -1); + } + + // Load data into new array + Group* new_qd_group = ds.getRoot()->createGroup("new_quadraturedata"); + new_qd_group->load(filename); + EXPECT_TRUE(new_qd_group->hasView("states")); + View* new_states_view = new_qd_group->getView("states"); + new_states_view->setExternalDataPtr(saved_states.data()); + new_qd_group->loadExternalData(filename); + + // Test data is back to original + i = 0; + for(auto& state: saved_states){ + EXPECT_TRUE(check(state, i++)); + } +} + +//------------------------------------------------------------------------------ + +TEST(sidre, QD_double_readandwrite) +{ + test_user_defined_data(); +} + +TEST(sidre, QD_StateOne_readandwrite) +{ + test_user_defined_data(); +} + +TEST(sidre, QD_StateTwo_readandwrite) +{ + test_user_defined_data(); +} + +TEST(sidre, QD_StateThree_readandwrite) +{ + test_user_defined_data(); +} + +TEST(sidre, QD_StateTensor_readandwrite) +{ + test_user_defined_data(); +} + +//------------------------------------------------------------------------------ + +TEST(sidre, QD_double_external_readandwrite) +{ + test_external_user_defined_data(); +} + +TEST(sidre, QD_StateOne_external_readandwrite) +{ + test_external_user_defined_data(); +} + +//---------------------------------------------------------------------- +int main(int argc, char* argv[]) +{ + int result = 0; + + ::testing::InitGoogleTest(&argc, argv); + axom::slic::SimpleLogger logger; + + result = RUN_ALL_TESTS(); + + return result; +} + From f6740b88e26c4bef2211c1028def59298a73439f Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 13 Nov 2024 17:58:59 -0800 Subject: [PATCH 02/27] remove unused using's --- src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp index a0496e9107..86a353bc68 100644 --- a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp +++ b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp @@ -9,11 +9,7 @@ using axom::sidre::DataStore; using axom::sidre::Group; using axom::sidre::View; -using axom::sidre::indexIsValid; using axom::sidre::IndexType; -using axom::sidre::InvalidIndex; -using axom::sidre::InvalidName; -using axom::sidre::nameIsValid; //-----Mock Serac Structs------------------------------------------------------ From 59affef7a37fa97c1a9c66f1d51ff1d4d21647ed Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 13 Nov 2024 23:49:41 -0800 Subject: [PATCH 03/27] style --- .../sidre_read_write_userdefined_data.cpp | 153 +++++++++--------- 1 file changed, 80 insertions(+), 73 deletions(-) diff --git a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp index 86a353bc68..6b9f7b3ad3 100644 --- a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp +++ b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp @@ -8,8 +8,8 @@ using axom::sidre::DataStore; using axom::sidre::Group; -using axom::sidre::View; using axom::sidre::IndexType; +using axom::sidre::View; //-----Mock Serac Structs------------------------------------------------------ @@ -29,54 +29,60 @@ void fill(T&, double) //--------------------- template -class Tensor { +class Tensor +{ public: - // Constructor to initialize all elements to a specific value - Tensor(const T& value = T()) { - for (auto& row : data) { - row.fill(value); - } - } - - // Constructor to initialize from an initializer list - Tensor(std::initializer_list> init) { - size_t row = 0; - for (auto& rowData : init) { - size_t col = 0; - for (auto& element : rowData) { - data[row][col++] = element; - } - row++; - } - } - - // Accessor for elements (read/write) - T& at(size_t row, size_t col) { - return data[row][col]; - } - - // Const accessor for elements (read-only) - const T& at(size_t row, size_t col) const { - return data[row][col]; + // Constructor to initialize all elements to a specific value + Tensor(const T& value = T()) + { + for(auto& row : data) + { + row.fill(value); } + } - // Get tensor dimensions - std::pair dimensions() const { - return {Rows, Cols}; + // Constructor to initialize from an initializer list + Tensor(std::initializer_list> init) + { + size_t row = 0; + for(auto& rowData : init) + { + size_t col = 0; + for(auto& element : rowData) + { + data[row][col++] = element; + } + row++; } + } - // Print the tensor for demonstration purposes - void print() const { - for (const auto& row : data) { - for (const auto& element : row) { - std::cout << element << " "; - } - std::cout << "\n"; - } + // Accessor for elements (read/write) + T& at(size_t row, size_t col) { return data[row][col]; } + + // Const accessor for elements (read-only) + const T& at(size_t row, size_t col) const { return data[row][col]; } + + // Get tensor dimensions + std::pair dimensions() const { return {Rows, Cols}; } + + // Function to return a string representation of the tensor + std::string to_string() const + { + std::ostringstream oss; + for(const auto& row : data) + { + oss << "[ "; + for(const auto& elem : row) + { + oss << elem << " "; + } + oss << "]\n"; } + return oss.str(); + } private: - std::array, Rows> data; + std::array, Rows> data; }; //--------------------- @@ -96,7 +102,8 @@ void fill(double& state, double value) //--------------------- -struct StateOne { +struct StateOne +{ double x; }; @@ -115,7 +122,8 @@ void fill(StateOne& state, double value) //--------------------- -struct StateTwo { +struct StateTwo +{ double x; double y; }; @@ -135,7 +143,8 @@ void fill(StateTwo& state, double value) //--------------------- -struct StateThree { +struct StateThree +{ double x; double y; double z; @@ -144,7 +153,8 @@ struct StateThree { template <> bool check(const StateThree& state, double value) { - return (state.x == value) && (state.y == (value + 1)) && (state.z == (value + 2)); + return (state.x == value) && (state.y == (value + 1)) && + (state.z == (value + 2)); } template <> @@ -157,7 +167,8 @@ void fill(StateThree& state, double value) //--------------------- -struct StateTensor { +struct StateTensor +{ Tensor t; double x; }; @@ -165,9 +176,9 @@ struct StateTensor { template <> bool check(const StateTensor& state, double value) { - return (state.t.at(0,0) == value) && (state.t.at(0,1) == (value + 1)) && - (state.t.at(1,0) == (value + 2)) && (state.t.at(1,1) == (value + 3)) && - (state.x == (value + 4)); + return (state.t.at(0, 0) == value) && (state.t.at(0, 1) == (value + 1)) && + (state.t.at(1, 0) == (value + 2)) && (state.t.at(1, 1) == (value + 3)) && + (state.x == (value + 4)); } template <> @@ -193,7 +204,8 @@ void test_user_defined_data() constexpr IndexType size = 10; QuadratureData1D states(size, size); IndexType i = 0; - for(auto& state: states){ + for(auto& state : states) + { fill(state, i++); } @@ -212,23 +224,23 @@ void test_user_defined_data() qd_group->createViewScalar("total_size", total_size); // write data to datastore as bytes - View* data_view = qd_group->createViewAndAllocate("states", - axom::sidre::UINT8_ID, - total_size); + View* data_view = + qd_group->createViewAndAllocate("states", axom::sidre::UINT8_ID, total_size); std::uint8_t* sidre_state_data = data_view->getData(); memcpy(sidre_state_data, states.data(), static_cast(total_size)); // mess with data before overriding it back to original in sidre fill(states[0], 123); - fill(states[size/2], 456); - fill(states[size-1], 789); + fill(states[size / 2], 456); + fill(states[size - 1], 789); // Copy original data back over local data memcpy(states.data(), sidre_state_data, static_cast(total_size)); // Test data is back to original i = 0; - for(auto& state: states){ + for(auto& state : states) + { EXPECT_TRUE(check(state, i++)); } } @@ -240,7 +252,8 @@ void test_external_user_defined_data() constexpr IndexType size = 10; QuadratureData1D states(size, size); IndexType i = 0; - for(auto& state: states){ + for(auto& state : states) + { fill(state, i++); } @@ -261,7 +274,9 @@ void test_external_user_defined_data() // Add states as an external buffer View* states_view = qd_group->createView("states"); - states_view->setExternalDataPtr(axom::sidre::UINT8_ID, num_uint8s, states.data()); + states_view->setExternalDataPtr(axom::sidre::UINT8_ID, + num_uint8s, + states.data()); // Save the array data in to a file std::string filename = "sidre_external_quadraturedata"; @@ -269,7 +284,8 @@ void test_external_user_defined_data() // Create new array to fill with saved data QuadratureData1D saved_states(size, size); - for(auto& state: saved_states){ + for(auto& state : saved_states) + { fill(state, -1); } @@ -283,27 +299,19 @@ void test_external_user_defined_data() // Test data is back to original i = 0; - for(auto& state: saved_states){ + for(auto& state : saved_states) + { EXPECT_TRUE(check(state, i++)); } } //------------------------------------------------------------------------------ -TEST(sidre, QD_double_readandwrite) -{ - test_user_defined_data(); -} +TEST(sidre, QD_double_readandwrite) { test_user_defined_data(); } -TEST(sidre, QD_StateOne_readandwrite) -{ - test_user_defined_data(); -} +TEST(sidre, QD_StateOne_readandwrite) { test_user_defined_data(); } -TEST(sidre, QD_StateTwo_readandwrite) -{ - test_user_defined_data(); -} +TEST(sidre, QD_StateTwo_readandwrite) { test_user_defined_data(); } TEST(sidre, QD_StateThree_readandwrite) { @@ -339,4 +347,3 @@ int main(int argc, char* argv[]) return result; } - From 6cc09d653d1d7601b5952ffa569da125974b2a11 Mon Sep 17 00:00:00 2001 From: Chris White Date: Thu, 14 Nov 2024 18:01:45 -0800 Subject: [PATCH 04/27] use the actual type when getting the size, thanks noah! --- src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp index 6b9f7b3ad3..2cddb5af21 100644 --- a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp +++ b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp @@ -90,7 +90,6 @@ class Tensor template <> bool check(const double& state, double value) { - SLIC_INFO(axom::fmt::format("{} == {}", state, value)); return state == value; } @@ -110,7 +109,6 @@ struct StateOne template <> bool check(const StateOne& state, double value) { - SLIC_INFO(axom::fmt::format("{} == {}", state.x, value)); return state.x == value; } @@ -265,7 +263,7 @@ void test_external_user_defined_data() auto num_states = static_cast(states.size()); auto state_size = static_cast(sizeof(states[0])); auto total_size = num_states * state_size; - auto num_uint8s = total_size / sizeof(axom::sidre::UINT8_ID); + auto num_uint8s = total_size / sizeof(std::uint8_t); // write shape qd_group->createViewScalar("num_states", num_states); From e7fcc2b254862eb4f3cd22d6b8bd91b8aa7a2be7 Mon Sep 17 00:00:00 2001 From: Chris White Date: Fri, 22 Nov 2024 10:28:10 -0800 Subject: [PATCH 05/27] add dim, swap for serac's tensor, unify filling and checking whole array --- .../sidre_read_write_userdefined_data.cpp | 293 +++++++++++------- 1 file changed, 179 insertions(+), 114 deletions(-) diff --git a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp index 2cddb5af21..4c2202a079 100644 --- a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp +++ b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp @@ -13,80 +13,94 @@ using axom::sidre::View; //-----Mock Serac Structs------------------------------------------------------ -template -bool check(const T&, double) +/** + * @brief Arbitrary-rank tensor class + * @tparam T The type stored at each index + * @tparam n The dimensions of the tensor + */ +template +struct tensor; + +template +struct tensor { - SLIC_ERROR("You didn't implement a specialization for check"); - return false; -} + template + constexpr auto& operator()(i_type i) + { + return data[i]; + } + template + constexpr auto& operator()(i_type i) const + { + return data[i]; + } + template + constexpr auto& operator()(i_type i, jklm_type... jklm) + { + return data[i](jklm...); + } + template + constexpr auto& operator()(i_type i, jklm_type... jklm) const + { + return data[i](jklm...); + } -template -void fill(T&, double) -{ - SLIC_ERROR("You didn't implement a specialization for fill"); -} + constexpr auto& operator[](int i) { return data[i]; } + constexpr const auto& operator[](int i) const { return data[i]; } -//--------------------- + tensor data[m]; +}; -template -class Tensor +template +struct tensor { -public: - // Constructor to initialize all elements to a specific value - Tensor(const T& value = T()) + template + constexpr auto& operator()(i_type i) { - for(auto& row : data) - { - row.fill(value); - } + return data[i]; } - - // Constructor to initialize from an initializer list - Tensor(std::initializer_list> init) + template + constexpr auto& operator()(i_type i) const { - size_t row = 0; - for(auto& rowData : init) - { - size_t col = 0; - for(auto& element : rowData) - { - data[row][col++] = element; - } - row++; - } + return data[i]; } + constexpr auto& operator[](int i) { return data[i]; } + constexpr const auto& operator[](int i) const { return data[i]; } - // Accessor for elements (read/write) - T& at(size_t row, size_t col) { return data[row][col]; } - - // Const accessor for elements (read-only) - const T& at(size_t row, size_t col) const { return data[row][col]; } - - // Get tensor dimensions - std::pair dimensions() const { return {Rows, Cols}; } + template ::type> + constexpr operator T() + { + return data[0]; + } - // Function to return a string representation of the tensor - std::string to_string() const + template ::type> + constexpr operator T() const { - std::ostringstream oss; - for(const auto& row : data) - { - oss << "[ "; - for(const auto& elem : row) - { - oss << elem << " "; - } - oss << "]\n"; - } - return oss.str(); + return data[0]; } -private: - std::array, Rows> data; + T data[m]; }; //--------------------- +template +bool check(const T&, double) +{ + SLIC_ERROR("You didn't implement a specialization for check"); + return false; +} + +template +void fill(T&, double) +{ + SLIC_ERROR("You didn't implement a specialization for fill"); +} + +//--------------------- + template <> bool check(const double& state, double value) { @@ -167,45 +181,98 @@ void fill(StateThree& state, double value) struct StateTensor { - Tensor t; + //tensor t; + tensor t; double x; }; template <> bool check(const StateTensor& state, double value) { - return (state.t.at(0, 0) == value) && (state.t.at(0, 1) == (value + 1)) && - (state.t.at(1, 0) == (value + 2)) && (state.t.at(1, 1) == (value + 3)) && + // SLIC_INFO(axom::fmt::format("check({}, {}, {}, {}), {}", + // state.t(0, 0), + // state.t(0, 1), + // state.t(1, 0), + // state.t(1, 1), + // state.x)); + + // return (state.t(0, 0) == value) && (state.t(0, 1) == (value + 1)) && + // (state.t(1, 0) == (value + 2)) && (state.t(1, 1) == (value + 3)) && + // (state.x == (value + 4)); + + SLIC_INFO( + axom::fmt::format("check({}, {}), {}", state.t(0), state.t(1), state.x)); + + return (state.t(0) == value) && (state.t(1) == (value + 1)) && (state.x == (value + 4)); } template <> void fill(StateTensor& state, double value) { - state.t = {{value, value + 1}, {value + 2, value + 3}}; + // state.t(0,0) = value; + // state.t(0,1) = value + 1; + // state.t(1,0) = value + 2; + // state.t(1,1) = value + 3; + state.t(0) = value; + state.t(1) = value + 1; state.x = value + 4; } //--------------------- -template -using QuadratureData1D = axom::Array; -template -using QuadratureData2D = axom::Array; +template +void fill_array(T, int, bool) +{ + SLIC_ERROR("You didn't implement the fill array of this type."); +} + +template +void check_array(T) +{ + SLIC_ERROR("You didn't implement the check array of this type."); +} + +template +void fill_array(axom::Array& states, double fill_value, bool increment) +{ + int count = 0; + for(auto& state : states) + { + fill(state, fill_value); + if(increment) + { + fill_value++; + } + count++; + } + SLIC_INFO( + axom::fmt::format("filled {} states with end value {}", count, fill_value)); +} + +template +void check_array(axom::Array states) +{ + int count = 0; + double check_value = 0; + for(auto& state : states) + { + EXPECT_TRUE(check(state, check_value++)); + count++; + } + SLIC_INFO( + axom::fmt::format("checked {} states with end value {}", count, check_value)); +} //------------------------------------------------------------------------------ -template +template void test_user_defined_data() { // populate data constexpr IndexType size = 10; - QuadratureData1D states(size, size); - IndexType i = 0; - for(auto& state : states) - { - fill(state, i++); - } + axom::Array states(size, size); + fill_array(states, 0, true); // Create datastore DataStore ds; @@ -220,6 +287,12 @@ void test_user_defined_data() qd_group->createViewScalar("num_states", num_states); qd_group->createViewScalar("state_size", state_size); qd_group->createViewScalar("total_size", total_size); + SLIC_INFO(axom::fmt::format("Num of States={}", num_states)); + SLIC_INFO(axom::fmt::format("State Size={}", state_size)); + SLIC_INFO(axom::fmt::format("Total Size={}", total_size)); + SLIC_INFO(axom::fmt::format("Double Size={}", sizeof(double))); + SLIC_INFO(axom::fmt::format("Total Size/Double Size={}", + total_size / sizeof(double))); // write data to datastore as bytes View* data_view = @@ -228,32 +301,22 @@ void test_user_defined_data() memcpy(sidre_state_data, states.data(), static_cast(total_size)); // mess with data before overriding it back to original in sidre - fill(states[0], 123); - fill(states[size / 2], 456); - fill(states[size - 1], 789); + fill_array(states, -1, false); // Copy original data back over local data memcpy(states.data(), sidre_state_data, static_cast(total_size)); // Test data is back to original - i = 0; - for(auto& state : states) - { - EXPECT_TRUE(check(state, i++)); - } + check_array(states); } -template +template void test_external_user_defined_data() { // populate data constexpr IndexType size = 10; - QuadratureData1D states(size, size); - IndexType i = 0; - for(auto& state : states) - { - fill(state, i++); - } + axom::Array states(size, size); + fill_array(states, 0, true); // Create datastore DataStore ds; @@ -281,11 +344,8 @@ void test_external_user_defined_data() qd_group->save(filename); // Create new array to fill with saved data - QuadratureData1D saved_states(size, size); - for(auto& state : saved_states) - { - fill(state, -1); - } + axom::Array saved_states(size, size); + fill_array(saved_states, -1, false); // Load data into new array Group* new_qd_group = ds.getRoot()->createGroup("new_quadraturedata"); @@ -295,43 +355,48 @@ void test_external_user_defined_data() new_states_view->setExternalDataPtr(saved_states.data()); new_qd_group->loadExternalData(filename); - // Test data is back to original - i = 0; - for(auto& state : saved_states) - { - EXPECT_TRUE(check(state, i++)); - } + // Test data was read into the new location and overwrote the bad data + check_array(saved_states); } //------------------------------------------------------------------------------ -TEST(sidre, QD_double_readandwrite) { test_user_defined_data(); } +TEST(sidre, OneD_double_readandwrite) { test_user_defined_data(); } -TEST(sidre, QD_StateOne_readandwrite) { test_user_defined_data(); } +// TEST(sidre, OneD_StateOne_readandwrite) { test_user_defined_data(); } -TEST(sidre, QD_StateTwo_readandwrite) { test_user_defined_data(); } +// TEST(sidre, OneD_StateTwo_readandwrite) { test_user_defined_data(); } -TEST(sidre, QD_StateThree_readandwrite) -{ - test_user_defined_data(); -} +// TEST(sidre, OneD_StateThree_readandwrite) { test_user_defined_data(); } + +// TEST(sidre, OneD_StateTensor_readandwrite) { test_user_defined_data(); } -TEST(sidre, QD_StateTensor_readandwrite) +// //------------------------- + +// TEST(sidre, TwoD_double_readandwrite) { test_user_defined_data(); } + +// TEST(sidre, TwoD_StateOne_readandwrite) { test_user_defined_data(); } + +// TEST(sidre, TwoD_StateTwo_readandwrite) { test_user_defined_data(); } + +// TEST(sidre, TwoD_StateThree_readandwrite) { test_user_defined_data(); } + +TEST(sidre, TwoD_StateTensor_readandwrite) { - test_user_defined_data(); + test_user_defined_data(); } //------------------------------------------------------------------------------ -TEST(sidre, QD_double_external_readandwrite) -{ - test_external_user_defined_data(); -} +// TEST(sidre, OneD_double_external_readandwrite) { test_external_user_defined_data(); } -TEST(sidre, QD_StateOne_external_readandwrite) -{ - test_external_user_defined_data(); -} +// TEST(sidre, OneD_StateOne_external_readandwrite) { test_external_user_defined_data(); } + +// TEST(sidre, OneD_StateTwo_external_readandwrite) { test_external_user_defined_data(); } + +// TEST(sidre, OneD_StateThree_external_readandwrite) { test_external_user_defined_data(); } + +// TEST(sidre, OneD_StateTensor_external_readandwrite) { test_external_user_defined_data(); } //---------------------------------------------------------------------- int main(int argc, char* argv[]) From 87e99d8faec347eab0ee0668bd40d3d1bcb4d444 Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 27 Nov 2024 14:33:28 -0800 Subject: [PATCH 06/27] fix tests, add tests covering differing size tensor --- .../sidre_read_write_userdefined_data.cpp | 160 +++++++++++------- 1 file changed, 95 insertions(+), 65 deletions(-) diff --git a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp index 4c2202a079..a6224d81b3 100644 --- a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp +++ b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp @@ -179,43 +179,49 @@ void fill(StateThree& state, double value) //--------------------- -struct StateTensor +struct StateTensorSmall { - //tensor t; tensor t; double x; }; template <> -bool check(const StateTensor& state, double value) +bool check(const StateTensorSmall& state, double value) { - // SLIC_INFO(axom::fmt::format("check({}, {}, {}, {}), {}", - // state.t(0, 0), - // state.t(0, 1), - // state.t(1, 0), - // state.t(1, 1), - // state.x)); + return (state.t(0) == value) && (state.t(1) == (value + 1)) && (state.x == (value + 4)); +} - // return (state.t(0, 0) == value) && (state.t(0, 1) == (value + 1)) && - // (state.t(1, 0) == (value + 2)) && (state.t(1, 1) == (value + 3)) && - // (state.x == (value + 4)); +template <> +void fill(StateTensorSmall& state, double value) +{ + state.t(0) = value; + state.t(1) = value + 1; + state.x = value + 4; +} - SLIC_INFO( - axom::fmt::format("check({}, {}), {}", state.t(0), state.t(1), state.x)); +//--------------------- - return (state.t(0) == value) && (state.t(1) == (value + 1)) && +struct StateTensorLarge +{ + tensor t; + double x; +}; + +template <> +bool check(const StateTensorLarge& state, double value) +{ + return (state.t(0, 0) == value) && (state.t(0, 1) == (value + 1)) && + (state.t(1, 0) == (value + 2)) && (state.t(1, 1) == (value + 3)) && (state.x == (value + 4)); } template <> -void fill(StateTensor& state, double value) +void fill(StateTensorLarge& state, double value) { - // state.t(0,0) = value; - // state.t(0,1) = value + 1; - // state.t(1,0) = value + 2; - // state.t(1,1) = value + 3; - state.t(0) = value; - state.t(1) = value + 1; + state.t(0,0) = value; + state.t(0,1) = value + 1; + state.t(1,0) = value + 2; + state.t(1,1) = value + 3; state.x = value + 4; } @@ -276,28 +282,28 @@ void test_user_defined_data() // Create datastore DataStore ds; - Group* qd_group = ds.getRoot()->createGroup("quadraturedata"); + Group* root = ds.getRoot(); // get size auto num_states = static_cast(states.size()); - auto state_size = static_cast(sizeof(states[0])); + auto state_size = static_cast(sizeof(*(states.begin()))); auto total_size = num_states * state_size; - // write shape - qd_group->createViewScalar("num_states", num_states); - qd_group->createViewScalar("state_size", state_size); - qd_group->createViewScalar("total_size", total_size); SLIC_INFO(axom::fmt::format("Num of States={}", num_states)); SLIC_INFO(axom::fmt::format("State Size={}", state_size)); SLIC_INFO(axom::fmt::format("Total Size={}", total_size)); - SLIC_INFO(axom::fmt::format("Double Size={}", sizeof(double))); - SLIC_INFO(axom::fmt::format("Total Size/Double Size={}", - total_size / sizeof(double))); + SLIC_INFO(axom::fmt::format("Total Size/State Size={}", + total_size / state_size)); + + // write shape + root->createViewScalar("num_states", num_states); + root->createViewScalar("state_size", state_size); + root->createViewScalar("total_size", total_size); // write data to datastore as bytes - View* data_view = - qd_group->createViewAndAllocate("states", axom::sidre::UINT8_ID, total_size); - std::uint8_t* sidre_state_data = data_view->getData(); + View* states_view = + root->createViewAndAllocate("states", axom::sidre::UINT8_ID, total_size); + std::uint8_t* sidre_state_data = states_view->getData(); memcpy(sidre_state_data, states.data(), static_cast(total_size)); // mess with data before overriding it back to original in sidre @@ -320,40 +326,47 @@ void test_external_user_defined_data() // Create datastore DataStore ds; - Group* qd_group = ds.getRoot()->createGroup("quadraturedata"); + Group* root = ds.getRoot(); // get size auto num_states = static_cast(states.size()); - auto state_size = static_cast(sizeof(states[0])); + auto state_size = static_cast(sizeof(*(states.begin()))); auto total_size = num_states * state_size; auto num_uint8s = total_size / sizeof(std::uint8_t); + SLIC_INFO(axom::fmt::format("Num of States={}", num_states)); + SLIC_INFO(axom::fmt::format("State Size={}", state_size)); + SLIC_INFO(axom::fmt::format("Total Size={}", total_size)); + SLIC_INFO(axom::fmt::format("Total Size/State Size={}", + total_size / state_size)); + SLIC_INFO(axom::fmt::format("Num of uint8={}", num_uint8s)); + // write shape - qd_group->createViewScalar("num_states", num_states); - qd_group->createViewScalar("state_size", state_size); - qd_group->createViewScalar("total_size", total_size); + root->createViewScalar("num_states", num_states); + root->createViewScalar("state_size", state_size); + root->createViewScalar("total_size", total_size); // Add states as an external buffer - View* states_view = qd_group->createView("states"); + View* states_view = root->createView("states"); states_view->setExternalDataPtr(axom::sidre::UINT8_ID, num_uint8s, states.data()); // Save the array data in to a file - std::string filename = "sidre_external_quadraturedata"; - qd_group->save(filename); + std::string filename = "sidre_external_states"; + root->save(filename); // Create new array to fill with saved data axom::Array saved_states(size, size); fill_array(saved_states, -1, false); // Load data into new array - Group* new_qd_group = ds.getRoot()->createGroup("new_quadraturedata"); - new_qd_group->load(filename); - EXPECT_TRUE(new_qd_group->hasView("states")); - View* new_states_view = new_qd_group->getView("states"); + Group* loaded_group = root->createGroup("loaded_data"); + loaded_group->load(filename); + EXPECT_TRUE(loaded_group->hasView("states")); + View* new_states_view = loaded_group->getView("states"); new_states_view->setExternalDataPtr(saved_states.data()); - new_qd_group->loadExternalData(filename); + loaded_group->loadExternalData(filename); // Test data was read into the new location and overwrote the bad data check_array(saved_states); @@ -363,40 +376,57 @@ void test_external_user_defined_data() TEST(sidre, OneD_double_readandwrite) { test_user_defined_data(); } -// TEST(sidre, OneD_StateOne_readandwrite) { test_user_defined_data(); } +TEST(sidre, OneD_StateOne_readandwrite) { test_user_defined_data(); } -// TEST(sidre, OneD_StateTwo_readandwrite) { test_user_defined_data(); } +TEST(sidre, OneD_StateTwo_readandwrite) { test_user_defined_data(); } -// TEST(sidre, OneD_StateThree_readandwrite) { test_user_defined_data(); } +TEST(sidre, OneD_StateThree_readandwrite) { test_user_defined_data(); } -// TEST(sidre, OneD_StateTensor_readandwrite) { test_user_defined_data(); } +TEST(sidre, OneD_StateTensorSmall_readandwrite) { test_user_defined_data(); } -// //------------------------- +TEST(sidre, OneD_StateTensorLarge_readandwrite) { test_user_defined_data(); } -// TEST(sidre, TwoD_double_readandwrite) { test_user_defined_data(); } +//------------------------- -// TEST(sidre, TwoD_StateOne_readandwrite) { test_user_defined_data(); } +TEST(sidre, TwoD_double_readandwrite) { test_user_defined_data(); } -// TEST(sidre, TwoD_StateTwo_readandwrite) { test_user_defined_data(); } +TEST(sidre, TwoD_StateOne_readandwrite) { test_user_defined_data(); } -// TEST(sidre, TwoD_StateThree_readandwrite) { test_user_defined_data(); } +TEST(sidre, TwoD_StateTwo_readandwrite) { test_user_defined_data(); } -TEST(sidre, TwoD_StateTensor_readandwrite) -{ - test_user_defined_data(); -} +TEST(sidre, TwoD_StateThree_readandwrite) { test_user_defined_data(); } + +TEST(sidre, TwoD_StateTensorSmall_readandwrite) { test_user_defined_data(); } + +TEST(sidre, TwoD_StateTensorLarge_readandwrite) { test_user_defined_data(); } //------------------------------------------------------------------------------ -// TEST(sidre, OneD_double_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, OneD_double_external_readandwrite) { test_external_user_defined_data(); } + +TEST(sidre, OneD_StateOne_external_readandwrite) { test_external_user_defined_data(); } + +TEST(sidre, OneD_StateTwo_external_readandwrite) { test_external_user_defined_data(); } + +TEST(sidre, OneD_StateThree_external_readandwrite) { test_external_user_defined_data(); } + +TEST(sidre, OneD_StateTensorSmall_external_readandwrite) { test_external_user_defined_data(); } + +TEST(sidre, OneD_StateTensorLarge_external_readandwrite) { test_external_user_defined_data(); } + +//------------------------- + +TEST(sidre, TwoD_double_external_readandwrite) { test_external_user_defined_data(); } + +TEST(sidre, TwoD_StateOne_external_readandwrite) { test_external_user_defined_data(); } -// TEST(sidre, OneD_StateOne_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, TwoD_StateTwo_external_readandwrite) { test_external_user_defined_data(); } -// TEST(sidre, OneD_StateTwo_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, TwoD_StateThree_external_readandwrite) { test_external_user_defined_data(); } -// TEST(sidre, OneD_StateThree_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, TwoD_StateTensorSmall_external_readandwrite) { test_external_user_defined_data(); } -// TEST(sidre, OneD_StateTensor_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, TwoD_StateTensorLarge_external_readandwrite) { test_external_user_defined_data(); } //---------------------------------------------------------------------- int main(int argc, char* argv[]) From d4a23cece5f8783ad0b787a6e8fd5d9c1e9ad98c Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 27 Nov 2024 15:11:03 -0800 Subject: [PATCH 07/27] add comment explaining test --- scripts/spack/radiuss-spack-configs | 2 +- .../sidre/tests/sidre_read_write_userdefined_data.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/spack/radiuss-spack-configs b/scripts/spack/radiuss-spack-configs index 22f5feaabf..efe7a45205 160000 --- a/scripts/spack/radiuss-spack-configs +++ b/scripts/spack/radiuss-spack-configs @@ -1 +1 @@ -Subproject commit 22f5feaabfe618339cf621d2734fe0d66077da39 +Subproject commit efe7a45205f0c71563c909e26c2f0a54a4c9427a diff --git a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp index a6224d81b3..ed85ab3319 100644 --- a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp +++ b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp @@ -11,6 +11,14 @@ using axom::sidre::Group; using axom::sidre::IndexType; using axom::sidre::View; +// This test is meant to mock how Serac stores and loads Quadrature Data. +// The data is stored in Axom Array's of material states and are a user defined +// structure of POD types. +// +// There are two types of tests, one is where the data is managed by Sidre and +// the other is where the data is external to sidre and is saved and loaded to +// disk. The latter is what Serac is doing. + //-----Mock Serac Structs------------------------------------------------------ /** From e7f4f75dc5179a65be541eca19a64074ba3ad4f6 Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 27 Nov 2024 15:24:45 -0800 Subject: [PATCH 08/27] style --- .../sidre_read_write_userdefined_data.cpp | 129 +++++++++++++----- 1 file changed, 98 insertions(+), 31 deletions(-) diff --git a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp index ed85ab3319..e27fd7ac60 100644 --- a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp +++ b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp @@ -196,7 +196,8 @@ struct StateTensorSmall template <> bool check(const StateTensorSmall& state, double value) { - return (state.t(0) == value) && (state.t(1) == (value + 1)) && (state.x == (value + 4)); + return (state.t(0) == value) && (state.t(1) == (value + 1)) && + (state.x == (value + 4)); } template <> @@ -226,10 +227,10 @@ bool check(const StateTensorLarge& state, double value) template <> void fill(StateTensorLarge& state, double value) { - state.t(0,0) = value; - state.t(0,1) = value + 1; - state.t(1,0) = value + 2; - state.t(1,1) = value + 3; + state.t(0, 0) = value; + state.t(0, 1) = value + 1; + state.t(1, 0) = value + 2; + state.t(1, 1) = value + 3; state.x = value + 4; } @@ -300,8 +301,8 @@ void test_user_defined_data() SLIC_INFO(axom::fmt::format("Num of States={}", num_states)); SLIC_INFO(axom::fmt::format("State Size={}", state_size)); SLIC_INFO(axom::fmt::format("Total Size={}", total_size)); - SLIC_INFO(axom::fmt::format("Total Size/State Size={}", - total_size / state_size)); + SLIC_INFO( + axom::fmt::format("Total Size/State Size={}", total_size / state_size)); // write shape root->createViewScalar("num_states", num_states); @@ -345,8 +346,8 @@ void test_external_user_defined_data() SLIC_INFO(axom::fmt::format("Num of States={}", num_states)); SLIC_INFO(axom::fmt::format("State Size={}", state_size)); SLIC_INFO(axom::fmt::format("Total Size={}", total_size)); - SLIC_INFO(axom::fmt::format("Total Size/State Size={}", - total_size / state_size)); + SLIC_INFO( + axom::fmt::format("Total Size/State Size={}", total_size / state_size)); SLIC_INFO(axom::fmt::format("Num of uint8={}", num_uint8s)); // write shape @@ -384,57 +385,123 @@ void test_external_user_defined_data() TEST(sidre, OneD_double_readandwrite) { test_user_defined_data(); } -TEST(sidre, OneD_StateOne_readandwrite) { test_user_defined_data(); } +TEST(sidre, OneD_StateOne_readandwrite) +{ + test_user_defined_data(); +} -TEST(sidre, OneD_StateTwo_readandwrite) { test_user_defined_data(); } +TEST(sidre, OneD_StateTwo_readandwrite) +{ + test_user_defined_data(); +} -TEST(sidre, OneD_StateThree_readandwrite) { test_user_defined_data(); } +TEST(sidre, OneD_StateThree_readandwrite) +{ + test_user_defined_data(); +} -TEST(sidre, OneD_StateTensorSmall_readandwrite) { test_user_defined_data(); } +TEST(sidre, OneD_StateTensorSmall_readandwrite) +{ + test_user_defined_data(); +} -TEST(sidre, OneD_StateTensorLarge_readandwrite) { test_user_defined_data(); } +TEST(sidre, OneD_StateTensorLarge_readandwrite) +{ + test_user_defined_data(); +} //------------------------- TEST(sidre, TwoD_double_readandwrite) { test_user_defined_data(); } -TEST(sidre, TwoD_StateOne_readandwrite) { test_user_defined_data(); } +TEST(sidre, TwoD_StateOne_readandwrite) +{ + test_user_defined_data(); +} -TEST(sidre, TwoD_StateTwo_readandwrite) { test_user_defined_data(); } +TEST(sidre, TwoD_StateTwo_readandwrite) +{ + test_user_defined_data(); +} -TEST(sidre, TwoD_StateThree_readandwrite) { test_user_defined_data(); } +TEST(sidre, TwoD_StateThree_readandwrite) +{ + test_user_defined_data(); +} -TEST(sidre, TwoD_StateTensorSmall_readandwrite) { test_user_defined_data(); } +TEST(sidre, TwoD_StateTensorSmall_readandwrite) +{ + test_user_defined_data(); +} -TEST(sidre, TwoD_StateTensorLarge_readandwrite) { test_user_defined_data(); } +TEST(sidre, TwoD_StateTensorLarge_readandwrite) +{ + test_user_defined_data(); +} //------------------------------------------------------------------------------ -TEST(sidre, OneD_double_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, OneD_double_external_readandwrite) +{ + test_external_user_defined_data(); +} -TEST(sidre, OneD_StateOne_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, OneD_StateOne_external_readandwrite) +{ + test_external_user_defined_data(); +} -TEST(sidre, OneD_StateTwo_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, OneD_StateTwo_external_readandwrite) +{ + test_external_user_defined_data(); +} -TEST(sidre, OneD_StateThree_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, OneD_StateThree_external_readandwrite) +{ + test_external_user_defined_data(); +} -TEST(sidre, OneD_StateTensorSmall_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, OneD_StateTensorSmall_external_readandwrite) +{ + test_external_user_defined_data(); +} -TEST(sidre, OneD_StateTensorLarge_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, OneD_StateTensorLarge_external_readandwrite) +{ + test_external_user_defined_data(); +} //------------------------- -TEST(sidre, TwoD_double_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, TwoD_double_external_readandwrite) +{ + test_external_user_defined_data(); +} -TEST(sidre, TwoD_StateOne_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, TwoD_StateOne_external_readandwrite) +{ + test_external_user_defined_data(); +} -TEST(sidre, TwoD_StateTwo_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, TwoD_StateTwo_external_readandwrite) +{ + test_external_user_defined_data(); +} -TEST(sidre, TwoD_StateThree_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, TwoD_StateThree_external_readandwrite) +{ + test_external_user_defined_data(); +} -TEST(sidre, TwoD_StateTensorSmall_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, TwoD_StateTensorSmall_external_readandwrite) +{ + test_external_user_defined_data(); +} -TEST(sidre, TwoD_StateTensorLarge_external_readandwrite) { test_external_user_defined_data(); } +TEST(sidre, TwoD_StateTensorLarge_external_readandwrite) +{ + test_external_user_defined_data(); +} //---------------------------------------------------------------------- int main(int argc, char* argv[]) From 8870d33e6918a99036938d2c712147856539579c Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 27 Nov 2024 15:30:08 -0800 Subject: [PATCH 09/27] revert submodule --- scripts/spack/radiuss-spack-configs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/spack/radiuss-spack-configs b/scripts/spack/radiuss-spack-configs index efe7a45205..22f5feaabf 160000 --- a/scripts/spack/radiuss-spack-configs +++ b/scripts/spack/radiuss-spack-configs @@ -1 +1 @@ -Subproject commit efe7a45205f0c71563c909e26c2f0a54a4c9427a +Subproject commit 22f5feaabfe618339cf621d2734fe0d66077da39 From 60bf2e40d406251cf563dd21573249325a3629a6 Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 4 Dec 2024 16:30:00 -0800 Subject: [PATCH 10/27] change MFEMSidreDataCollection::LoadExternalData to take a group instead of a file path --- RELEASE-NOTES.md | 1 + src/axom/sidre/core/MFEMSidreDataCollection.cpp | 11 ++++++++--- src/axom/sidre/core/MFEMSidreDataCollection.hpp | 5 +++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 45922f3a7f..e5dc79d785 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -35,6 +35,7 @@ to use Open Cascade's file I/O capabilities in support of Quest applications. - ItemCollection and its child classes MapCollection, ListCollection, and IndexedCollection were moved from Sidre to core. The namespace prefix for these classes is now `axom::` instead of `axom::sidre`. The internal usage of these types within Sidre Datastore and Group is unchanged. +- `MFEMSidreDataCollection::LoadExternalData` now takes an optional `Group` parameter and will only load external data from the given `Group` or from the `MFEMSidreDataCollection` instead of the entire `DataStore`. This is instead of a file path that the class already knows. ### Deprecated diff --git a/src/axom/sidre/core/MFEMSidreDataCollection.cpp b/src/axom/sidre/core/MFEMSidreDataCollection.cpp index 3b5806bebe..b0106c368b 100644 --- a/src/axom/sidre/core/MFEMSidreDataCollection.cpp +++ b/src/axom/sidre/core/MFEMSidreDataCollection.cpp @@ -953,18 +953,23 @@ void MFEMSidreDataCollection::Load(const std::string& path, } } -void MFEMSidreDataCollection::LoadExternalData(const std::string& path) +void MFEMSidreDataCollection::LoadExternalData(Group* grp) { #if defined(AXOM_USE_MPI) && defined(MFEM_USE_MPI) if(m_comm != MPI_COMM_NULL) { + if(grp == nullptr) + { + grp = m_bp_grp; + } + IOManager reader(m_comm); - reader.loadExternalData(m_bp_grp->getDataStore()->getRoot(), path); + reader.loadExternalData(grp, get_file_path(name)); } else #endif { - m_bp_grp->loadExternalData(path); + m_bp_grp->loadExternalData(get_file_path(name)); } } diff --git a/src/axom/sidre/core/MFEMSidreDataCollection.hpp b/src/axom/sidre/core/MFEMSidreDataCollection.hpp index d90d8ca0e4..db12661476 100644 --- a/src/axom/sidre/core/MFEMSidreDataCollection.hpp +++ b/src/axom/sidre/core/MFEMSidreDataCollection.hpp @@ -476,8 +476,9 @@ class MFEMSidreDataCollection : public mfem::DataCollection Load(get_file_path(name), "sidre_hdf5"); } - /// Load external data after registering externally owned fields. - void LoadExternalData(const std::string& path); + /// Load external data for the whole MFEMDataCollection unless a specific group is given. + /// @note This must happen after registering externally owned fields. + void LoadExternalData(Group* grp = nullptr); /** @brief Updates the DataCollection's cycle, time, and time-step variables with the values from the data store. */ From 1ad469564371ea6bae0729cc9fdc656886f1bfc4 Mon Sep 17 00:00:00 2001 From: Chris White Date: Mon, 9 Dec 2024 10:56:25 -0800 Subject: [PATCH 11/27] add optional group name and have class act on file name like other functions --- RELEASE-NOTES.md | 4 ++- .../sidre/core/MFEMSidreDataCollection.cpp | 31 ++++++++++++++----- .../sidre/core/MFEMSidreDataCollection.hpp | 10 ++++-- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index e5dc79d785..5dd3aa5247 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -35,7 +35,9 @@ to use Open Cascade's file I/O capabilities in support of Quest applications. - ItemCollection and its child classes MapCollection, ListCollection, and IndexedCollection were moved from Sidre to core. The namespace prefix for these classes is now `axom::` instead of `axom::sidre`. The internal usage of these types within Sidre Datastore and Group is unchanged. -- `MFEMSidreDataCollection::LoadExternalData` now takes an optional `Group` parameter and will only load external data from the given `Group` or from the `MFEMSidreDataCollection` instead of the entire `DataStore`. This is instead of a file path that the class already knows. +- `MFEMSidreDataCollection::LoadExternalData` now takes two optional string parameters, one that is a + filename (defaults to the `name` member variable) and the other is a Group path relative to the base of + the Data Collection itself (defaults to the whole Data Collection). ### Deprecated diff --git a/src/axom/sidre/core/MFEMSidreDataCollection.cpp b/src/axom/sidre/core/MFEMSidreDataCollection.cpp index b0106c368b..6073cf3ab3 100644 --- a/src/axom/sidre/core/MFEMSidreDataCollection.cpp +++ b/src/axom/sidre/core/MFEMSidreDataCollection.cpp @@ -953,23 +953,40 @@ void MFEMSidreDataCollection::Load(const std::string& path, } } -void MFEMSidreDataCollection::LoadExternalData(Group* grp) +void MFEMSidreDataCollection::LoadExternalData(const std::string& filename, const std::string& group_name) { + // Use the user-provided group name or the DataCollection's base group + Group* grp = m_bp_grp; + if(!group_name.empty()) + { + SLIC_ERROR_IF(!m_bp_grp->hasGroup(group_name), + axom::fmt::format("MFEMSidreDataCollection does not have a Sidre Group '{}'", group_name)); + grp = m_bp_grp->getGroup(group_name); + } + + // Use the user-provided file name or the DataCollection's file name + std::string path = name; + if(!filename.empty()) + { + path = filename; + } + path = get_file_path(path); + #if defined(AXOM_USE_MPI) && defined(MFEM_USE_MPI) if(m_comm != MPI_COMM_NULL) { - if(grp == nullptr) - { - grp = m_bp_grp; - } + // The conduit abstraction appears to automatically handle the ".root" + // suffix, but the IOManager does not, so it gets added here + using axom::utilities::string::endsWith; + std::string suffixedPath = endsWith(path, ".root") ? path : path + ".root"; IOManager reader(m_comm); - reader.loadExternalData(grp, get_file_path(name)); + reader.loadExternalData(grp, suffixedPath); } else #endif { - m_bp_grp->loadExternalData(get_file_path(name)); + grp->loadExternalData(path); } } diff --git a/src/axom/sidre/core/MFEMSidreDataCollection.hpp b/src/axom/sidre/core/MFEMSidreDataCollection.hpp index db12661476..b276cfc45d 100644 --- a/src/axom/sidre/core/MFEMSidreDataCollection.hpp +++ b/src/axom/sidre/core/MFEMSidreDataCollection.hpp @@ -476,9 +476,13 @@ class MFEMSidreDataCollection : public mfem::DataCollection Load(get_file_path(name), "sidre_hdf5"); } - /// Load external data for the whole MFEMDataCollection unless a specific group is given. - /// @note This must happen after registering externally owned fields. - void LoadExternalData(Group* grp = nullptr); + /** @brief Load external data for the whole MFEMSidreDataCollection unless a specific group name is given. + * @note This must happen after registering externally owned fields. + * + * @param filename Optional base filename to be loaded, function will add prefix path and cycle + * @param group_name Optional group name to load external data, relative to base of MFEMSidreDataCollection + **/ + void LoadExternalData(const std::string& filename = "", const std::string& group_name = ""); /** @brief Updates the DataCollection's cycle, time, and time-step variables with the values from the data store. */ From a9c21f16248dcf2daaf0929444cffd120368d067 Mon Sep 17 00:00:00 2001 From: Chris White Date: Mon, 9 Dec 2024 14:50:07 -0800 Subject: [PATCH 12/27] add check for loaded size, add broken test for MFEMSidreDataCollection --- .../sidre/core/MFEMSidreDataCollection.cpp | 7 +- .../sidre/core/MFEMSidreDataCollection.hpp | 3 +- .../sidre_read_write_userdefined_data.cpp | 203 +++++++++++++++++- 3 files changed, 203 insertions(+), 10 deletions(-) diff --git a/src/axom/sidre/core/MFEMSidreDataCollection.cpp b/src/axom/sidre/core/MFEMSidreDataCollection.cpp index 6073cf3ab3..026e7fa9f7 100644 --- a/src/axom/sidre/core/MFEMSidreDataCollection.cpp +++ b/src/axom/sidre/core/MFEMSidreDataCollection.cpp @@ -953,14 +953,17 @@ void MFEMSidreDataCollection::Load(const std::string& path, } } -void MFEMSidreDataCollection::LoadExternalData(const std::string& filename, const std::string& group_name) +void MFEMSidreDataCollection::LoadExternalData(const std::string& filename, + const std::string& group_name) { // Use the user-provided group name or the DataCollection's base group Group* grp = m_bp_grp; if(!group_name.empty()) { SLIC_ERROR_IF(!m_bp_grp->hasGroup(group_name), - axom::fmt::format("MFEMSidreDataCollection does not have a Sidre Group '{}'", group_name)); + axom::fmt::format( + "MFEMSidreDataCollection does not have a Sidre Group '{}'", + group_name)); grp = m_bp_grp->getGroup(group_name); } diff --git a/src/axom/sidre/core/MFEMSidreDataCollection.hpp b/src/axom/sidre/core/MFEMSidreDataCollection.hpp index b276cfc45d..2d8b8bea8c 100644 --- a/src/axom/sidre/core/MFEMSidreDataCollection.hpp +++ b/src/axom/sidre/core/MFEMSidreDataCollection.hpp @@ -482,7 +482,8 @@ class MFEMSidreDataCollection : public mfem::DataCollection * @param filename Optional base filename to be loaded, function will add prefix path and cycle * @param group_name Optional group name to load external data, relative to base of MFEMSidreDataCollection **/ - void LoadExternalData(const std::string& filename = "", const std::string& group_name = ""); + void LoadExternalData(const std::string& filename = "", + const std::string& group_name = ""); /** @brief Updates the DataCollection's cycle, time, and time-step variables with the values from the data store. */ diff --git a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp index e27fd7ac60..1b70636f2f 100644 --- a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp +++ b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp @@ -9,6 +9,9 @@ using axom::sidre::DataStore; using axom::sidre::Group; using axom::sidre::IndexType; +#ifdef AXOM_USE_MFEM +using axom::sidre::MFEMSidreDataCollection; +#endif using axom::sidre::View; // This test is meant to mock how Serac stores and loads Quadrature Data. @@ -112,6 +115,7 @@ void fill(T&, double) template <> bool check(const double& state, double value) { + SLIC_INFO(axom::fmt::format("{} == {}", state, value)); return state == value; } @@ -365,22 +369,131 @@ void test_external_user_defined_data() std::string filename = "sidre_external_states"; root->save(filename); - // Create new array to fill with saved data - axom::Array saved_states(size, size); - fill_array(saved_states, -1, false); - // Load data into new array Group* loaded_group = root->createGroup("loaded_data"); loaded_group->load(filename); + + // Verify size correctness + EXPECT_TRUE(loaded_group->hasView("num_states")); + auto loaded_num_states = + loaded_group->getView("num_states")->getData(); + EXPECT_TRUE(num_states == loaded_num_states); + + EXPECT_TRUE(loaded_group->hasView("state_size")); + auto loaded_state_size = + loaded_group->getView("state_size")->getData(); + EXPECT_TRUE(state_size == loaded_state_size); + + EXPECT_TRUE(loaded_group->hasView("total_size")); + auto loaded_total_size = + loaded_group->getView("total_size")->getData(); + EXPECT_TRUE(total_size == loaded_total_size); + + // Create new array to fill with loaded data + axom::Array loaded_states(size, size); + fill_array(loaded_states, -1, false); + + // Load external data EXPECT_TRUE(loaded_group->hasView("states")); - View* new_states_view = loaded_group->getView("states"); - new_states_view->setExternalDataPtr(saved_states.data()); + View* loaded_states_view = loaded_group->getView("states"); + loaded_states_view->setExternalDataPtr(loaded_states.data()); loaded_group->loadExternalData(filename); // Test data was read into the new location and overwrote the bad data - check_array(saved_states); + check_array(loaded_states); +} + +#ifdef AXOM_USE_MFEM + +template +void test_MFEMSidreDataCollection_user_defined_data() +{ + std::string test_name = + ::testing::UnitTest::GetInstance()->current_test_info()->name(); + + // populate data + constexpr IndexType size = 10; + axom::Array states(size, size); + fill_array(states, 0, true); + + // Create MFEMSidreDataCollection + auto* mesh = new mfem::Mesh(mfem::Mesh::MakeCartesian1D(10)); + const bool owns_mesh_data = true; + MFEMSidreDataCollection sdc_writer(test_name, mesh, owns_mesh_data); + Group* bp_group = sdc_writer.GetBPGroup(); + + // get size + auto num_states = static_cast(states.size()); + auto state_size = static_cast(sizeof(*(states.begin()))); + auto total_size = num_states * state_size; + auto num_uint8s = total_size / sizeof(std::uint8_t); + + SLIC_INFO(axom::fmt::format("Num of States={}", num_states)); + SLIC_INFO(axom::fmt::format("State Size={}", state_size)); + SLIC_INFO(axom::fmt::format("Total Size={}", total_size)); + SLIC_INFO( + axom::fmt::format("Total Size/State Size={}", total_size / state_size)); + SLIC_INFO(axom::fmt::format("Num of uint8={}", num_uint8s)); + + // write shape + bp_group->createViewScalar("num_states", num_states); + bp_group->createViewScalar("state_size", state_size); + bp_group->createViewScalar("total_size", total_size); + + // Add states as an external buffer + View* states_view = bp_group->createView("states"); + states_view->setExternalDataPtr(axom::sidre::UINT8_ID, + num_uint8s, + states.data()); + + // Save the array data in to a file + #if defined(AXOM_USE_MPI) && defined(MFEM_USE_MPI) + sdc_writer.SetComm(MPI_COMM_WORLD); + #endif + sdc_writer.SetCycle(0); + sdc_writer.Save(); + + // Load data into new Data Collection + MFEMSidreDataCollection sdc_reader(test_name); + #if defined(AXOM_USE_MPI) && defined(MFEM_USE_MPI) + sdc_reader.SetComm(MPI_COMM_WORLD); + #endif + sdc_reader.Load(); + + Group* loaded_bp_group = sdc_reader.GetBPGroup(); + + // Verify size correctness + EXPECT_TRUE(loaded_bp_group->hasView("num_states")); + auto loaded_num_states = + loaded_bp_group->getView("num_states")->getData(); + EXPECT_TRUE(num_states == loaded_num_states); + + EXPECT_TRUE(loaded_bp_group->hasView("state_size")); + auto loaded_state_size = + loaded_bp_group->getView("state_size")->getData(); + EXPECT_TRUE(state_size == loaded_state_size); + + EXPECT_TRUE(loaded_bp_group->hasView("total_size")); + auto loaded_total_size = + loaded_bp_group->getView("total_size")->getData(); + EXPECT_TRUE(total_size == loaded_total_size); + + // Create new array to fill with loaded data + axom::Array loaded_states(size, size); + fill_array(loaded_states, -1, false); + + // Load external data + EXPECT_TRUE(loaded_bp_group->hasView("states")); + View* loaded_states_view = loaded_bp_group->getView("states"); + loaded_states_view->setExternalDataPtr(loaded_states.data()); + sdc_reader.LoadExternalData(); + + // Test data was read into the new location and overwrote the bad data + check_array(loaded_states); } +#endif // AXOM_USE_MFEM + //------------------------------------------------------------------------------ TEST(sidre, OneD_double_readandwrite) { test_user_defined_data(); } @@ -503,6 +616,74 @@ TEST(sidre, TwoD_StateTensorLarge_external_readandwrite) test_external_user_defined_data(); } +//------------------------- + +#ifdef AXOM_USE_MFEM + +TEST(sidre, OneD_double_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} +/* +TEST(sidre, OneD_StateOne_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} + +TEST(sidre, OneD_StateTwo_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} + +TEST(sidre, OneD_StateThree_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} + +TEST(sidre, OneD_StateTensorSmall_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} + +TEST(sidre, OneD_StateTensorLarge_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} + +//------------------------- + +TEST(sidre, TwoD_double_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} + +TEST(sidre, TwoD_StateOne_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} + +TEST(sidre, TwoD_StateTwo_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} + +TEST(sidre, TwoD_StateThree_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} + +TEST(sidre, TwoD_StateTensorSmall_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} + +TEST(sidre, TwoD_StateTensorLarge_MFEMSidreDataCollection_readandwrite) +{ + test_MFEMSidreDataCollection_user_defined_data(); +} +*/ +#endif // AXOM_USE_MFEM + //---------------------------------------------------------------------- int main(int argc, char* argv[]) { @@ -511,7 +692,15 @@ int main(int argc, char* argv[]) ::testing::InitGoogleTest(&argc, argv); axom::slic::SimpleLogger logger; +#ifdef AXOM_USE_MPI + MPI_Init(&argc, &argv); +#endif + result = RUN_ALL_TESTS(); +#ifdef AXOM_USE_MPI + MPI_Finalize(); +#endif + return result; } From 1aaa3f7c680868000779b61fb670c14e4e8a5aa0 Mon Sep 17 00:00:00 2001 From: Chris White Date: Tue, 10 Dec 2024 16:17:53 -0800 Subject: [PATCH 13/27] add test for loading external data piecemeal --- src/axom/sidre/tests/spio/spio_parallel.hpp | 157 +++++++++++++++++++- 1 file changed, 149 insertions(+), 8 deletions(-) diff --git a/src/axom/sidre/tests/spio/spio_parallel.hpp b/src/axom/sidre/tests/spio/spio_parallel.hpp index 974e7d5241..12e09ba0ea 100644 --- a/src/axom/sidre/tests/spio/spio_parallel.hpp +++ b/src/axom/sidre/tests/spio/spio_parallel.hpp @@ -359,7 +359,150 @@ TEST(spio_parallel, external_writeread) View* view2 = root2->getView("fields2/b/external_undescribed"); view2->setExternalDataPtr(restored_vals2); - reader.loadExternalData(root2, "out_spio_external_write_read.root"); + reader.loadExternalData(root2, file_name + ROOT_EXT); + + enum SpioTestResult + { + SPIO_TEST_SUCCESS = 0, + HIERARCHY_ERROR = 1 << 0, + EXT_ARRAY_ERROR = 1 << 1, + EXT_UNDESC_ERROR = 1 << 2 + }; + int result = SPIO_TEST_SUCCESS; + + /* + * Verify that the contents of ds2 match those written from ds. + */ + EXPECT_TRUE(ds2->getRoot()->isEquivalentTo(root1)); + if(!ds2->getRoot()->isEquivalentTo(root1)) + { + result |= HIERARCHY_ERROR; + } + SLIC_WARNING_IF(result & HIERARCHY_ERROR, "Tree layouts don't match"); + + EXPECT_EQ(view1->getNumElements(), nvals); + if(view1->getNumElements() != nvals) + { + result |= EXT_ARRAY_ERROR; + } + else + { + for(int i = 0; i < nvals; ++i) + { + EXPECT_EQ(orig_vals1[i], restored_vals1[i]); + if(orig_vals1[i] != restored_vals1[i]) + { + result |= EXT_ARRAY_ERROR; + break; + } + } + } + SLIC_WARNING_IF(result & EXT_ARRAY_ERROR, + "External_array was not correctly loaded"); + + /* + * external_undescribed was not written to disk (since it is undescribed) + * make sure it was not read in. + */ + for(int i = 0; i < nvals; ++i) + { + EXPECT_EQ(-1, restored_vals2[i]); + if(-1 != restored_vals2[i]) + { + result |= EXT_UNDESC_ERROR; + break; + } + } + SLIC_WARNING_IF(result & EXT_UNDESC_ERROR, + "External_undescribed data was modified."); + + delete ds1; + delete ds2; +} + +//------------------------------------------------------------------------------ +TEST(spio_parallel, external_piecemeal_writeread) +{ + if(PROTOCOL != "sidre_hdf5") + { + SUCCEED() << "Loading external data in spio only currently supported " + << " for 'sidre_hdf5' protocol"; + return; + } + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + + int num_ranks; + MPI_Comm_size(MPI_COMM_WORLD, &num_ranks); + + const int num_output = numOutputFiles(num_ranks); + + const int nvals = 10; + int orig_vals1[nvals], orig_vals2[nvals]; + for(int i = 0; i < 10; i++) + { + orig_vals1[i] = (i + 10) * (404 - my_rank - i); + orig_vals2[i] = (i + 10) * (404 - my_rank - i) + 20; + } + + /* + * Create a DataStore and give it a small hierarchy of groups and views. + * + * The views are filled with repeatable nonsense data that will vary based + * on rank. + */ + DataStore* ds1 = new DataStore(); + + Group* root1 = ds1->getRoot(); + + Group* flds1 = root1->createGroup("fields1"); + Group* flds2 = root1->createGroup("fields2"); + + flds1->createView("external_array", axom::sidre::INT_ID, nvals, orig_vals1); + flds2->createView("external_array", axom::sidre::INT_ID, nvals, orig_vals2); + + /* + * Contents of the DataStore written to files with IOManager. + */ + const int num_files = num_output; + IOManager writer(MPI_COMM_WORLD); + + const std::string file_name = "out_spio_external_piecemeal_write_read"; + + writer.write(root1, num_files, file_name, PROTOCOL); + + /* + * Create another DataStore than holds nothing but the root group. + */ + DataStore* ds2 = new DataStore(); + Group* root2 = ds2->getRoot(); + + /* + * Read from the files that were written above. + */ + IOManager reader(MPI_COMM_WORLD); + + reader.read(root2, file_name + ROOT_EXT); + + int restored_vals1[nvals], restored_vals2[nvals]; + for(int i = 0; i < nvals; ++i) + { + restored_vals1[i] = -1; + restored_vals2[i] = -1; + } + + View* view1 = root2->getView("fields1/external_array"); + view1->setExternalDataPtr(restored_vals1); + + View* view2 = root2->getView("fields2/external_array"); + view2->setExternalDataPtr(restored_vals2); + + // load external arrays one at a time + EXPECT_TRUE(root2->hasGroup("fields1")); + reader.loadExternalData(root2->getGroup("fields1"), file_name + ROOT_EXT); + EXPECT_TRUE(root2->hasGroup("fields2")); + reader.loadExternalData(root2->getGroup("fields2"), file_name + ROOT_EXT); enum SpioTestResult { @@ -726,6 +869,8 @@ TEST(spio_parallel, parallel_increase_procs) MPI_Comm_split(MPI_COMM_WORLD, my_rank, 0, &split_comm); } + const std::string file_name = "out_spio_parallel_increase_procs"; + DataStore* ds = new DataStore(); if(my_rank <= top_output_rank) { @@ -748,8 +893,6 @@ TEST(spio_parallel, parallel_increase_procs) int num_files = 1; axom::sidre::IOManager writer(split_comm); - const std::string file_name = "out_spio_parallel_increase_procs"; - writer.write(root, num_files, file_name, PROTOCOL); } @@ -763,8 +906,7 @@ TEST(spio_parallel, parallel_increase_procs) IOManager reader(MPI_COMM_WORLD); - const std::string root_name = "out_spio_parallel_increase_procs.root"; - reader.read(ds2->getRoot(), root_name); + reader.read(ds2->getRoot(), file_name + ROOT_EXT); /* * Verify that the contents of ds2 on rank 0 match those written from ds. @@ -890,8 +1032,7 @@ TEST(spio_parallel, parallel_decrease_procs) { IOManager reader(split_comm); - const std::string root_name = "out_spio_parallel_decrease_procs.root"; - reader.read(ds2->getRoot(), root_name); + reader.read(ds2->getRoot(), file_name + ROOT_EXT); Group* ds2_root = ds2->getRoot(); @@ -1021,7 +1162,7 @@ TEST(spio_parallel, sidre_simple_blueprint_example) // Add the bp index to the root file writer.writeBlueprintIndexToRootFile(&ds, "mesh", - "out_spio_blueprint_example.root", + file_name + ROOT_EXT, "mesh"); #endif // AXOM_USE_HDF5 From a90e98c78ce4c7c045553c8c5de710ae258daf25 Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 11 Dec 2024 11:23:00 -0800 Subject: [PATCH 14/27] fix test to show failure --- src/axom/sidre/tests/spio/spio_parallel.hpp | 35 +++++++++++++-------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/axom/sidre/tests/spio/spio_parallel.hpp b/src/axom/sidre/tests/spio/spio_parallel.hpp index 12e09ba0ea..864586cfbd 100644 --- a/src/axom/sidre/tests/spio/spio_parallel.hpp +++ b/src/axom/sidre/tests/spio/spio_parallel.hpp @@ -498,7 +498,12 @@ TEST(spio_parallel, external_piecemeal_writeread) View* view2 = root2->getView("fields2/external_array"); view2->setExternalDataPtr(restored_vals2); - // load external arrays one at a time + // Swap these two sections to show error + + // Section 1: (Works) Load all external arrays + //reader.loadExternalData(root2, file_name + ROOT_EXT); + + // Section 2: (Doesn't work) Load external arrays one at a time EXPECT_TRUE(root2->hasGroup("fields1")); reader.loadExternalData(root2->getGroup("fields1"), file_name + ROOT_EXT); EXPECT_TRUE(root2->hasGroup("fields2")); @@ -541,23 +546,27 @@ TEST(spio_parallel, external_piecemeal_writeread) } } SLIC_WARNING_IF(result & EXT_ARRAY_ERROR, - "External_array was not correctly loaded"); + "External_array1 was not correctly loaded"); - /* - * external_undescribed was not written to disk (since it is undescribed) - * make sure it was not read in. - */ - for(int i = 0; i < nvals; ++i) + EXPECT_EQ(view2->getNumElements(), nvals); + if(view2->getNumElements() != nvals) { - EXPECT_EQ(-1, restored_vals2[i]); - if(-1 != restored_vals2[i]) + result |= EXT_ARRAY_ERROR; + } + else + { + for(int i = 0; i < nvals; ++i) { - result |= EXT_UNDESC_ERROR; - break; + EXPECT_EQ(orig_vals2[i], restored_vals2[i]); + if(orig_vals2[i] != restored_vals2[i]) + { + result |= EXT_ARRAY_ERROR; + break; + } } } - SLIC_WARNING_IF(result & EXT_UNDESC_ERROR, - "External_undescribed data was modified."); + SLIC_WARNING_IF(result & EXT_ARRAY_ERROR, + "External_array2 was not correctly loaded"); delete ds1; delete ds2; From b02cd7de0f6a565f30ef9687c60433aaa04f633f Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 11 Dec 2024 11:23:28 -0800 Subject: [PATCH 15/27] remove unused error --- src/axom/sidre/tests/spio/spio_parallel.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/axom/sidre/tests/spio/spio_parallel.hpp b/src/axom/sidre/tests/spio/spio_parallel.hpp index 864586cfbd..938af4387f 100644 --- a/src/axom/sidre/tests/spio/spio_parallel.hpp +++ b/src/axom/sidre/tests/spio/spio_parallel.hpp @@ -514,7 +514,6 @@ TEST(spio_parallel, external_piecemeal_writeread) SPIO_TEST_SUCCESS = 0, HIERARCHY_ERROR = 1 << 0, EXT_ARRAY_ERROR = 1 << 1, - EXT_UNDESC_ERROR = 1 << 2 }; int result = SPIO_TEST_SUCCESS; From 4256802e3de1c2467377f91b2c7d2b9419b3f421 Mon Sep 17 00:00:00 2001 From: Chris White Date: Thu, 2 Jan 2025 15:30:26 -0800 Subject: [PATCH 16/27] general cleanup --- src/axom/sidre/tests/spio/spio_parallel.hpp | 28 ++++++++++++--------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/axom/sidre/tests/spio/spio_parallel.hpp b/src/axom/sidre/tests/spio/spio_parallel.hpp index 938af4387f..1c1fd29496 100644 --- a/src/axom/sidre/tests/spio/spio_parallel.hpp +++ b/src/axom/sidre/tests/spio/spio_parallel.hpp @@ -478,13 +478,7 @@ TEST(spio_parallel, external_piecemeal_writeread) DataStore* ds2 = new DataStore(); Group* root2 = ds2->getRoot(); - /* - * Read from the files that were written above. - */ - IOManager reader(MPI_COMM_WORLD); - - reader.read(root2, file_name + ROOT_EXT); - + // pollute values so we know they are changed int restored_vals1[nvals], restored_vals2[nvals]; for(int i = 0; i < nvals; ++i) { @@ -492,11 +486,18 @@ TEST(spio_parallel, external_piecemeal_writeread) restored_vals2[i] = -1; } + /* + * Read from the files that were written above. + */ + IOManager reader(MPI_COMM_WORLD); + + reader.read(root2, file_name + ROOT_EXT); + + reader.read(root2->getGroup("fields1"), file_name + ROOT_EXT); + EXPECT_TRUE(root2->hasGroup("fields1")); View* view1 = root2->getView("fields1/external_array"); view1->setExternalDataPtr(restored_vals1); - - View* view2 = root2->getView("fields2/external_array"); - view2->setExternalDataPtr(restored_vals2); + reader.loadExternalData(root2->getGroup("fields1"), file_name + ROOT_EXT); // Swap these two sections to show error @@ -504,9 +505,12 @@ TEST(spio_parallel, external_piecemeal_writeread) //reader.loadExternalData(root2, file_name + ROOT_EXT); // Section 2: (Doesn't work) Load external arrays one at a time - EXPECT_TRUE(root2->hasGroup("fields1")); - reader.loadExternalData(root2->getGroup("fields1"), file_name + ROOT_EXT); + + + reader.read(root2->getGroup("fields2"), file_name + ROOT_EXT); EXPECT_TRUE(root2->hasGroup("fields2")); + View* view2 = root2->getView("fields2/external_array"); + view2->setExternalDataPtr(restored_vals2); reader.loadExternalData(root2->getGroup("fields2"), file_name + ROOT_EXT); enum SpioTestResult From 2ce97b6028de30d60e116468ba0ad0d6882ab93b Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 8 Jan 2025 20:11:58 -0800 Subject: [PATCH 17/27] fix loadexternaldata to work since SPIO currently requires the root, error if non-root is requested --- src/axom/sidre/core/MFEMSidreDataCollection.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/axom/sidre/core/MFEMSidreDataCollection.cpp b/src/axom/sidre/core/MFEMSidreDataCollection.cpp index 026e7fa9f7..fa82f81343 100644 --- a/src/axom/sidre/core/MFEMSidreDataCollection.cpp +++ b/src/axom/sidre/core/MFEMSidreDataCollection.cpp @@ -957,9 +957,16 @@ void MFEMSidreDataCollection::LoadExternalData(const std::string& filename, const std::string& group_name) { // Use the user-provided group name or the DataCollection's base group - Group* grp = m_bp_grp; + Group* grp = m_bp_grp->getDataStore()->getRoot(); if(!group_name.empty()) { + #if defined(AXOM_USE_MPI) && defined(MFEM_USE_MPI) + if(m_comm != MPI_COMM_NULL) + { + SLIC_ERROR("Loading external data with a group name is not supported in parallel."); + } + #endif + SLIC_ERROR_IF(!m_bp_grp->hasGroup(group_name), axom::fmt::format( "MFEMSidreDataCollection does not have a Sidre Group '{}'", @@ -982,7 +989,6 @@ void MFEMSidreDataCollection::LoadExternalData(const std::string& filename, // suffix, but the IOManager does not, so it gets added here using axom::utilities::string::endsWith; std::string suffixedPath = endsWith(path, ".root") ? path : path + ".root"; - IOManager reader(m_comm); reader.loadExternalData(grp, suffixedPath); } From 97b9443b732094aca0b20fd7c32ca9dd38d4bd08 Mon Sep 17 00:00:00 2001 From: Chris White Date: Thu, 9 Jan 2025 13:26:54 -0800 Subject: [PATCH 18/27] style --- src/axom/sidre/core/MFEMSidreDataCollection.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/axom/sidre/core/MFEMSidreDataCollection.cpp b/src/axom/sidre/core/MFEMSidreDataCollection.cpp index fa82f81343..23da04568c 100644 --- a/src/axom/sidre/core/MFEMSidreDataCollection.cpp +++ b/src/axom/sidre/core/MFEMSidreDataCollection.cpp @@ -960,12 +960,14 @@ void MFEMSidreDataCollection::LoadExternalData(const std::string& filename, Group* grp = m_bp_grp->getDataStore()->getRoot(); if(!group_name.empty()) { - #if defined(AXOM_USE_MPI) && defined(MFEM_USE_MPI) + #if defined(AXOM_USE_MPI) && defined(MFEM_USE_MPI) if(m_comm != MPI_COMM_NULL) { - SLIC_ERROR("Loading external data with a group name is not supported in parallel."); + SLIC_ERROR( + "Loading external data with a group name is not supported in " + "parallel."); } - #endif + #endif SLIC_ERROR_IF(!m_bp_grp->hasGroup(group_name), axom::fmt::format( From ea4da5ae0f840995023c4ffa963de364f82278b2 Mon Sep 17 00:00:00 2001 From: Chris White Date: Thu, 9 Jan 2025 13:28:59 -0800 Subject: [PATCH 19/27] Style --- src/axom/sidre/tests/spio/spio_parallel.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/axom/sidre/tests/spio/spio_parallel.hpp b/src/axom/sidre/tests/spio/spio_parallel.hpp index 1c1fd29496..aec050b716 100644 --- a/src/axom/sidre/tests/spio/spio_parallel.hpp +++ b/src/axom/sidre/tests/spio/spio_parallel.hpp @@ -506,7 +506,6 @@ TEST(spio_parallel, external_piecemeal_writeread) // Section 2: (Doesn't work) Load external arrays one at a time - reader.read(root2->getGroup("fields2"), file_name + ROOT_EXT); EXPECT_TRUE(root2->hasGroup("fields2")); View* view2 = root2->getView("fields2/external_array"); From 4f04b5413da7fe922aee42036d18306ac200bd71 Mon Sep 17 00:00:00 2001 From: Chris White Date: Thu, 9 Jan 2025 13:29:22 -0800 Subject: [PATCH 20/27] add test for load external data on mfem sidre datacollection --- .../sidre/tests/sidre_mfem_datacollection.cpp | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/axom/sidre/tests/sidre_mfem_datacollection.cpp b/src/axom/sidre/tests/sidre_mfem_datacollection.cpp index d3bb3601f2..b306e0e300 100644 --- a/src/axom/sidre/tests/sidre_mfem_datacollection.cpp +++ b/src/axom/sidre/tests/sidre_mfem_datacollection.cpp @@ -256,6 +256,56 @@ TEST(sidre_datacollection, dc_reload_gf_vdim) EXPECT_TRUE(sdc_reader.verifyMeshBlueprint()); } +TEST(sidre_datacollection, dc_reload_externaldata) +{ + const std::string view_name = "external_data"; + + // Create DC + auto mesh = mfem::Mesh::MakeCartesian1D(10); + const bool owns_mesh_data = true; + MFEMSidreDataCollection sdc_writer(testName(), &mesh, owns_mesh_data); +#if defined(AXOM_USE_MPI) && defined(MFEM_USE_MPI) + sdc_writer.SetComm(MPI_COMM_WORLD); +#endif + sdc_writer.SetCycle(0); + + // Create external buffer and add it to DC + axom::Array writer_data {1, 2, 3, 4}; + axom::sidre::Group* writer_bp_group = sdc_writer.GetBPGroup(); + axom::sidre::View* writer_external_view = writer_bp_group->createView(view_name); + writer_external_view->setExternalDataPtr(axom::sidre::INT64_ID, + writer_data.size(), + writer_data.data()); + EXPECT_TRUE(writer_bp_group->hasView(view_name)); + + sdc_writer.Save(); + + // Load DC from file + MFEMSidreDataCollection sdc_reader(testName()); +#if defined(AXOM_USE_MPI) && defined(MFEM_USE_MPI) + sdc_reader.SetComm(MPI_COMM_WORLD); +#endif + // Note: this will recreate the external view but not load the external data yet + sdc_reader.Load(); + axom::sidre::Group* reader_bp_group = sdc_reader.GetBPGroup(); + EXPECT_TRUE(reader_bp_group->hasView(view_name)); + axom::sidre::View* reader_external_view = reader_bp_group->getView(view_name); + + // Create external buffer with wrong data and load previously saved data into it + axom::Array reader_data {5, 6, 7, 8}; + reader_external_view->setExternalDataPtr(reader_data.data()); + sdc_reader.LoadExternalData(); + + EXPECT_TRUE(writer_data.size() == reader_data.size()); + SLIC_INFO(axom::fmt::format("~~~~ {}", writer_data.size())); + for(int i = 0; i < reader_data.size(); ++i) + { + SLIC_INFO(axom::fmt::format("~~~~ {} == {}", reader_data[i], writer_data[i])); + EXPECT_TRUE(reader_data[i] == writer_data[i]); + } + SLIC_INFO("~~~ END"); +} + TEST(sidre_datacollection, dc_reload_mesh) { const std::string field_name = "test_field"; From ce802f7d2f90159d0733236d5cdf7b409fb71623 Mon Sep 17 00:00:00 2001 From: Chris White Date: Thu, 9 Jan 2025 13:49:26 -0800 Subject: [PATCH 21/27] fix double free --- src/axom/sidre/tests/sidre_mfem_datacollection.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/axom/sidre/tests/sidre_mfem_datacollection.cpp b/src/axom/sidre/tests/sidre_mfem_datacollection.cpp index b306e0e300..e56bce61aa 100644 --- a/src/axom/sidre/tests/sidre_mfem_datacollection.cpp +++ b/src/axom/sidre/tests/sidre_mfem_datacollection.cpp @@ -264,6 +264,8 @@ TEST(sidre_datacollection, dc_reload_externaldata) auto mesh = mfem::Mesh::MakeCartesian1D(10); const bool owns_mesh_data = true; MFEMSidreDataCollection sdc_writer(testName(), &mesh, owns_mesh_data); + // After creation set owning to false so data doesn't get double free'd by reader and writer + sdc_writer.SetOwnData(false); #if defined(AXOM_USE_MPI) && defined(MFEM_USE_MPI) sdc_writer.SetComm(MPI_COMM_WORLD); #endif From b986f088151f0133d4247aa5895df44c939de530 Mon Sep 17 00:00:00 2001 From: Chris White Date: Thu, 9 Jan 2025 13:51:06 -0800 Subject: [PATCH 22/27] style --- src/axom/sidre/tests/sidre_mfem_datacollection.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/axom/sidre/tests/sidre_mfem_datacollection.cpp b/src/axom/sidre/tests/sidre_mfem_datacollection.cpp index e56bce61aa..f20e683823 100644 --- a/src/axom/sidre/tests/sidre_mfem_datacollection.cpp +++ b/src/axom/sidre/tests/sidre_mfem_datacollection.cpp @@ -274,7 +274,8 @@ TEST(sidre_datacollection, dc_reload_externaldata) // Create external buffer and add it to DC axom::Array writer_data {1, 2, 3, 4}; axom::sidre::Group* writer_bp_group = sdc_writer.GetBPGroup(); - axom::sidre::View* writer_external_view = writer_bp_group->createView(view_name); + axom::sidre::View* writer_external_view = + writer_bp_group->createView(view_name); writer_external_view->setExternalDataPtr(axom::sidre::INT64_ID, writer_data.size(), writer_data.data()); From c561c267bc01b7ecdae9e44bdfd15f739d79f4e5 Mon Sep 17 00:00:00 2001 From: Chris White Date: Thu, 9 Jan 2025 13:55:34 -0800 Subject: [PATCH 23/27] fix release notes --- RELEASE-NOTES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 5dd3aa5247..57106ce349 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -36,8 +36,8 @@ to use Open Cascade's file I/O capabilities in support of Quest applications. to core. The namespace prefix for these classes is now `axom::` instead of `axom::sidre`. The internal usage of these types within Sidre Datastore and Group is unchanged. - `MFEMSidreDataCollection::LoadExternalData` now takes two optional string parameters, one that is a - filename (defaults to the `name` member variable) and the other is a Group path relative to the base of - the Data Collection itself (defaults to the whole Data Collection). + filename (defaults to the `name` member variable) and the other is a `Group` path relative to the base of + the Data Collection itself (defaults to the root of the `DataStore`). ### Deprecated From b0d6aaba13948b6831ec773536872e7954bb3047 Mon Sep 17 00:00:00 2001 From: Chris White Date: Thu, 9 Jan 2025 14:34:13 -0800 Subject: [PATCH 24/27] fix spio test --- src/axom/sidre/tests/spio/spio_parallel.hpp | 38 ++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/axom/sidre/tests/spio/spio_parallel.hpp b/src/axom/sidre/tests/spio/spio_parallel.hpp index aec050b716..c2a5ba1314 100644 --- a/src/axom/sidre/tests/spio/spio_parallel.hpp +++ b/src/axom/sidre/tests/spio/spio_parallel.hpp @@ -493,24 +493,38 @@ TEST(spio_parallel, external_piecemeal_writeread) reader.read(root2, file_name + ROOT_EXT); - reader.read(root2->getGroup("fields1"), file_name + ROOT_EXT); + // Swap these two sections to show lack of piecemeal loading + + // Section 1: (Works) Load all external arrays EXPECT_TRUE(root2->hasGroup("fields1")); - View* view1 = root2->getView("fields1/external_array"); + flds1 = root2->getGroup("fields1"); + EXPECT_TRUE(flds1->hasView("external_array")); + View* view1 = flds1->getView("external_array"); view1->setExternalDataPtr(restored_vals1); - reader.loadExternalData(root2->getGroup("fields1"), file_name + ROOT_EXT); - // Swap these two sections to show error + EXPECT_TRUE(root2->hasGroup("fields2")); + flds2 = root2->getGroup("fields2"); + EXPECT_TRUE(flds2->hasView("external_array")); + View* view2 = flds2->getView("external_array"); + view2->setExternalDataPtr(restored_vals2); - // Section 1: (Works) Load all external arrays - //reader.loadExternalData(root2, file_name + ROOT_EXT); + reader.loadExternalData(root2, file_name + ROOT_EXT); + // TODO: convert test to this when functionality works // Section 2: (Doesn't work) Load external arrays one at a time - - reader.read(root2->getGroup("fields2"), file_name + ROOT_EXT); - EXPECT_TRUE(root2->hasGroup("fields2")); - View* view2 = root2->getView("fields2/external_array"); - view2->setExternalDataPtr(restored_vals2); - reader.loadExternalData(root2->getGroup("fields2"), file_name + ROOT_EXT); + // EXPECT_TRUE(root2->hasGroup("fields1")); + // flds1 = root2->getGroup("fields1"); + // EXPECT_TRUE(flds1->hasView("external_array")); + // View* view1 = flds1->getView("external_array"); + // view1->setExternalDataPtr(restored_vals1); + // reader.loadExternalData(flds1, file_name + ROOT_EXT); + + // EXPECT_TRUE(root2->hasGroup("fields2")); + // flds2 = root2->getGroup("fields2"); + // EXPECT_TRUE(flds2->hasView("external_array")); + // View* view2 = flds2->getView("external_array"); + // view2->setExternalDataPtr(restored_vals2); + // reader.loadExternalData(flds2, file_name + ROOT_EXT); enum SpioTestResult { From b93b63ed0e1ba3b8f9713af33f16b198e1088535 Mon Sep 17 00:00:00 2001 From: Chris White Date: Thu, 9 Jan 2025 14:34:44 -0800 Subject: [PATCH 25/27] clarify comment --- src/axom/sidre/tests/spio/spio_parallel.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/axom/sidre/tests/spio/spio_parallel.hpp b/src/axom/sidre/tests/spio/spio_parallel.hpp index c2a5ba1314..6f4e735271 100644 --- a/src/axom/sidre/tests/spio/spio_parallel.hpp +++ b/src/axom/sidre/tests/spio/spio_parallel.hpp @@ -495,7 +495,7 @@ TEST(spio_parallel, external_piecemeal_writeread) // Swap these two sections to show lack of piecemeal loading - // Section 1: (Works) Load all external arrays + // Section 1: (Works) Load all external arrays at a single time EXPECT_TRUE(root2->hasGroup("fields1")); flds1 = root2->getGroup("fields1"); EXPECT_TRUE(flds1->hasView("external_array")); From 44a99b236b9de447549134a4f3df0717afd03221 Mon Sep 17 00:00:00 2001 From: Chris White Date: Fri, 10 Jan 2025 17:41:54 -0800 Subject: [PATCH 26/27] Fix words Co-authored-by: Kenneth Weiss --- src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp index 1b70636f2f..af3dca3aaf 100644 --- a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp +++ b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp @@ -365,7 +365,7 @@ void test_external_user_defined_data() num_uint8s, states.data()); - // Save the array data in to a file + // Save the array data into a file std::string filename = "sidre_external_states"; root->save(filename); @@ -446,7 +446,7 @@ void test_MFEMSidreDataCollection_user_defined_data() num_uint8s, states.data()); - // Save the array data in to a file + // Save the array data into a file #if defined(AXOM_USE_MPI) && defined(MFEM_USE_MPI) sdc_writer.SetComm(MPI_COMM_WORLD); #endif From 3066766a4c46e337a5f8aea3ecb8013a34f09226 Mon Sep 17 00:00:00 2001 From: Chris White Date: Fri, 10 Jan 2025 17:53:01 -0800 Subject: [PATCH 27/27] reenable tests i forgot i wrote --- src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp index af3dca3aaf..ea706dcb96 100644 --- a/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp +++ b/src/axom/sidre/tests/sidre_read_write_userdefined_data.cpp @@ -624,7 +624,7 @@ TEST(sidre, OneD_double_MFEMSidreDataCollection_readandwrite) { test_MFEMSidreDataCollection_user_defined_data(); } -/* + TEST(sidre, OneD_StateOne_MFEMSidreDataCollection_readandwrite) { test_MFEMSidreDataCollection_user_defined_data(); @@ -681,7 +681,7 @@ TEST(sidre, TwoD_StateTensorLarge_MFEMSidreDataCollection_readandwrite) { test_MFEMSidreDataCollection_user_defined_data(); } -*/ + #endif // AXOM_USE_MFEM //----------------------------------------------------------------------