From 105568d3d89e8620fc4cf044e2dadd86bc659dfa Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Mon, 9 Dec 2024 14:37:35 +0000 Subject: [PATCH 01/19] Modify build system for wider-scale use of XIOS --- core/src/CMakeLists.txt | 9 +++ core/src/ParaGridIO.cpp | 4 +- core/test/CMakeLists.txt | 115 ++++++++++++++++---------------- core/test/ConfigOutput_test.cpp | 5 +- core/test/ParaGrid_test.cpp | 7 +- core/test/RectGrid_test.cpp | 3 +- 6 files changed, 78 insertions(+), 65 deletions(-) diff --git a/core/src/CMakeLists.txt b/core/src/CMakeLists.txt index b3d973f76..2f841c848 100644 --- a/core/src/CMakeLists.txt +++ b/core/src/CMakeLists.txt @@ -1,5 +1,14 @@ # Sources for the main neXtSIM model +if(ENABLE_XIOS) + set(XIOS_INCLUDE_LIST + "${xios_INCLUDES}" + "${xios_EXTERNS}/blitz/" + "${xios_EXTERNS}/rapidxml/include" + ) + set(NextsimIncludeDirs "${NextsimIncludeDirs}" "${XIOS_INCLUDE_LIST}") +endif() + set(BaseSources "Logged.cpp" "ModelConfig.cpp" diff --git a/core/src/ParaGridIO.cpp b/core/src/ParaGridIO.cpp index 63f47cb48..a6feaf874 100644 --- a/core/src/ParaGridIO.cpp +++ b/core/src/ParaGridIO.cpp @@ -1,7 +1,7 @@ /*! * @file ParaGridIO.cpp * - * @date Oct 24, 2022 + * @date 09 Dec 2024 * @author Tim Spain */ @@ -227,7 +227,7 @@ ModelState ParaGridIO::readForcingTimeStatic( std::vector timeVec(timeDim.getSize()); timeVar.getVar(timeVec.data()); // Get the index of the largest TimePoint less than the target. - targetTIndex = std::find_if(begin(timeVec), end(timeVec), [time](double t) { + targetTIndex = std::find_if(std::begin(timeVec), std::end(timeVec), [time](double t) { return (TimePoint() + Duration(t)) > time; }) - timeVec.begin(); // Rather than the first that is greater than, get the last that is less diff --git a/core/test/CMakeLists.txt b/core/test/CMakeLists.txt index ed8e02992..e2d440cff 100644 --- a/core/test/CMakeLists.txt +++ b/core/test/CMakeLists.txt @@ -19,59 +19,13 @@ include_directories(${COMMON_INCLUDE_DIRS}) set(MODEL_INCLUDE_DIR "../../core/src/discontinuousgalerkin") if(ENABLE_MPI) - # Generate partition files needed for MPI test from respective cdl files - add_custom_command( - OUTPUT partition_metadata_3.nc - COMMAND - ncgen -b -o partition_metadata_3.nc ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_3.cdl - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_3.cdl - ) - add_custom_command( - OUTPUT partition_metadata_2.nc - COMMAND - ncgen -b -o partition_metadata_2.nc ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_2.cdl - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_2.cdl - ) - add_custom_target( - generate_partition_files - ALL - DEPENDS partition_metadata_3.nc partition_metadata_2.nc - ) - - add_executable(testRectGrid_MPI3 "RectGrid_test.cpp" "MainMPI.cpp") - target_compile_definitions( - testRectGrid_MPI3 - PRIVATE TEST_FILES_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" - ) - target_include_directories( - testRectGrid_MPI3 - PRIVATE ${MODEL_INCLUDE_DIR} "${ModulesRoot}/StructureModule" - ) - target_link_libraries(testRectGrid_MPI3 PRIVATE nextsimlib doctest::doctest) - - add_executable(testParaGrid_MPI2 "ParaGrid_test.cpp" "MainMPI.cpp") - target_compile_definitions( - testParaGrid_MPI2 - PRIVATE - USE_MPI - TEST_FILES_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" - TEST_FILE_SOURCE=\"${CMAKE_CURRENT_SOURCE_DIR}\" - ) - target_include_directories( - testParaGrid_MPI2 - PRIVATE ${MODEL_INCLUDE_DIR} "${ModulesRoot}/StructureModule" - ) - target_link_libraries(testParaGrid_MPI2 PRIVATE nextsimlib doctest::doctest) - - add_executable(testConfigOutput_MPI2 "ConfigOutput_test.cpp" "MainMPI.cpp") - target_compile_definitions( - testConfigOutput_MPI2 - PRIVATE USE_MPI TEST_FILES_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" - ) - target_include_directories(testConfigOutput_MPI2 PRIVATE ${MODEL_INCLUDE_DIR}) - target_link_libraries(testConfigOutput_MPI2 PRIVATE nextsimlib doctest::doctest) - if(ENABLE_XIOS) + set(XIOS_INCLUDE_LIST + "${xios_INCLUDES}" + "${xios_EXTERNS}/blitz/" + "${xios_EXTERNS}/rapidxml/include" + ) + set(MODEL_INCLUDE_DIR "${MODEL_INCLUDE_DIR}" "${XIOS_INCLUDE_LIST}") file( CREATE_LINK "${CMAKE_SOURCE_DIR}/core/test/iodef.xml" @@ -84,11 +38,6 @@ if(ENABLE_MPI) DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/xios_test_input.cdl ) add_custom_target(generate_xios_input_file ALL DEPENDS xios_test_input.nc) - set(XIOS_INCLUDE_LIST - "${xios_INCLUDES}" - "${xios_EXTERNS}/blitz/" - "${xios_EXTERNS}/rapidxml/include" - ) add_executable(testXiosCalendar_MPI2 "XiosCalendar_test.cpp" "MainMPI.cpp") target_compile_definitions(testXiosCalendar_MPI2 PRIVATE USE_XIOS) @@ -146,6 +95,58 @@ if(ENABLE_MPI) ) target_link_libraries(testXiosReadWrite_MPI2 PRIVATE nextsimlib doctest::doctest) endif() + + # Generate partition files needed for MPI test from respective cdl files + add_custom_command( + OUTPUT partition_metadata_3.nc + COMMAND + ncgen -b -o partition_metadata_3.nc ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_3.cdl + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_3.cdl + ) + add_custom_command( + OUTPUT partition_metadata_2.nc + COMMAND + ncgen -b -o partition_metadata_2.nc ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_2.cdl + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_2.cdl + ) + add_custom_target( + generate_partition_files + ALL + DEPENDS partition_metadata_3.nc partition_metadata_2.nc + ) + + add_executable(testRectGrid_MPI3 "RectGrid_test.cpp" "MainMPI.cpp") + target_compile_definitions( + testRectGrid_MPI3 + PRIVATE TEST_FILES_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" + ) + target_include_directories( + testRectGrid_MPI3 + PRIVATE ${MODEL_INCLUDE_DIR} "${ModulesRoot}/StructureModule" + ) + target_link_libraries(testRectGrid_MPI3 PRIVATE nextsimlib doctest::doctest) + + add_executable(testParaGrid_MPI2 "ParaGrid_test.cpp" "MainMPI.cpp") + target_compile_definitions( + testParaGrid_MPI2 + PRIVATE + USE_MPI + TEST_FILES_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" + TEST_FILE_SOURCE=\"${CMAKE_CURRENT_SOURCE_DIR}\" + ) + target_include_directories( + testParaGrid_MPI2 + PRIVATE ${MODEL_INCLUDE_DIR} "${ModulesRoot}/StructureModule" + ) + target_link_libraries(testParaGrid_MPI2 PRIVATE nextsimlib doctest::doctest) + + add_executable(testConfigOutput_MPI2 "ConfigOutput_test.cpp" "MainMPI.cpp") + target_compile_definitions( + testConfigOutput_MPI2 + PRIVATE USE_MPI TEST_FILES_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" + ) + target_include_directories(testConfigOutput_MPI2 PRIVATE ${MODEL_INCLUDE_DIR}) + target_link_libraries(testConfigOutput_MPI2 PRIVATE nextsimlib doctest::doctest) else() add_executable(testRectGrid "RectGrid_test.cpp") target_compile_definitions(testRectGrid PRIVATE TEST_FILES_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\") diff --git a/core/test/ConfigOutput_test.cpp b/core/test/ConfigOutput_test.cpp index facbc8e57..40035289a 100644 --- a/core/test/ConfigOutput_test.cpp +++ b/core/test/ConfigOutput_test.cpp @@ -1,12 +1,13 @@ /*! * @file ConfigOutput_test.cpp * - * @date 24 Sep 2024 + * @date 09 Dec 2024 * @author Tim Spain */ #ifdef USE_MPI #include +#undef INFO #else #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include @@ -21,8 +22,8 @@ #include "include/ModelComponent.hpp" #include "include/ModelMetadata.hpp" #include "include/ModelState.hpp" -#include "include/NextsimModule.hpp" #include "include/NZLevels.hpp" +#include "include/NextsimModule.hpp" #include "include/gridNames.hpp" #include diff --git a/core/test/ParaGrid_test.cpp b/core/test/ParaGrid_test.cpp index f4e41e0c1..42169d9ac 100644 --- a/core/test/ParaGrid_test.cpp +++ b/core/test/ParaGrid_test.cpp @@ -1,7 +1,7 @@ /*! * @file ParaGrid_test.cpp * - * @date 24 Sep 2024 + * @date 09 Dec 2024 * @author Tim Spain */ @@ -9,6 +9,7 @@ #include #ifdef USE_MPI #include +#undef INFO #else #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include @@ -16,11 +17,11 @@ #include "include/Configurator.hpp" #include "include/ConfiguredModule.hpp" +#include "include/IStructure.hpp" #include "include/NZLevels.hpp" +#include "include/NextsimModule.hpp" #include "include/ParaGridIO.hpp" #include "include/ParametricGrid.hpp" -#include "include/IStructure.hpp" -#include "include/NextsimModule.hpp" #include "include/gridNames.hpp" #include diff --git a/core/test/RectGrid_test.cpp b/core/test/RectGrid_test.cpp index a2d2e8c76..ec6c0c296 100644 --- a/core/test/RectGrid_test.cpp +++ b/core/test/RectGrid_test.cpp @@ -1,12 +1,13 @@ /*! * @file RectGrid_test.cpp * - * @date 24 Sep 2024 + * @date 09 Dec 2024 * @author Tim Spain */ #ifdef USE_MPI #include +#undef INFO #else #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include From 6ff28af72130175b5bbe5310ef309365ccfb3273 Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Mon, 9 Dec 2024 14:41:25 +0000 Subject: [PATCH 02/19] Add Xios::incrementCalendar and use in ModelMetadata::incrementTime --- core/src/ModelMetadata.cpp | 11 ++++++++++- core/src/Xios.cpp | 5 +++++ core/src/include/ModelMetadata.hpp | 19 +++++++++++++++++-- core/src/include/Xios.hpp | 3 ++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/core/src/ModelMetadata.cpp b/core/src/ModelMetadata.cpp index 65fbbb23f..17a3792e5 100644 --- a/core/src/ModelMetadata.cpp +++ b/core/src/ModelMetadata.cpp @@ -1,7 +1,7 @@ /*! * @file ModelMetadata.cpp * - * @date 21 August 2024 + * @date 09 Dec 2024 * @author Tim Spain */ @@ -103,4 +103,13 @@ ModelState& ModelMetadata::affixCoordinates(ModelState& state) const } return state; } + +void ModelMetadata::incrementTime(const Duration& step) +{ + m_time += step; +#ifdef USE_XIOS + xiosHandler->incrementCalendar(); +#endif +} + } /* namespace Nextsim */ diff --git a/core/src/Xios.cpp b/core/src/Xios.cpp index 68d8b257e..f16045047 100644 --- a/core/src/Xios.cpp +++ b/core/src/Xios.cpp @@ -354,6 +354,11 @@ std::string Xios::getCurrentDate(const bool isoFormat) */ void Xios::updateCalendar(const int stepNumber) { cxios_update_calendar(stepNumber); } +/*! + * Increment XIOS' calendar iteration/step number by one. + */ +void Xios::incrementCalendar() { updateCalendar(getCalendarStep() + 1); } + /*! * Get the axis_definition group * diff --git a/core/src/include/ModelMetadata.hpp b/core/src/include/ModelMetadata.hpp index ad4956c7a..afd0b143d 100644 --- a/core/src/include/ModelMetadata.hpp +++ b/core/src/include/ModelMetadata.hpp @@ -1,7 +1,7 @@ /*! * @file ModelMetadata.hpp * - * @date Jun 29, 2022 + * @date 09 Dec 2024 * @author Tim Spain */ @@ -12,6 +12,9 @@ #include "include/ModelArray.hpp" #include "include/ModelState.hpp" #include "include/Time.hpp" +#ifdef USE_XIOS +#include "include/Xios.hpp" +#endif #include @@ -53,7 +56,7 @@ class ModelMetadata { * * @param step Duration of the time increment to add. */ - inline void incrementTime(const Duration& step) { m_time += step; } + void incrementTime(const Duration& step); //! Returns the current model time. inline const TimePoint& time() const { return m_time; } @@ -99,6 +102,15 @@ class ModelMetadata { int localCornerX, localCornerY, localExtentX, localExtentY, globalExtentX, globalExtentY; #endif +#ifdef USE_XIOS + /* + * @brief Set pointer to Xios handler instance. + * + * @param xiosPtr Pointer to set + */ + inline void setXiosHandler(Xios* xiosPtr) { xiosHandler = xiosPtr; } +#endif + private: TimePoint m_time; ConfigMap m_config; @@ -117,6 +129,9 @@ class ModelMetadata { #ifdef USE_MPI const std::string bboxName = "bounding_boxes"; #endif +#ifdef USE_XIOS + Xios* xiosHandler; +#endif }; } /* namespace Nextsim */ diff --git a/core/src/include/Xios.hpp b/core/src/include/Xios.hpp index cd846ded7..5792e6019 100644 --- a/core/src/include/Xios.hpp +++ b/core/src/include/Xios.hpp @@ -2,7 +2,7 @@ * @file Xios.hpp * @author Tom Meltzer * @author Joe Wallwork - * @date 04 Dec 2024 + * @date 10 Dec 2024 * @brief XIOS interface header * @details * @@ -55,6 +55,7 @@ class Xios : public Configured { void setCalendarOrigin(const TimePoint origin); void setCalendarStart(const TimePoint start); void setCalendarTimestep(const Duration timestep); + void incrementCalendar(); std::string getCalendarType(); TimePoint getCalendarOrigin(); TimePoint getCalendarStart(); From 3d15fae3fee9ddce289b761a5f928a643b49775a Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Mon, 9 Dec 2024 14:44:39 +0000 Subject: [PATCH 03/19] Rename updateCalendar as setCalendarStep --- core/src/Xios.cpp | 24 ++++++++++++------------ core/src/include/Xios.hpp | 2 +- core/test/XiosCalendar_test.cpp | 4 ++-- core/test/XiosReadWrite_test.cpp | 6 +++--- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/core/src/Xios.cpp b/core/src/Xios.cpp index f16045047..35fe77e2c 100644 --- a/core/src/Xios.cpp +++ b/core/src/Xios.cpp @@ -271,6 +271,18 @@ void Xios::setCalendarTimestep(const Duration timestep) cxios_update_calendar_timestep(clientCalendar); } +/*! + * Update XIOS calendar iteration/step number to some value + * + * @param Step number to update to + */ +void Xios::setCalendarStep(const int stepNumber) { cxios_update_calendar(stepNumber); } + +/*! + * Increment XIOS' calendar iteration/step number by one. + */ +void Xios::incrementCalendar() { setCalendarStep(getCalendarStep() + 1); } + /*! * Get calendar type * @@ -347,18 +359,6 @@ std::string Xios::getCurrentDate(const bool isoFormat) return convertXiosDatetimeToString(xiosDate, isoFormat); } -/*! - * Update XIOS calendar iteration/step number - * - * @param current step number - */ -void Xios::updateCalendar(const int stepNumber) { cxios_update_calendar(stepNumber); } - -/*! - * Increment XIOS' calendar iteration/step number by one. - */ -void Xios::incrementCalendar() { updateCalendar(getCalendarStep() + 1); } - /*! * Get the axis_definition group * diff --git a/core/src/include/Xios.hpp b/core/src/include/Xios.hpp index 5792e6019..4db7b6f47 100644 --- a/core/src/include/Xios.hpp +++ b/core/src/include/Xios.hpp @@ -55,6 +55,7 @@ class Xios : public Configured { void setCalendarOrigin(const TimePoint origin); void setCalendarStart(const TimePoint start); void setCalendarTimestep(const Duration timestep); + void setCalendarStep(const int stepNumber); void incrementCalendar(); std::string getCalendarType(); TimePoint getCalendarOrigin(); @@ -62,7 +63,6 @@ class Xios : public Configured { Duration getCalendarTimestep(); int getCalendarStep(); std::string getCurrentDate(const bool isoFormat = true); - void updateCalendar(const int stepNumber); /* Axis */ void createAxis(const std::string axisId); diff --git a/core/test/XiosCalendar_test.cpp b/core/test/XiosCalendar_test.cpp index 6dcd0a7cc..6fe41dae5 100644 --- a/core/test/XiosCalendar_test.cpp +++ b/core/test/XiosCalendar_test.cpp @@ -1,7 +1,7 @@ /*! * @file XiosCalendar_test.cpp * @author Joe Wallwork - * @date 04 Dec 2024 + * @date 10 Dec 2024 * @brief Tests for XIOS calandars * @details * This test is designed to test calendar functionality of the C++ interface @@ -64,7 +64,7 @@ MPI_TEST_CASE("TestXiosInitialization", 2) REQUIRE(xios_handler.getCurrentDate(false) == "2023-03-17 17:11:00"); // -- Tests that the timestep is set up correctly - xios_handler.updateCalendar(1); + xios_handler.setCalendarStep(1); REQUIRE(xios_handler.getCurrentDate() == "2023-03-17T18:41:00Z"); xios_handler.context_finalize(); diff --git a/core/test/XiosReadWrite_test.cpp b/core/test/XiosReadWrite_test.cpp index d746216a8..649054682 100644 --- a/core/test/XiosReadWrite_test.cpp +++ b/core/test/XiosReadWrite_test.cpp @@ -1,7 +1,7 @@ /*! * @file XiosReadWrite_test.cpp * @author Joe Wallwork - * @date 04 Dec 2024 + * @date 10 Dec 2024 * @brief Tests for XIOS write method * @details * This test is designed to test the read and write methods of the C++ @@ -148,7 +148,7 @@ void readFile(Xios* xios_handler, HField& field_A, const std::string fieldId) // Simulate 4 iterations (timesteps) for (int ts = 1; ts <= 4; ts++) { // Update the current timestep - xios_handler->updateCalendar(ts); + xios_handler->setCalendarStep(ts); // Receive data from XIOS that is read from disk xios_handler->read(fieldId, field_A); // Verify timestep @@ -239,7 +239,7 @@ void testFileWrite(Xios* xios_handler, HField& field_A, const std::string fieldI // Simulate 4 iterations (timesteps) for (int ts = 1; ts <= 4; ts++) { // Update the current timestep - xios_handler->updateCalendar(ts); + xios_handler->setCalendarStep(ts); // Send data to XIOS to be written to disk xios_handler->write(fieldId, field_A); // Verify timestep From ee75b9dc9e2dcec5534f3d00e627817fef3a259b Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Mon, 9 Dec 2024 14:57:45 +0000 Subject: [PATCH 04/19] Use ModelMetadata::incrementTime in XIOS read/write test --- core/test/XiosReadWrite_test.cpp | 34 +++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/core/test/XiosReadWrite_test.cpp b/core/test/XiosReadWrite_test.cpp index 649054682..65714a7d9 100644 --- a/core/test/XiosReadWrite_test.cpp +++ b/core/test/XiosReadWrite_test.cpp @@ -12,9 +12,9 @@ #undef INFO #include "StructureModule/include/ParametricGrid.hpp" +#include "include/ModelMetadata.hpp" #include "include/NextsimModule.hpp" #include "include/ParaGridIO.hpp" -#include "include/Xios.hpp" #include @@ -145,14 +145,22 @@ void readFile(Xios* xios_handler, HField& field_A, const std::string fieldId) // Check the input file exists REQUIRE(std::filesystem::exists("xios_test_input.nc")); + // Create ModelMetadata instance + ModelMetadata metadata; + metadata.setTime(xios_handler->getCalendarStart()); + metadata.setXiosHandler(xios_handler); + + // FIXME: Why is timestep undefined? + xios_handler->setCalendarTimestep(Duration("P0-0T01:30:00")); // Shouldn't be necessary + Duration timestep = xios_handler->getCalendarTimestep(); + // Simulate 4 iterations (timesteps) for (int ts = 1; ts <= 4; ts++) { - // Update the current timestep - xios_handler->setCalendarStep(ts); + // Update the current timestep and verify it's updated in XIOS + metadata.incrementTime(timestep); + REQUIRE(xios_handler->getCalendarStep() == ts); // Receive data from XIOS that is read from disk xios_handler->read(fieldId, field_A); - // Verify timestep - REQUIRE(xios_handler->getCalendarStep() == ts); } } @@ -236,14 +244,22 @@ void testFileWrite(Xios* xios_handler, HField& field_A, const std::string fieldI // Check a file with the expected name doesn't exist yet REQUIRE_FALSE(std::filesystem::exists("xios_test_output*.nc")); + // Create ModelMetadata instance + ModelMetadata metadata; + metadata.setTime(xios_handler->getCalendarStart()); + metadata.setXiosHandler(xios_handler); + + // FIXME: Why is timestep undefined? + xios_handler->setCalendarTimestep(Duration("P0-0T01:30:00")); // Shouldn't be necessary + Duration timestep = xios_handler->getCalendarTimestep(); + // Simulate 4 iterations (timesteps) for (int ts = 1; ts <= 4; ts++) { - // Update the current timestep - xios_handler->setCalendarStep(ts); + // Update the current timestep and verify it's updated in XIOS + metadata.incrementTime(timestep); + REQUIRE(xios_handler->getCalendarStep() == ts); // Send data to XIOS to be written to disk xios_handler->write(fieldId, field_A); - // Verify timestep - REQUIRE(xios_handler->getCalendarStep() == ts); } // Check the files have indeed been created then remove it From 752b24fc21f6785731ee043716e6c5d2568b930e Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Mon, 9 Dec 2024 15:32:53 +0000 Subject: [PATCH 05/19] Create XIOS handlers for other tests build with XIOS support --- core/test/ConfigOutput_test.cpp | 5 ++++- core/test/ParaGrid_test.cpp | 16 ++++++++++++++++ core/test/RectGrid_test.cpp | 4 ++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/core/test/ConfigOutput_test.cpp b/core/test/ConfigOutput_test.cpp index 40035289a..addb9ce82 100644 --- a/core/test/ConfigOutput_test.cpp +++ b/core/test/ConfigOutput_test.cpp @@ -98,8 +98,11 @@ TEST_CASE("Test periodic output") ModelComponent::getStore().registerArray(Protected::T_ICE, &tice); ModelMetadata meta; +#ifdef USE_XIOS + Xios xiosHandler; + meta.setXiosHandler(&xiosHandler); +#endif meta.setTime(TimePoint("2020-01-01T00:00:00Z")); - #ifdef USE_MPI meta.setMpiMetadata(test_comm); #endif diff --git a/core/test/ParaGrid_test.cpp b/core/test/ParaGrid_test.cpp index 42169d9ac..efdb3c045 100644 --- a/core/test/ParaGrid_test.cpp +++ b/core/test/ParaGrid_test.cpp @@ -208,6 +208,10 @@ TEST_CASE("Write and read a ModelState-based ParaGrid restart file") {} }; ModelMetadata metadata; +#ifdef USE_XIOS + Xios xiosHandler("test1"); + metadata.setXiosHandler(&xiosHandler); +#endif metadata.setTime(TimePoint("2000-01-01T00:00:00Z")); // The coordinates are passed through the metadata object as affix // coordinates is the correct way to add coordinates to a ModelState @@ -401,6 +405,10 @@ TEST_CASE("Write a diagnostic ParaGrid file") {} }; ModelMetadata metadata; +#ifdef USE_XIOS + Xios xiosHandler("test2"); + metadata.setXiosHandler(&xiosHandler); +#endif metadata.setTime(TimePoint("2000-01-01T00:00:00Z")); // The coordinates are passed through the metadata object as affix // coordinates is the correct way to add coordinates to a ModelState @@ -537,6 +545,10 @@ TEST_CASE("Check an exception is thrown for an invalid file name") std::string longRandomFilename("a44f5cc1f7934a8ae8dd03a95308745d.nc"); #ifdef USE_MPI ModelMetadata metadataIn(partitionFilename, test_comm); +#ifdef USE_XIOS + Xios xiosHandler("test4"); + metadataIn.setXiosHandler(&xiosHandler); +#endif metadataIn.setTime(TimePoint(dateString)); REQUIRE_THROWS(state = gridIn.getModelState(longRandomFilename, metadataIn)); #else @@ -588,6 +600,10 @@ TEST_CASE("Check if a file with the old dimension names can be read") #ifdef USE_MPI ModelMetadata metadata; +#ifdef USE_XIOS + Xios xiosHandler("test5"); + metadata.setXiosHandler(&xiosHandler); +#endif metadata.setMpiMetadata(test_comm); if (metadata.mpiMyRank == 0) { metadata.localCornerX = 0; diff --git a/core/test/RectGrid_test.cpp b/core/test/RectGrid_test.cpp index ec6c0c296..063bc31f0 100644 --- a/core/test/RectGrid_test.cpp +++ b/core/test/RectGrid_test.cpp @@ -84,6 +84,10 @@ TEST_CASE("Write and read a ModelState-based RectGrid restart file") {} }; ModelMetadata metadata; +#ifdef USE_XIOS + Xios xiosHandler; + metadata.setXiosHandler(&xiosHandler); +#endif metadata.setTime(TimePoint(date_string)); // Use x & y coordinates ModelArray x(ModelArray::Type::H); From a5b639b0aaf38afe5ff2b794f6b9a99ef1c2c019 Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Mon, 9 Dec 2024 16:10:02 +0000 Subject: [PATCH 06/19] Same for ModelMetadata::setTime --- core/src/ModelMetadata.cpp | 14 ++++++++++++++ core/src/include/ModelMetadata.hpp | 2 +- core/test/ConfigOutput_test.cpp | 5 +++-- core/test/ParaGrid_test.cpp | 11 ++++++++++- core/test/RectGrid_test.cpp | 8 +++++++- core/test/XiosReadWrite_test.cpp | 4 ++-- 6 files changed, 37 insertions(+), 7 deletions(-) diff --git a/core/src/ModelMetadata.cpp b/core/src/ModelMetadata.cpp index 17a3792e5..f2d3275cf 100644 --- a/core/src/ModelMetadata.cpp +++ b/core/src/ModelMetadata.cpp @@ -104,10 +104,24 @@ ModelState& ModelMetadata::affixCoordinates(ModelState& state) const return state; } +void ModelMetadata::setTime(const TimePoint& time) +{ + m_time = time; +#ifdef USE_XIOS + if (!xiosHandler->isInitialized()) { + throw std::runtime_error("ModelMetadata: Xios handler has not been initialized"); + } + xiosHandler->setCalendarStart(time); +#endif +} + void ModelMetadata::incrementTime(const Duration& step) { m_time += step; #ifdef USE_XIOS + if (!xiosHandler->isInitialized()) { + throw std::runtime_error("ModelMetadata: Xios handler has not been initialized"); + } xiosHandler->incrementCalendar(); #endif } diff --git a/core/src/include/ModelMetadata.hpp b/core/src/include/ModelMetadata.hpp index afd0b143d..6df11ac4e 100644 --- a/core/src/include/ModelMetadata.hpp +++ b/core/src/include/ModelMetadata.hpp @@ -50,7 +50,7 @@ class ModelMetadata { * * @param time TimePoint instance encoding the current time. */ - inline void setTime(const TimePoint& time) { m_time = time; } + void setTime(const TimePoint& time); /*! * @brief Increments the model time metadata value. * diff --git a/core/test/ConfigOutput_test.cpp b/core/test/ConfigOutput_test.cpp index addb9ce82..55d6437e5 100644 --- a/core/test/ConfigOutput_test.cpp +++ b/core/test/ConfigOutput_test.cpp @@ -99,7 +99,8 @@ TEST_CASE("Test periodic output") ModelMetadata meta; #ifdef USE_XIOS - Xios xiosHandler; + Xios xiosHandler("test1"); + xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); meta.setXiosHandler(&xiosHandler); #endif meta.setTime(TimePoint("2020-01-01T00:00:00Z")); @@ -149,7 +150,7 @@ TEST_CASE("Test periodic output") ModelState state; ido.outputState(meta); - meta.incrementTime(Duration(3600.)); + meta.incrementTime(Duration(3600.)); // FIXME: Context undefined? } } diff --git a/core/test/ParaGrid_test.cpp b/core/test/ParaGrid_test.cpp index efdb3c045..200dd753f 100644 --- a/core/test/ParaGrid_test.cpp +++ b/core/test/ParaGrid_test.cpp @@ -209,7 +209,8 @@ TEST_CASE("Write and read a ModelState-based ParaGrid restart file") ModelMetadata metadata; #ifdef USE_XIOS - Xios xiosHandler("test1"); + Xios xiosHandler("test1a"); + xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); #endif metadata.setTime(TimePoint("2000-01-01T00:00:00Z")); @@ -255,6 +256,11 @@ TEST_CASE("Write and read a ModelState-based ParaGrid restart file") #ifdef USE_MPI ModelMetadata metadataIn(partitionFilename, test_comm); +#ifdef USE_XIOS + Xios xiosHandlerIn("test1b"); + xiosHandlerIn.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); + metadataIn.setXiosHandler(&xiosHandlerIn); +#endif metadataIn.setTime(TimePoint(dateString)); ModelState ms = gridIn.getModelState(filename, metadataIn); #else @@ -407,6 +413,7 @@ TEST_CASE("Write a diagnostic ParaGrid file") ModelMetadata metadata; #ifdef USE_XIOS Xios xiosHandler("test2"); + xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); #endif metadata.setTime(TimePoint("2000-01-01T00:00:00Z")); @@ -547,6 +554,7 @@ TEST_CASE("Check an exception is thrown for an invalid file name") ModelMetadata metadataIn(partitionFilename, test_comm); #ifdef USE_XIOS Xios xiosHandler("test4"); + xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadataIn.setXiosHandler(&xiosHandler); #endif metadataIn.setTime(TimePoint(dateString)); @@ -602,6 +610,7 @@ TEST_CASE("Check if a file with the old dimension names can be read") ModelMetadata metadata; #ifdef USE_XIOS Xios xiosHandler("test5"); + xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); #endif metadata.setMpiMetadata(test_comm); diff --git a/core/test/RectGrid_test.cpp b/core/test/RectGrid_test.cpp index 063bc31f0..95eb3d76a 100644 --- a/core/test/RectGrid_test.cpp +++ b/core/test/RectGrid_test.cpp @@ -85,7 +85,8 @@ TEST_CASE("Write and read a ModelState-based RectGrid restart file") ModelMetadata metadata; #ifdef USE_XIOS - Xios xiosHandler; + Xios xiosHandler("test1a"); + xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); #endif metadata.setTime(TimePoint(date_string)); @@ -154,6 +155,11 @@ TEST_CASE("Write and read a ModelState-based RectGrid restart file") gridIn.setIO(new RectGridIO(grid)); #ifdef USE_MPI ModelMetadata metadataIn(partition_filename, test_comm); +#ifdef USE_XIOS + Xios xiosHandlerIn("test1b"); + xiosHandlerIn.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); + metadata.setXiosHandler(&xiosHandlerIn); +#endif metadataIn.setTime(TimePoint(date_string)); ModelState ms = gridIn.getModelState(filename, metadataIn); #else diff --git a/core/test/XiosReadWrite_test.cpp b/core/test/XiosReadWrite_test.cpp index 65714a7d9..80ad6a12c 100644 --- a/core/test/XiosReadWrite_test.cpp +++ b/core/test/XiosReadWrite_test.cpp @@ -147,8 +147,8 @@ void readFile(Xios* xios_handler, HField& field_A, const std::string fieldId) // Create ModelMetadata instance ModelMetadata metadata; - metadata.setTime(xios_handler->getCalendarStart()); metadata.setXiosHandler(xios_handler); + metadata.setTime(xios_handler->getCalendarStart()); // FIXME: Why is timestep undefined? xios_handler->setCalendarTimestep(Duration("P0-0T01:30:00")); // Shouldn't be necessary @@ -246,8 +246,8 @@ void testFileWrite(Xios* xios_handler, HField& field_A, const std::string fieldI // Create ModelMetadata instance ModelMetadata metadata; - metadata.setTime(xios_handler->getCalendarStart()); metadata.setXiosHandler(xios_handler); + metadata.setTime(xios_handler->getCalendarStart()); // FIXME: Why is timestep undefined? xios_handler->setCalendarTimestep(Duration("P0-0T01:30:00")); // Shouldn't be necessary From 57bb7494259fc94854a488681d3e832128e5dd51 Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Mon, 9 Dec 2024 16:25:56 +0000 Subject: [PATCH 07/19] Enable XIOS; remember to close context defs --- core/test/ConfigOutput_test.cpp | 2 ++ core/test/ParaGrid_test.cpp | 1 + core/test/RectGrid_test.cpp | 7 +++++++ core/test/XiosReadWrite_test.cpp | 2 ++ 4 files changed, 12 insertions(+) diff --git a/core/test/ConfigOutput_test.cpp b/core/test/ConfigOutput_test.cpp index 55d6437e5..913a372e5 100644 --- a/core/test/ConfigOutput_test.cpp +++ b/core/test/ConfigOutput_test.cpp @@ -99,9 +99,11 @@ TEST_CASE("Test periodic output") ModelMetadata meta; #ifdef USE_XIOS + enableXios(); Xios xiosHandler("test1"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); meta.setXiosHandler(&xiosHandler); + xiosHandler.close_context_definition(); #endif meta.setTime(TimePoint("2020-01-01T00:00:00Z")); #ifdef USE_MPI diff --git a/core/test/ParaGrid_test.cpp b/core/test/ParaGrid_test.cpp index 200dd753f..f435dc011 100644 --- a/core/test/ParaGrid_test.cpp +++ b/core/test/ParaGrid_test.cpp @@ -209,6 +209,7 @@ TEST_CASE("Write and read a ModelState-based ParaGrid restart file") ModelMetadata metadata; #ifdef USE_XIOS + enableXios(); Xios xiosHandler("test1a"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); diff --git a/core/test/RectGrid_test.cpp b/core/test/RectGrid_test.cpp index 95eb3d76a..c4d364c52 100644 --- a/core/test/RectGrid_test.cpp +++ b/core/test/RectGrid_test.cpp @@ -85,11 +85,15 @@ TEST_CASE("Write and read a ModelState-based RectGrid restart file") ModelMetadata metadata; #ifdef USE_XIOS + enableXios(); Xios xiosHandler("test1a"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); #endif metadata.setTime(TimePoint(date_string)); +#ifdef USE_XIOS + xiosHandler.close_context_definition(); +#endif // Use x & y coordinates ModelArray x(ModelArray::Type::H); ModelArray y(ModelArray::Type::H); @@ -161,6 +165,9 @@ TEST_CASE("Write and read a ModelState-based RectGrid restart file") metadata.setXiosHandler(&xiosHandlerIn); #endif metadataIn.setTime(TimePoint(date_string)); +#ifdef USE_XIOS + xiosHandlerIn.close_context_definition(); +#endif ModelState ms = gridIn.getModelState(filename, metadataIn); #else ModelState ms = gridIn.getModelState(filename); diff --git a/core/test/XiosReadWrite_test.cpp b/core/test/XiosReadWrite_test.cpp index 80ad6a12c..87d78c60a 100644 --- a/core/test/XiosReadWrite_test.cpp +++ b/core/test/XiosReadWrite_test.cpp @@ -47,6 +47,8 @@ Xios setupXiosHandler(int dim, bool read) throw std::invalid_argument("Test only implemented for 2D and 3D cases"); } + enableXios(); + // Create ParametricGrid and ParaGridIO instances Module::setImplementation("Nextsim::ParametricGrid"); ParametricGrid grid; From 8238fb6c4f28417c724b583add347bb3a27fa92f Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Mon, 9 Dec 2024 16:33:51 +0000 Subject: [PATCH 08/19] Initialise xiosHandler to nullptr --- core/src/include/ModelMetadata.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/include/ModelMetadata.hpp b/core/src/include/ModelMetadata.hpp index 6df11ac4e..e0b2c6419 100644 --- a/core/src/include/ModelMetadata.hpp +++ b/core/src/include/ModelMetadata.hpp @@ -130,7 +130,7 @@ class ModelMetadata { const std::string bboxName = "bounding_boxes"; #endif #ifdef USE_XIOS - Xios* xiosHandler; + Xios* xiosHandler = nullptr; #endif }; From 4868f88a0ba60a126552416f3bf6d355a174d9a5 Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Mon, 9 Dec 2024 16:34:19 +0000 Subject: [PATCH 09/19] Don't build RectGrid_test with XIOS --- core/test/CMakeLists.txt | 22 +++++++++++----------- core/test/RectGrid_test.cpp | 17 ----------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/core/test/CMakeLists.txt b/core/test/CMakeLists.txt index e2d440cff..15ae0c2c3 100644 --- a/core/test/CMakeLists.txt +++ b/core/test/CMakeLists.txt @@ -94,6 +94,17 @@ if(ENABLE_MPI) PRIVATE "${MODEL_INCLUDE_DIR}" "${XIOS_INCLUDE_LIST}" "${ModulesRoot}/StructureModule" ) target_link_libraries(testXiosReadWrite_MPI2 PRIVATE nextsimlib doctest::doctest) + else() + add_executable(testRectGrid_MPI3 "RectGrid_test.cpp" "MainMPI.cpp") + target_compile_definitions( + testRectGrid_MPI3 + PRIVATE TEST_FILES_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" + ) + target_include_directories( + testRectGrid_MPI3 + PRIVATE ${MODEL_INCLUDE_DIR} "${ModulesRoot}/StructureModule" + ) + target_link_libraries(testRectGrid_MPI3 PRIVATE nextsimlib doctest::doctest) endif() # Generate partition files needed for MPI test from respective cdl files @@ -115,17 +126,6 @@ if(ENABLE_MPI) DEPENDS partition_metadata_3.nc partition_metadata_2.nc ) - add_executable(testRectGrid_MPI3 "RectGrid_test.cpp" "MainMPI.cpp") - target_compile_definitions( - testRectGrid_MPI3 - PRIVATE TEST_FILES_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" - ) - target_include_directories( - testRectGrid_MPI3 - PRIVATE ${MODEL_INCLUDE_DIR} "${ModulesRoot}/StructureModule" - ) - target_link_libraries(testRectGrid_MPI3 PRIVATE nextsimlib doctest::doctest) - add_executable(testParaGrid_MPI2 "ParaGrid_test.cpp" "MainMPI.cpp") target_compile_definitions( testParaGrid_MPI2 diff --git a/core/test/RectGrid_test.cpp b/core/test/RectGrid_test.cpp index c4d364c52..ec6c0c296 100644 --- a/core/test/RectGrid_test.cpp +++ b/core/test/RectGrid_test.cpp @@ -84,16 +84,7 @@ TEST_CASE("Write and read a ModelState-based RectGrid restart file") {} }; ModelMetadata metadata; -#ifdef USE_XIOS - enableXios(); - Xios xiosHandler("test1a"); - xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); - metadata.setXiosHandler(&xiosHandler); -#endif metadata.setTime(TimePoint(date_string)); -#ifdef USE_XIOS - xiosHandler.close_context_definition(); -#endif // Use x & y coordinates ModelArray x(ModelArray::Type::H); ModelArray y(ModelArray::Type::H); @@ -159,15 +150,7 @@ TEST_CASE("Write and read a ModelState-based RectGrid restart file") gridIn.setIO(new RectGridIO(grid)); #ifdef USE_MPI ModelMetadata metadataIn(partition_filename, test_comm); -#ifdef USE_XIOS - Xios xiosHandlerIn("test1b"); - xiosHandlerIn.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); - metadata.setXiosHandler(&xiosHandlerIn); -#endif metadataIn.setTime(TimePoint(date_string)); -#ifdef USE_XIOS - xiosHandlerIn.close_context_definition(); -#endif ModelState ms = gridIn.getModelState(filename, metadataIn); #else ModelState ms = gridIn.getModelState(filename); From 260e05065cf6356913f3d82ed4d986a6d94a8bdb Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Tue, 10 Dec 2024 13:12:43 +0000 Subject: [PATCH 10/19] Pass timestep to Xios constructor when contextId is specified --- core/test/ConfigOutput_test.cpp | 4 ++-- core/test/ParaGrid_test.cpp | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/test/ConfigOutput_test.cpp b/core/test/ConfigOutput_test.cpp index 913a372e5..6a0c46e10 100644 --- a/core/test/ConfigOutput_test.cpp +++ b/core/test/ConfigOutput_test.cpp @@ -1,7 +1,7 @@ /*! * @file ConfigOutput_test.cpp * - * @date 09 Dec 2024 + * @date 10 Dec 2024 * @author Tim Spain */ @@ -100,7 +100,7 @@ TEST_CASE("Test periodic output") ModelMetadata meta; #ifdef USE_XIOS enableXios(); - Xios xiosHandler("test1"); + Xios xiosHandler("P0-0T01:00:00", "test1"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); meta.setXiosHandler(&xiosHandler); xiosHandler.close_context_definition(); diff --git a/core/test/ParaGrid_test.cpp b/core/test/ParaGrid_test.cpp index f435dc011..e5a57c1d1 100644 --- a/core/test/ParaGrid_test.cpp +++ b/core/test/ParaGrid_test.cpp @@ -1,7 +1,7 @@ /*! * @file ParaGrid_test.cpp * - * @date 09 Dec 2024 + * @date 10 Dec 2024 * @author Tim Spain */ @@ -210,7 +210,7 @@ TEST_CASE("Write and read a ModelState-based ParaGrid restart file") ModelMetadata metadata; #ifdef USE_XIOS enableXios(); - Xios xiosHandler("test1a"); + Xios xiosHandler("P0-0T01:00:00", "test1a"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); #endif @@ -258,7 +258,7 @@ TEST_CASE("Write and read a ModelState-based ParaGrid restart file") #ifdef USE_MPI ModelMetadata metadataIn(partitionFilename, test_comm); #ifdef USE_XIOS - Xios xiosHandlerIn("test1b"); + Xios xiosHandlerIn("P0-0T01:00:00", "test1b"); xiosHandlerIn.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadataIn.setXiosHandler(&xiosHandlerIn); #endif @@ -413,7 +413,7 @@ TEST_CASE("Write a diagnostic ParaGrid file") ModelMetadata metadata; #ifdef USE_XIOS - Xios xiosHandler("test2"); + Xios xiosHandler("P0-0T01:00:00", "test2"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); #endif @@ -554,7 +554,7 @@ TEST_CASE("Check an exception is thrown for an invalid file name") #ifdef USE_MPI ModelMetadata metadataIn(partitionFilename, test_comm); #ifdef USE_XIOS - Xios xiosHandler("test4"); + Xios xiosHandler("P0-0T01:00:00", "test4"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadataIn.setXiosHandler(&xiosHandler); #endif @@ -610,7 +610,7 @@ TEST_CASE("Check if a file with the old dimension names can be read") #ifdef USE_MPI ModelMetadata metadata; #ifdef USE_XIOS - Xios xiosHandler("test5"); + Xios xiosHandler("P0-0T01:00:00", "test5"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); #endif From 326d519463e7a56e24dec15b4b5363a8038b31dc Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Tue, 10 Dec 2024 13:18:27 +0000 Subject: [PATCH 11/19] At the core of the issue in the read/write test --- core/test/XiosReadWrite_test.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/core/test/XiosReadWrite_test.cpp b/core/test/XiosReadWrite_test.cpp index 87d78c60a..5fceebd10 100644 --- a/core/test/XiosReadWrite_test.cpp +++ b/core/test/XiosReadWrite_test.cpp @@ -130,6 +130,11 @@ Xios setupXiosHandler(int dim, bool read) xios_handler.fileAddField(fileId, fieldId); xios_handler.close_context_definition(); + // FIXME: Why do we need to re-set the calendar timestep and start here? + // These are already set in the Xios constructor and the test fails if the following two + // lines are moved above the close_context_definition. + xios_handler.setCalendarTimestep(Duration("P0-0T01:30:00")); + xios_handler.setCalendarStart(TimePoint("2023-03-17T17:11:00Z")); return xios_handler; } @@ -152,11 +157,8 @@ void readFile(Xios* xios_handler, HField& field_A, const std::string fieldId) metadata.setXiosHandler(xios_handler); metadata.setTime(xios_handler->getCalendarStart()); - // FIXME: Why is timestep undefined? - xios_handler->setCalendarTimestep(Duration("P0-0T01:30:00")); // Shouldn't be necessary - Duration timestep = xios_handler->getCalendarTimestep(); - // Simulate 4 iterations (timesteps) + Duration timestep = xios_handler->getCalendarTimestep(); for (int ts = 1; ts <= 4; ts++) { // Update the current timestep and verify it's updated in XIOS metadata.incrementTime(timestep); @@ -251,11 +253,8 @@ void testFileWrite(Xios* xios_handler, HField& field_A, const std::string fieldI metadata.setXiosHandler(xios_handler); metadata.setTime(xios_handler->getCalendarStart()); - // FIXME: Why is timestep undefined? - xios_handler->setCalendarTimestep(Duration("P0-0T01:30:00")); // Shouldn't be necessary - Duration timestep = xios_handler->getCalendarTimestep(); - // Simulate 4 iterations (timesteps) + Duration timestep = xios_handler->getCalendarTimestep(); for (int ts = 1; ts <= 4; ts++) { // Update the current timestep and verify it's updated in XIOS metadata.incrementTime(timestep); From 9cf905ab9ce1961867a0a7cb6f8a3d343d4a5d13 Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Mon, 9 Dec 2024 18:07:52 +0000 Subject: [PATCH 12/19] Add extra workflow job for testing without XIOS --- .github/workflows/test_suite.yml | 40 ++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test_suite.yml b/.github/workflows/test_suite.yml index 3056b53e5..f7c502653 100644 --- a/.github/workflows/test_suite.yml +++ b/.github/workflows/test_suite.yml @@ -50,9 +50,43 @@ jobs: cd test python3 ThermoIntegration_test.py ./run_test_jan2010_integration_test.sh python3 - cd - - test-ubuntu-mpi: + test-ubuntu-mpi-noxios: + + runs-on: ubuntu-22.04 + container: + image: ghcr.io/nextsimhub/nextsimdg-dev-env:latest + + steps: + - uses: actions/checkout@v2 + + - name: build and compile with MPI but not XIOS + run: | + . /opt/spack-environment/activate.sh + mkdir -p build && cd build + cmake -DENABLE_MPI=ON -DENABLE_XIOS=OFF -DCMAKE_CXX_COMPILER="$(which mpic++)" .. + make -j 4 + + - name: run MPI tests + run: | + . /opt/spack-environment/activate.sh + apt update + apt install -y wget + cd build + (cd core/test && wget "ftp://ftp.nersc.no/nextsim/netCDF/partition_metadata_1.nc") + for component in core physics dynamics + do + cd $component/test + for file in $(find test* -maxdepth 0 -type f) + do + echo $file + nprocs=$(echo $file | sed -r "s/.*MPI([0-9]+)/\1/") + mpirun --allow-run-as-root --oversubscribe -n $nprocs ./$file + done + cd - + done + + test-ubuntu-mpi-xios: runs-on: ubuntu-22.04 container: @@ -86,7 +120,6 @@ jobs: done cd - done - cd - test-mac-serial: @@ -138,4 +171,3 @@ jobs: cd test python ThermoIntegration_test.py ./run_test_jan2010_integration_test.sh python - cd - From fe2118d9aee0bde8b6da87beb82fd737ca9fce88 Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Tue, 10 Dec 2024 13:57:04 +0000 Subject: [PATCH 13/19] Don't clear streams in Xios --- core/src/Xios.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/Xios.cpp b/core/src/Xios.cpp index 35fe77e2c..91a08f3fe 100644 --- a/core/src/Xios.cpp +++ b/core/src/Xios.cpp @@ -2,7 +2,7 @@ * @file Xios.cpp * @author Tom Meltzer * @author Joe Wallwork - * @date 09 Dec 2024 + * @date 10 Dec 2024 * @brief XIOS interface implementation * @details * @@ -37,7 +37,6 @@ static const std::map keyMap = { { Xios::ENABLED_KEY, "xios.en //! Enable XIOS in the 'config' void enableXios() { - Configurator::clearStreams(); std::stringstream config; config << "[xios]" << std::endl << "enable = true" << std::endl; std::unique_ptr pcstream(new std::stringstream(config.str())); From 955c5c2df6ed09eb667b6d95f3e07842c0f1ba9e Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Tue, 10 Dec 2024 14:25:21 +0000 Subject: [PATCH 14/19] Fix ParaGrid_test --- core/test/ParaGrid_test.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/test/ParaGrid_test.cpp b/core/test/ParaGrid_test.cpp index e5a57c1d1..8b598ec4d 100644 --- a/core/test/ParaGrid_test.cpp +++ b/core/test/ParaGrid_test.cpp @@ -213,6 +213,7 @@ TEST_CASE("Write and read a ModelState-based ParaGrid restart file") Xios xiosHandler("P0-0T01:00:00", "test1a"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); + xiosHandler.close_context_definition(); #endif metadata.setTime(TimePoint("2000-01-01T00:00:00Z")); // The coordinates are passed through the metadata object as affix @@ -258,9 +259,7 @@ TEST_CASE("Write and read a ModelState-based ParaGrid restart file") #ifdef USE_MPI ModelMetadata metadataIn(partitionFilename, test_comm); #ifdef USE_XIOS - Xios xiosHandlerIn("P0-0T01:00:00", "test1b"); - xiosHandlerIn.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); - metadataIn.setXiosHandler(&xiosHandlerIn); + metadataIn.setXiosHandler(&xiosHandler); #endif metadataIn.setTime(TimePoint(dateString)); ModelState ms = gridIn.getModelState(filename, metadataIn); @@ -413,9 +412,11 @@ TEST_CASE("Write a diagnostic ParaGrid file") ModelMetadata metadata; #ifdef USE_XIOS + enableXios(); Xios xiosHandler("P0-0T01:00:00", "test2"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); + xiosHandler.close_context_definition(); #endif metadata.setTime(TimePoint("2000-01-01T00:00:00Z")); // The coordinates are passed through the metadata object as affix @@ -554,9 +555,11 @@ TEST_CASE("Check an exception is thrown for an invalid file name") #ifdef USE_MPI ModelMetadata metadataIn(partitionFilename, test_comm); #ifdef USE_XIOS + enableXios(); Xios xiosHandler("P0-0T01:00:00", "test4"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadataIn.setXiosHandler(&xiosHandler); + xiosHandler.close_context_definition(); #endif metadataIn.setTime(TimePoint(dateString)); REQUIRE_THROWS(state = gridIn.getModelState(longRandomFilename, metadataIn)); @@ -610,9 +613,11 @@ TEST_CASE("Check if a file with the old dimension names can be read") #ifdef USE_MPI ModelMetadata metadata; #ifdef USE_XIOS + enableXios(); Xios xiosHandler("P0-0T01:00:00", "test5"); xiosHandler.setCalendarOrigin(TimePoint("1970-01-01T00:00:00Z")); metadata.setXiosHandler(&xiosHandler); + xiosHandler.close_context_definition(); #endif metadata.setMpiMetadata(test_comm); if (metadata.mpiMyRank == 0) { From 0ca57adba8ff3e2d38584735e4818ee997a323dc Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Tue, 10 Dec 2024 14:25:37 +0000 Subject: [PATCH 15/19] Reset XIOS calendar step in ModelMetadata::setTime --- core/src/ModelMetadata.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/ModelMetadata.cpp b/core/src/ModelMetadata.cpp index f2d3275cf..f6f332672 100644 --- a/core/src/ModelMetadata.cpp +++ b/core/src/ModelMetadata.cpp @@ -1,7 +1,7 @@ /*! * @file ModelMetadata.cpp * - * @date 09 Dec 2024 + * @date 10 Dec 2024 * @author Tim Spain */ @@ -111,6 +111,7 @@ void ModelMetadata::setTime(const TimePoint& time) if (!xiosHandler->isInitialized()) { throw std::runtime_error("ModelMetadata: Xios handler has not been initialized"); } + xiosHandler->setCalendarStep(0); xiosHandler->setCalendarStart(time); #endif } From fe1c9b22c4e30054fd44040c2fccdd6ef8d181a2 Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Tue, 10 Dec 2024 16:20:02 +0000 Subject: [PATCH 16/19] Apply a hack to get XIOS2 working --- Dockerfiles/install-xios.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Dockerfiles/install-xios.sh b/Dockerfiles/install-xios.sh index e089ae39e..450d575d4 100755 --- a/Dockerfiles/install-xios.sh +++ b/Dockerfiles/install-xios.sh @@ -69,7 +69,12 @@ cat <arch/arch-GCC_LINUX.fcm %MAKE gmake EOF -./make_xios --arch GCC_LINUX --job 8 --full --debug +# Hack to remove a line that stops calendar attributes being accessed after the +# context definition has been closed. +# This should be fixed when we update to XIOS3 (see #761). +sed -i "s/if (hasClient) CleanTree/\/\/if (hasClient) CleanTree/" src/node/context.cpp + +./make_xios --arch GCC_LINUX --job 8 --debug rm -r /xios/obj /xios/bin/generic_testcase.exe /xios/src /xios/tools \ /xios/inputs /xios/doc /xios/arch /xios/xios_test_suite /xios/flags \ /xios/generic_testcase /xios/ppsrc /xios/done From 350702ec2f7d9f3e7bee873a97f1eebf77e2aa4f Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Tue, 10 Dec 2024 15:09:19 +0000 Subject: [PATCH 17/19] Issue fixed by XIOS hack --- core/test/XiosReadWrite_test.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/test/XiosReadWrite_test.cpp b/core/test/XiosReadWrite_test.cpp index 5fceebd10..22d1d8a89 100644 --- a/core/test/XiosReadWrite_test.cpp +++ b/core/test/XiosReadWrite_test.cpp @@ -130,11 +130,6 @@ Xios setupXiosHandler(int dim, bool read) xios_handler.fileAddField(fileId, fieldId); xios_handler.close_context_definition(); - // FIXME: Why do we need to re-set the calendar timestep and start here? - // These are already set in the Xios constructor and the test fails if the following two - // lines are moved above the close_context_definition. - xios_handler.setCalendarTimestep(Duration("P0-0T01:30:00")); - xios_handler.setCalendarStart(TimePoint("2023-03-17T17:11:00Z")); return xios_handler; } From 00f1a5ebe328238e4bffcbebaf6fa19809f11aef Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Wed, 11 Dec 2024 09:23:17 +0000 Subject: [PATCH 18/19] Drop FIXME no longer relevant --- core/test/ConfigOutput_test.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/test/ConfigOutput_test.cpp b/core/test/ConfigOutput_test.cpp index 6a0c46e10..b06282205 100644 --- a/core/test/ConfigOutput_test.cpp +++ b/core/test/ConfigOutput_test.cpp @@ -1,7 +1,7 @@ /*! * @file ConfigOutput_test.cpp * - * @date 10 Dec 2024 + * @date 11 Dec 2024 * @author Tim Spain */ @@ -106,6 +106,7 @@ TEST_CASE("Test periodic output") xiosHandler.close_context_definition(); #endif meta.setTime(TimePoint("2020-01-01T00:00:00Z")); + #ifdef USE_MPI meta.setMpiMetadata(test_comm); #endif @@ -152,7 +153,7 @@ TEST_CASE("Test periodic output") ModelState state; ido.outputState(meta); - meta.incrementTime(Duration(3600.)); // FIXME: Context undefined? + meta.incrementTime(Duration(3600.)); } } From 28b24531a7879d11cc9c830dc6ffddec6fcfcd41 Mon Sep 17 00:00:00 2001 From: Joe Wallwork Date: Wed, 11 Dec 2024 09:31:27 +0000 Subject: [PATCH 19/19] assertIsClose no longer needed --- core/test/XiosReadWrite_test.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/core/test/XiosReadWrite_test.cpp b/core/test/XiosReadWrite_test.cpp index 22d1d8a89..e9bfe5d70 100644 --- a/core/test/XiosReadWrite_test.cpp +++ b/core/test/XiosReadWrite_test.cpp @@ -1,7 +1,7 @@ /*! * @file XiosReadWrite_test.cpp * @author Joe Wallwork - * @date 10 Dec 2024 + * @date 11 Dec 2024 * @brief Tests for XIOS write method * @details * This test is designed to test the read and write methods of the C++ @@ -163,17 +163,6 @@ void readFile(Xios* xios_handler, HField& field_A, const std::string fieldId) } } -/*! - * Utility for checking that two double values are approximately equal. - * - * Without this (i.e., if it's inlined below) the first test passes but the second one fails. The - * same is true with any REQUIRE call. - * - * @param val1 the first double - * @param val2 the second double - */ -void assertIsClose(double val1, double val2) { REQUIRE(val1 == doctest::Approx(val2)); } - /*! * TestXiosRead_2D * @@ -194,7 +183,7 @@ MPI_TEST_CASE("TestXiosRead_2D", 2) const size_t ny = xios_handler.getDomainLocalYSize("xy_domain"); for (size_t j = 0; j < ny; ++j) { for (size_t i = 0; i < nx; ++i) { - assertIsClose(field_2D(i, j), i + nx * j); + REQUIRE(field_2D(i, j) == doctest::Approx(i + nx * j)); } } xios_handler.context_finalize(); @@ -222,7 +211,7 @@ MPI_TEST_CASE("TestXiosRead_3D", 2) for (size_t k = 0; k < nz; ++k) { for (size_t j = 0; j < ny; ++j) { for (size_t i = 0; i < nx; ++i) { - assertIsClose(field_3D(i, j, k), i + nx * (j + ny * k)); + REQUIRE(field_3D(i, j, k) == doctest::Approx(i + nx * (j + ny * k))); } } }