From 27c15c16b3c7a7b1ffb5b3c4aaf315837d9ee1af Mon Sep 17 00:00:00 2001 From: "Victor A. P. Magri" Date: Fri, 6 Dec 2024 00:12:13 -0500 Subject: [PATCH 1/7] Add timing statistics for output file writing --- .../fileIO/Outputs/OutputBase.cpp | 22 +++++++++++++++++ .../fileIO/Outputs/OutputBase.hpp | 22 ++++++++++++++++- .../fileIO/Outputs/VTKOutput.cpp | 24 ++++++++++++------- .../fileIO/Outputs/VTKOutput.hpp | 3 +++ 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/src/coreComponents/fileIO/Outputs/OutputBase.cpp b/src/coreComponents/fileIO/Outputs/OutputBase.cpp index 0733dd38cc5..2f4f9940d39 100644 --- a/src/coreComponents/fileIO/Outputs/OutputBase.cpp +++ b/src/coreComponents/fileIO/Outputs/OutputBase.cpp @@ -18,6 +18,7 @@ */ #include "OutputBase.hpp" +#include "common/Timer.hpp" #include "common/MpiWrapper.hpp" #include "functions/FunctionBase.hpp" @@ -29,6 +30,7 @@ using namespace dataRepository; OutputBase::OutputBase( string const & name, Group * const parent ): ExecutableGroup( name, parent ), + m_outputTimer(), m_childDirectory(), m_parallelThreads( 1 ) { @@ -43,6 +45,8 @@ OutputBase::OutputBase( string const & name, setInputFlag( InputFlags::OPTIONAL ). setDescription( "Number of plot files." ); + // Add the Timers log level + addLogLevel< logInfo::OutputTimers >(); } OutputBase::~OutputBase() @@ -106,5 +110,23 @@ void OutputBase::setupDirectoryStructure() } } +void OutputBase::cleanup( real64 const GEOS_UNUSED_PARAM( time_n ), + integer const GEOS_UNUSED_PARAM( cycleNumber ), + integer const GEOS_UNUSED_PARAM( eventCounter ), + real64 const GEOS_UNUSED_PARAM( eventProgress ), + DomainPartition & GEOS_UNUSED_PARAM( domain ) ) +{ + // Report timing statistics + real64 const time = std::chrono::duration< double >( m_outputTimer ).count(); + real64 const minTime = MpiWrapper::min( time ); + real64 const maxTime = MpiWrapper::max( time ); + if( maxTime > 0 ) + { + GEOS_LOG_LEVEL_INFO_RANK_0( logInfo::OutputTimers, + GEOS_FMT( "{}: file writing time = {} s (min), {} s (max)", + getName(), minTime, maxTime ) ); + } +} + } /* namespace geos */ diff --git a/src/coreComponents/fileIO/Outputs/OutputBase.hpp b/src/coreComponents/fileIO/Outputs/OutputBase.hpp index f4129433f7d..42580bae2ac 100644 --- a/src/coreComponents/fileIO/Outputs/OutputBase.hpp +++ b/src/coreComponents/fileIO/Outputs/OutputBase.hpp @@ -21,11 +21,21 @@ #include "dataRepository/Group.hpp" #include "dataRepository/ExecutableGroup.hpp" - +#include "dataRepository/LogLevelsInfo.hpp" // For logInfo namespace +#include "common/Timer.hpp" namespace geos { +namespace logInfo +{ +struct OutputTimers +{ + static constexpr int getMinLogLevel() { return 1; } + static constexpr std::string_view getDescription() { return "Output timers information"; } +}; +} + /** * @class OutputBase * @@ -102,6 +112,16 @@ class OutputBase : public ExecutableGroup **/ virtual void initializePreSubGroups() override; + // Timer used to track duration of output operations + std::chrono::system_clock::duration m_outputTimer; + + /// @copydoc geos::ExecutableGroup::cleanup + virtual void cleanup( real64 const time_n, + integer const cycleNumber, + integer const eventCounter, + real64 const eventProgress, + DomainPartition & domain ) override; + private: string m_childDirectory; integer m_parallelThreads; diff --git a/src/coreComponents/fileIO/Outputs/VTKOutput.cpp b/src/coreComponents/fileIO/Outputs/VTKOutput.cpp index 15e4b1dac13..8b4ffec9fc1 100644 --- a/src/coreComponents/fileIO/Outputs/VTKOutput.cpp +++ b/src/coreComponents/fileIO/Outputs/VTKOutput.cpp @@ -80,7 +80,7 @@ VTKOutput::VTKOutput( string const & name, registerWrapper( viewKeysStruct::fieldNames, &m_fieldNames ). setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ). setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Names of the fields to output. If this attribute is specified, GEOSX outputs all the fields specified by the user, regardless of their `plotLevel`" ); + setDescription( "Names of the fields to output. If this attribute is specified, GEOS outputs all the fields specified by the user, regardless of their `plotLevel`" ); registerWrapper( viewKeysStruct::levelNames, &m_levelNames ). setInputFlag( InputFlags::OPTIONAL ). @@ -159,14 +159,20 @@ bool VTKOutput::execute( real64 const time_n, real64 const GEOS_UNUSED_PARAM ( eventProgress ), DomainPartition & domain ) { - GEOS_LOG_LEVEL_RANK_0( 1, GEOS_FMT( "{}: writing {} at time {} s (cycle number {})", getName(), m_fieldNames, time_n + dt, cycleNumber )); - - m_writer.setWriteGhostCells( m_writeGhostCells ); - m_writer.setWriteFaceElementsAs3D ( m_writeFaceElementsAs3D ); - m_writer.setOutputMode( m_writeBinaryData ); - m_writer.setOutputRegionType( m_outputRegionType ); - m_writer.setPlotLevel( m_plotLevel ); - m_writer.write( time_n, cycleNumber, domain ); + GEOS_MARK_FUNCTION; + + GEOS_LOG_LEVEL_RANK_0( 2, GEOS_FMT( "{}: writing {} at time {} s (cycle number {})", getName(), m_fieldNames, time_n + dt, cycleNumber )); + + { + Timer timer( m_outputTimer ); + + m_writer.setWriteGhostCells( m_writeGhostCells ); + m_writer.setWriteFaceElementsAs3D ( m_writeFaceElementsAs3D ); + m_writer.setOutputMode( m_writeBinaryData ); + m_writer.setOutputRegionType( m_outputRegionType ); + m_writer.setPlotLevel( m_plotLevel ); + m_writer.write( time_n, cycleNumber, domain ); + } return false; } diff --git a/src/coreComponents/fileIO/Outputs/VTKOutput.hpp b/src/coreComponents/fileIO/Outputs/VTKOutput.hpp index 5b167dc66d6..8778b722b6d 100644 --- a/src/coreComponents/fileIO/Outputs/VTKOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/VTKOutput.hpp @@ -77,6 +77,9 @@ class VTKOutput : public OutputBase DomainPartition & domain ) override { execute( time_n, 0, cycleNumber, eventCounter, eventProgress, domain ); + + // Call parent class cleanup to get the timing statistics + OutputBase::cleanup(time_n, cycleNumber, eventCounter, eventProgress, domain); } /** From fe465f2969e09f20feb65eb670a69506184a03c4 Mon Sep 17 00:00:00 2001 From: "Victor A. P. Magri" <50467563+victorapm@users.noreply.github.com> Date: Thu, 5 Dec 2024 21:15:25 -0800 Subject: [PATCH 2/7] Remove redundant include --- src/coreComponents/fileIO/Outputs/OutputBase.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreComponents/fileIO/Outputs/OutputBase.cpp b/src/coreComponents/fileIO/Outputs/OutputBase.cpp index 2f4f9940d39..15c6b894507 100644 --- a/src/coreComponents/fileIO/Outputs/OutputBase.cpp +++ b/src/coreComponents/fileIO/Outputs/OutputBase.cpp @@ -18,7 +18,6 @@ */ #include "OutputBase.hpp" -#include "common/Timer.hpp" #include "common/MpiWrapper.hpp" #include "functions/FunctionBase.hpp" From 5ca998ef71b0f2e53bbbb080937a2ac5d6dcfb63 Mon Sep 17 00:00:00 2001 From: "Victor A. P. Magri" Date: Fri, 6 Dec 2024 00:19:02 -0500 Subject: [PATCH 3/7] Style --- src/coreComponents/fileIO/Outputs/OutputBase.cpp | 4 ++-- src/coreComponents/fileIO/Outputs/VTKOutput.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreComponents/fileIO/Outputs/OutputBase.cpp b/src/coreComponents/fileIO/Outputs/OutputBase.cpp index 2f4f9940d39..8f26401ad3a 100644 --- a/src/coreComponents/fileIO/Outputs/OutputBase.cpp +++ b/src/coreComponents/fileIO/Outputs/OutputBase.cpp @@ -123,8 +123,8 @@ void OutputBase::cleanup( real64 const GEOS_UNUSED_PARAM( time_n ), if( maxTime > 0 ) { GEOS_LOG_LEVEL_INFO_RANK_0( logInfo::OutputTimers, - GEOS_FMT( "{}: file writing time = {} s (min), {} s (max)", - getName(), minTime, maxTime ) ); + GEOS_FMT( "{}: file writing time = {} s (min), {} s (max)", + getName(), minTime, maxTime ) ); } } diff --git a/src/coreComponents/fileIO/Outputs/VTKOutput.hpp b/src/coreComponents/fileIO/Outputs/VTKOutput.hpp index 8778b722b6d..b53ff6c2c78 100644 --- a/src/coreComponents/fileIO/Outputs/VTKOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/VTKOutput.hpp @@ -79,7 +79,7 @@ class VTKOutput : public OutputBase execute( time_n, 0, cycleNumber, eventCounter, eventProgress, domain ); // Call parent class cleanup to get the timing statistics - OutputBase::cleanup(time_n, cycleNumber, eventCounter, eventProgress, domain); + OutputBase::cleanup( time_n, cycleNumber, eventCounter, eventProgress, domain ); } /** From 1f6f99c3a2cee66b2c0565ab67552ddbe91d99f2 Mon Sep 17 00:00:00 2001 From: "Victor A. P. Magri" Date: Fri, 6 Dec 2024 00:24:05 -0500 Subject: [PATCH 4/7] Documentation --- src/coreComponents/fileIO/Outputs/OutputBase.hpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/coreComponents/fileIO/Outputs/OutputBase.hpp b/src/coreComponents/fileIO/Outputs/OutputBase.hpp index 42580bae2ac..8c515688732 100644 --- a/src/coreComponents/fileIO/Outputs/OutputBase.hpp +++ b/src/coreComponents/fileIO/Outputs/OutputBase.hpp @@ -29,9 +29,22 @@ namespace geos namespace logInfo { +/** + * @brief Log information structure for output timing data + * @details Provides configuration for logging output operation timing information + */ struct OutputTimers { + /** + * @brief Get the minimum log level for output timing information + * @return The minimum log level + */ static constexpr int getMinLogLevel() { return 1; } + + /** + * @brief Get the description of this timing category + * @return Description string for output timing information + */ static constexpr std::string_view getDescription() { return "Output timers information"; } }; } @@ -112,7 +125,7 @@ class OutputBase : public ExecutableGroup **/ virtual void initializePreSubGroups() override; - // Timer used to track duration of output operations + /// Timer used to track duration of file writing operations std::chrono::system_clock::duration m_outputTimer; /// @copydoc geos::ExecutableGroup::cleanup From 7d8677d89139f7d7c745c84ab91019eb1cdf8436 Mon Sep 17 00:00:00 2001 From: "Victor A. P. Magri" Date: Fri, 6 Dec 2024 11:10:32 -0500 Subject: [PATCH 5/7] Implement timers for all possible outputs --- .../fileIO/Outputs/BlueprintOutput.cpp | 84 +++++++++++-------- .../fileIO/Outputs/BlueprintOutput.hpp | 3 + .../fileIO/Outputs/ChomboIO.cpp | 14 ++++ .../fileIO/Outputs/ChomboIO.hpp | 3 + .../fileIO/Outputs/OutputBase.hpp | 29 ++++--- .../fileIO/Outputs/PythonOutput.cpp | 14 ++++ .../fileIO/Outputs/PythonOutput.hpp | 3 + .../fileIO/Outputs/RestartOutput.cpp | 29 +++++-- .../fileIO/Outputs/RestartOutput.hpp | 3 + .../fileIO/Outputs/SiloOutput.cpp | 68 +++++++++------ .../fileIO/Outputs/SiloOutput.hpp | 3 + .../fileIO/Outputs/TimeHistoryOutput.cpp | 28 ++++++- .../fileIO/Outputs/TimeHistoryOutput.hpp | 3 + .../fileIO/Outputs/VTKOutput.cpp | 14 ++++ .../fileIO/Outputs/VTKOutput.hpp | 3 + 15 files changed, 219 insertions(+), 82 deletions(-) diff --git a/src/coreComponents/fileIO/Outputs/BlueprintOutput.cpp b/src/coreComponents/fileIO/Outputs/BlueprintOutput.cpp index 21457e7796e..cad26fcbb54 100644 --- a/src/coreComponents/fileIO/Outputs/BlueprintOutput.cpp +++ b/src/coreComponents/fileIO/Outputs/BlueprintOutput.cpp @@ -129,53 +129,57 @@ BlueprintOutput::BlueprintOutput( string const & name, } /////////////////////////////////////////////////////////////////////////////////////////////////// -bool BlueprintOutput::execute( real64 const time, - real64 const, - integer const cycle, - integer const, - real64 const, +bool BlueprintOutput::execute( real64 const time_n, + real64 const GEOS_UNUSED_PARAM( dt ), + integer const cycleNumber, + integer const GEOS_UNUSED_PARAM( eventCounter ), + real64 const GEOS_UNUSED_PARAM( eventProgress ), DomainPartition & domain ) { GEOS_MARK_FUNCTION; - MeshLevel const & meshLevel = domain.getMeshBody( 0 ).getBaseDiscretization(); + { + Timer timer( m_outputTimer ); - conduit::Node meshRoot; - conduit::Node & mesh = meshRoot[ "mesh" ]; - conduit::Node & coordset = mesh[ "coordsets/nodes" ]; - conduit::Node & topologies = mesh[ "topologies" ]; + MeshLevel const & meshLevel = domain.getMeshBody( 0 ).getBaseDiscretization(); - mesh[ "state/time" ] = time; - mesh[ "state/cycle" ] = cycle; + conduit::Node meshRoot; + conduit::Node & mesh = meshRoot[ "mesh" ]; + conduit::Node & coordset = mesh[ "coordsets/nodes" ]; + conduit::Node & topologies = mesh[ "topologies" ]; - addNodalData( meshLevel.getNodeManager(), coordset, topologies, mesh[ "fields" ] ); + mesh[ "state/time" ] = time_n; + mesh[ "state/cycle" ] = cycleNumber; - dataRepository::Group averagedElementData( "averagedElementData", this ); - addElementData( meshLevel.getElemManager(), coordset, topologies, mesh[ "fields" ], averagedElementData ); + addNodalData( meshLevel.getNodeManager(), coordset, topologies, mesh[ "fields" ] ); - /// The Blueprint will complain if the fields node is present but empty. - if( mesh[ "fields" ].number_of_children() == 0 ) - { - mesh.remove( "fields" ); - } + dataRepository::Group averagedElementData( "averagedElementData", this ); + addElementData( meshLevel.getElemManager(), coordset, topologies, mesh[ "fields" ], averagedElementData ); + + /// The Blueprint will complain if the fields node is present but empty. + if( mesh[ "fields" ].number_of_children() == 0 ) + { + mesh.remove( "fields" ); + } - /// Verify that the mesh conforms to the Blueprint. - conduit::Node info; - GEOS_ASSERT_MSG( conduit::blueprint::verify( "mesh", meshRoot, info ), info.to_json() ); + /// Verify that the mesh conforms to the Blueprint. + conduit::Node info; + GEOS_ASSERT_MSG( conduit::blueprint::verify( "mesh", meshRoot, info ), info.to_json() ); - /// Generate the Blueprint index. - conduit::Node fileRoot; - conduit::Node & index = fileRoot[ "blueprint_index/mesh" ]; - conduit::blueprint::mesh::generate_index( mesh, "mesh", MpiWrapper::commSize(), index ); + /// Generate the Blueprint index. + conduit::Node fileRoot; + conduit::Node & index = fileRoot[ "blueprint_index/mesh" ]; + conduit::blueprint::mesh::generate_index( mesh, "mesh", MpiWrapper::commSize(), index ); - /// Verify that the index conforms to the Blueprint. - info.reset(); - GEOS_ASSERT_MSG( conduit::blueprint::mesh::index::verify( index, info ), info.to_json() ); + /// Verify that the index conforms to the Blueprint. + info.reset(); + GEOS_ASSERT_MSG( conduit::blueprint::mesh::index::verify( index, info ), info.to_json() ); - /// Write out the root index file, then write out the mesh. - string const completePath = GEOS_FMT( "{}/blueprintFiles/cycle_{:07}", OutputBase::getOutputDirectory(), cycle ); - string const filePathForRank = dataRepository::writeRootFile( fileRoot, completePath ); - conduit::relay::io::save( meshRoot, filePathForRank, "hdf5" ); + /// Write out the root index file, then write out the mesh. + string const completePath = GEOS_FMT( "{}/blueprintFiles/cycle_{:07}", OutputBase::getOutputDirectory(), cycleNumber ); + string const filePathForRank = dataRepository::writeRootFile( fileRoot, completePath ); + conduit::relay::io::save( meshRoot, filePathForRank, "hdf5" ); + } return false; } @@ -307,7 +311,19 @@ void BlueprintOutput::writeOutConstitutiveData( dataRepository::Group const & co } ); } +namespace logInfo +{ +struct BlueprintOutputTimer : public OutputTimerBase +{ + std::string_view getDescription() const override { return "Blueprint output timing"; } +}; +} +logInfo::OutputTimerBase const & BlueprintOutput::getTimerCategory() const +{ + static logInfo::BlueprintOutputTimer timer; + return timer; +} REGISTER_CATALOG_ENTRY( OutputBase, BlueprintOutput, string const &, dataRepository::Group * const ) diff --git a/src/coreComponents/fileIO/Outputs/BlueprintOutput.hpp b/src/coreComponents/fileIO/Outputs/BlueprintOutput.hpp index 7d17570d47d..e8e8f558a24 100644 --- a/src/coreComponents/fileIO/Outputs/BlueprintOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/BlueprintOutput.hpp @@ -36,6 +36,9 @@ class ElementRegionManager; */ class BlueprintOutput : public OutputBase { +protected: + logInfo::OutputTimerBase const & getTimerCategory() const override; + public: /** diff --git a/src/coreComponents/fileIO/Outputs/ChomboIO.cpp b/src/coreComponents/fileIO/Outputs/ChomboIO.cpp index 674f1e4eace..26f73a9eb43 100644 --- a/src/coreComponents/fileIO/Outputs/ChomboIO.cpp +++ b/src/coreComponents/fileIO/Outputs/ChomboIO.cpp @@ -30,6 +30,20 @@ namespace geos using namespace dataRepository; +namespace logInfo +{ +struct ChomboOutputTimer : public OutputTimerBase +{ + std::string_view getDescription() const override { return "Chombo output timing"; } +}; +} + +logInfo::OutputTimerBase const & ChomboIO::getTimerCategory() const +{ + static logInfo::ChomboOutputTimer timer; + return timer; +} + ChomboIO::ChomboIO( string const & name, Group * const parent ): OutputBase( name, parent ), m_coupler( nullptr ), diff --git a/src/coreComponents/fileIO/Outputs/ChomboIO.hpp b/src/coreComponents/fileIO/Outputs/ChomboIO.hpp index c483f066968..f9c331fb58c 100644 --- a/src/coreComponents/fileIO/Outputs/ChomboIO.hpp +++ b/src/coreComponents/fileIO/Outputs/ChomboIO.hpp @@ -89,6 +89,9 @@ class ChomboIO final : public OutputBase } viewKeys; /// @endcond +protected: + logInfo::OutputTimerBase const & getTimerCategory() const override; + private: ChomboCoupler * m_coupler; string m_outputPath; diff --git a/src/coreComponents/fileIO/Outputs/OutputBase.hpp b/src/coreComponents/fileIO/Outputs/OutputBase.hpp index 8c515688732..1146d8aef6c 100644 --- a/src/coreComponents/fileIO/Outputs/OutputBase.hpp +++ b/src/coreComponents/fileIO/Outputs/OutputBase.hpp @@ -30,22 +30,26 @@ namespace geos namespace logInfo { /** - * @brief Log information structure for output timing data + * @brief Base timer category for output operations * @details Provides configuration for logging output operation timing information */ struct OutputTimers { - /** - * @brief Get the minimum log level for output timing information - * @return The minimum log level - */ + static std::string_view getDescription() { return "Output timing information"; } static constexpr int getMinLogLevel() { return 1; } +}; - /** - * @brief Get the description of this timing category - * @return Description string for output timing information - */ - static constexpr std::string_view getDescription() { return "Output timers information"; } +/** + * @brief Base interface for specific output type timers + * @details Each output type (VTK, Silo, etc.) implements this interface to provide + * its own timing category. This is used in conjunction with OutputTimers: + * - OutputTimerBase: For polymorphic behavior in derived output classes + * - OutputTimers: For the general output timing logging infrastructure + */ +struct OutputTimerBase +{ + virtual std::string_view getDescription() const = 0; + virtual ~OutputTimerBase() = default; }; } @@ -125,9 +129,12 @@ class OutputBase : public ExecutableGroup **/ virtual void initializePreSubGroups() override; - /// Timer used to track duration of file writing operations + /// Timer used to track duration of file writing operations for this specific output type std::chrono::system_clock::duration m_outputTimer; + /// Get the timer category for this specific output type + virtual logInfo::OutputTimerBase const & getTimerCategory() const = 0; + /// @copydoc geos::ExecutableGroup::cleanup virtual void cleanup( real64 const time_n, integer const cycleNumber, diff --git a/src/coreComponents/fileIO/Outputs/PythonOutput.cpp b/src/coreComponents/fileIO/Outputs/PythonOutput.cpp index e78f8835a06..5891fe55e26 100644 --- a/src/coreComponents/fileIO/Outputs/PythonOutput.cpp +++ b/src/coreComponents/fileIO/Outputs/PythonOutput.cpp @@ -18,6 +18,20 @@ namespace geos { +namespace logInfo +{ +struct PythonOutputTimer : public OutputTimerBase +{ + std::string_view getDescription() const override { return "Python output timing"; } +}; +} + +logInfo::OutputTimerBase const & PythonOutput::getTimerCategory() const +{ + static logInfo::PythonOutputTimer timer; + return timer; +} + REGISTER_CATALOG_ENTRY( OutputBase, PythonOutput, string const &, dataRepository::Group * const ) } // namespace geos diff --git a/src/coreComponents/fileIO/Outputs/PythonOutput.hpp b/src/coreComponents/fileIO/Outputs/PythonOutput.hpp index 0e6c3cebb85..a73b6781654 100644 --- a/src/coreComponents/fileIO/Outputs/PythonOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/PythonOutput.hpp @@ -75,6 +75,9 @@ class PythonOutput : public OutputBase GEOS_UNUSED_VAR( domain ); return true; } + +protected: + logInfo::OutputTimerBase const & getTimerCategory() const override; }; diff --git a/src/coreComponents/fileIO/Outputs/RestartOutput.cpp b/src/coreComponents/fileIO/Outputs/RestartOutput.cpp index 6fb7a2c6b19..6eb07281cf6 100644 --- a/src/coreComponents/fileIO/Outputs/RestartOutput.cpp +++ b/src/coreComponents/fileIO/Outputs/RestartOutput.cpp @@ -24,6 +24,14 @@ namespace geos using namespace dataRepository; +namespace logInfo +{ +struct RestartOutputTimer : public OutputTimerBase +{ + std::string_view getDescription() const override { return "Restart output timing"; } +}; +} + RestartOutput::RestartOutput( string const & name, Group * const parent ): OutputBase( name, parent ) @@ -41,19 +49,24 @@ bool RestartOutput::execute( real64 const GEOS_UNUSED_PARAM( time_n ), { GEOS_MARK_FUNCTION; - Group & rootGroup = this->getGroupByPath( "/Problem" ); + { + Timer timer( m_outputTimer ); - // Ignoring the eventProgress indicator for now to be compliant with the integrated test repo - // integer const eventProgressPercent = static_cast(eventProgress * 100.0); - string const fileName = GEOS_FMT( "{}_restart_{:09}", getFileNameRoot(), cycleNumber ); - - rootGroup.prepareToWrite(); - writeTree( joinPath( OutputBase::getOutputDirectory(), fileName ), *(rootGroup.getConduitNode().parent()) ); - rootGroup.finishWriting(); + Group & rootGroup = this->getGroupByPath( "/Problem" ); + string const fileName = GEOS_FMT( "{}_restart_{:09}", getFileNameRoot(), cycleNumber ); + rootGroup.prepareToWrite(); + writeTree( joinPath( OutputBase::getOutputDirectory(), fileName ), *(rootGroup.getConduitNode().parent()) ); + rootGroup.finishWriting(); + } return false; } +logInfo::OutputTimerBase const & RestartOutput::getTimerCategory() const +{ + static logInfo::RestartOutputTimer timer; + return timer; +} REGISTER_CATALOG_ENTRY( OutputBase, RestartOutput, string const &, Group * const ) } /* namespace geos */ diff --git a/src/coreComponents/fileIO/Outputs/RestartOutput.hpp b/src/coreComponents/fileIO/Outputs/RestartOutput.hpp index a2a12be781c..91c2fb2954f 100644 --- a/src/coreComponents/fileIO/Outputs/RestartOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/RestartOutput.hpp @@ -78,6 +78,9 @@ class RestartOutput : public OutputBase dataRepository::ViewKey writeFEMFaces = { "writeFEMFaces" }; } viewKeys; /// @endcond + +protected: + logInfo::OutputTimerBase const & getTimerCategory() const override; }; diff --git a/src/coreComponents/fileIO/Outputs/SiloOutput.cpp b/src/coreComponents/fileIO/Outputs/SiloOutput.cpp index 756facc2da1..ba03ceead5f 100644 --- a/src/coreComponents/fileIO/Outputs/SiloOutput.cpp +++ b/src/coreComponents/fileIO/Outputs/SiloOutput.cpp @@ -28,6 +28,20 @@ namespace geos using namespace dataRepository; +namespace logInfo +{ +struct SiloOutputTimer : public OutputTimerBase +{ + std::string_view getDescription() const override { return "Silo output timing"; } +}; +} + +logInfo::OutputTimerBase const & SiloOutput::getTimerCategory() const +{ + static logInfo::SiloOutputTimer timer; + return timer; +} + SiloOutput::SiloOutput( string const & name, Group * const parent ): OutputBase( name, parent ), @@ -122,31 +136,35 @@ bool SiloOutput::execute( real64 const time_n, { GEOS_MARK_FUNCTION; - SiloFile silo; - - int const size = MpiWrapper::commSize( MPI_COMM_GEOS ); - int const rank = MpiWrapper::commRank( MPI_COMM_GEOS ); - MpiWrapper::barrier( MPI_COMM_GEOS ); - - integer const numFiles = parallelThreads() == 0 ? size : parallelThreads(); - - // TODO set this during initialization - // silo.setOutputDirectory( getGlobalState().getCommandLineOptions().outputDirectory ), - silo.setOutputDirectory( getOutputDirectory() ), - silo.setPlotLevel( m_plotLevel ); - silo.setWriteEdgeMesh( m_writeEdgeMesh ); - silo.setWriteFaceMesh( m_writeFaceMesh ); - silo.setWriteCellElementMesh( m_writeCellElementMesh ); - silo.setWriteFaceElementMesh( m_writeFaceElementMesh ); - silo.setOnlyPlotSpecifiedFieldNamesFlag( m_onlyPlotSpecifiedFieldNames ); - silo.setFieldNames( m_fieldNames.toViewConst() ); - silo.setPlotFileRoot( m_plotFileRoot ); - silo.initialize( numFiles ); - silo.waitForBatonWrite( rank, cycleNumber, eventCounter, false ); - silo.writeDomainPartition( domain, cycleNumber, time_n + dt * eventProgress, 0 ); - silo.handOffBaton(); - silo.clearEmptiesFromMultiObjects( cycleNumber ); - silo.finish(); + { + Timer timer( m_outputTimer ); + + SiloFile silo; + + int const size = MpiWrapper::commSize( MPI_COMM_GEOS ); + int const rank = MpiWrapper::commRank( MPI_COMM_GEOS ); + MpiWrapper::barrier( MPI_COMM_GEOS ); + + integer const numFiles = parallelThreads() == 0 ? size : parallelThreads(); + + // TODO set this during initialization + // silo.setOutputDirectory( getGlobalState().getCommandLineOptions().outputDirectory ), + silo.setOutputDirectory( getOutputDirectory() ), + silo.setPlotLevel( m_plotLevel ); + silo.setWriteEdgeMesh( m_writeEdgeMesh ); + silo.setWriteFaceMesh( m_writeFaceMesh ); + silo.setWriteCellElementMesh( m_writeCellElementMesh ); + silo.setWriteFaceElementMesh( m_writeFaceElementMesh ); + silo.setOnlyPlotSpecifiedFieldNamesFlag( m_onlyPlotSpecifiedFieldNames ); + silo.setFieldNames( m_fieldNames.toViewConst() ); + silo.setPlotFileRoot( m_plotFileRoot ); + silo.initialize( numFiles ); + silo.waitForBatonWrite( rank, cycleNumber, eventCounter, false ); + silo.writeDomainPartition( domain, cycleNumber, time_n + dt * eventProgress, 0 ); + silo.handOffBaton(); + silo.clearEmptiesFromMultiObjects( cycleNumber ); + silo.finish(); + } return false; } diff --git a/src/coreComponents/fileIO/Outputs/SiloOutput.hpp b/src/coreComponents/fileIO/Outputs/SiloOutput.hpp index bb3574f3745..635ba196c98 100644 --- a/src/coreComponents/fileIO/Outputs/SiloOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/SiloOutput.hpp @@ -85,6 +85,9 @@ class SiloOutput : public OutputBase } siloOutputViewKeys; /// @endcond +protected: + logInfo::OutputTimerBase const & getTimerCategory() const override; + private: void postInputInitialization() override; diff --git a/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.cpp b/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.cpp index d01edac3dcf..7e1299aac57 100644 --- a/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.cpp +++ b/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.cpp @@ -25,6 +25,20 @@ namespace geos { using namespace dataRepository; +namespace logInfo +{ +struct TimeHistoryOutputTimer : public OutputTimerBase +{ + std::string_view getDescription() const override { return "Time history output timing"; } +}; +} + +logInfo::OutputTimerBase const & TimeHistoryOutput::getTimerCategory() const +{ + static logInfo::TimeHistoryOutputTimer timer; + return timer; +} + TimeHistoryOutput::TimeHistoryOutput( string const & name, Group * const parent ): OutputBase( name, parent ), @@ -166,12 +180,18 @@ bool TimeHistoryOutput::execute( real64 const GEOS_UNUSED_PARAM( time_n ), DomainPartition & GEOS_UNUSED_PARAM( domain ) ) { GEOS_MARK_FUNCTION; - localIndex newBuffered = m_io.front()->getBufferedCount( ); - for( auto & th_io : m_io ) + { - th_io->write( ); + Timer timer( m_outputTimer ); + + localIndex newBuffered = m_io.front()->getBufferedCount( ); + for( auto & th_io : m_io ) + { + th_io->write( ); + } + m_recordCount += newBuffered; } - m_recordCount += newBuffered; + return false; } diff --git a/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.hpp b/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.hpp index d7793943d9c..18230805668 100644 --- a/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.hpp @@ -114,6 +114,9 @@ class TimeHistoryOutput : public OutputBase virtual PyTypeObject * getPythonType() const override; #endif +protected: + logInfo::OutputTimerBase const & getTimerCategory() const override; + private: /** diff --git a/src/coreComponents/fileIO/Outputs/VTKOutput.cpp b/src/coreComponents/fileIO/Outputs/VTKOutput.cpp index 8b4ffec9fc1..b6f4348899e 100644 --- a/src/coreComponents/fileIO/Outputs/VTKOutput.cpp +++ b/src/coreComponents/fileIO/Outputs/VTKOutput.cpp @@ -29,6 +29,20 @@ namespace geos using namespace dataRepository; +namespace logInfo +{ +struct VTKOutputTimer : public OutputTimerBase +{ + std::string_view getDescription() const override { return "VTK output timing"; } +}; +} + +logInfo::OutputTimerBase const & VTKOutput::getTimerCategory() const +{ + static logInfo::VTKOutputTimer timer; + return timer; +} + VTKOutput::VTKOutput( string const & name, Group * const parent ): OutputBase( name, parent ), diff --git a/src/coreComponents/fileIO/Outputs/VTKOutput.hpp b/src/coreComponents/fileIO/Outputs/VTKOutput.hpp index b53ff6c2c78..0f112c6225e 100644 --- a/src/coreComponents/fileIO/Outputs/VTKOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/VTKOutput.hpp @@ -112,6 +112,9 @@ class VTKOutput : public OutputBase virtual PyTypeObject * getPythonType() const override; #endif +protected: + logInfo::OutputTimerBase const & getTimerCategory() const override; + private: string m_plotFileRoot; From b528cb57868406227b38de89981fb69deef37b60 Mon Sep 17 00:00:00 2001 From: "Victor A. P. Magri" Date: Fri, 6 Dec 2024 11:20:46 -0500 Subject: [PATCH 6/7] Documentation --- .../fileIO/Outputs/BlueprintOutput.hpp | 3 +++ .../fileIO/Outputs/ChomboIO.hpp | 3 +++ .../fileIO/Outputs/OutputBase.hpp | 19 +++++++++++++++++-- .../fileIO/Outputs/RestartOutput.hpp | 3 +++ .../fileIO/Outputs/SiloOutput.hpp | 3 +++ .../fileIO/Outputs/TimeHistoryOutput.hpp | 3 +++ .../fileIO/Outputs/VTKOutput.hpp | 3 +++ 7 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/coreComponents/fileIO/Outputs/BlueprintOutput.hpp b/src/coreComponents/fileIO/Outputs/BlueprintOutput.hpp index e8e8f558a24..fd963698c3c 100644 --- a/src/coreComponents/fileIO/Outputs/BlueprintOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/BlueprintOutput.hpp @@ -37,6 +37,9 @@ class ElementRegionManager; class BlueprintOutput : public OutputBase { protected: + /** + * @copydoc OutputBase::getTimerCategory + */ logInfo::OutputTimerBase const & getTimerCategory() const override; public: diff --git a/src/coreComponents/fileIO/Outputs/ChomboIO.hpp b/src/coreComponents/fileIO/Outputs/ChomboIO.hpp index f9c331fb58c..c9e60cf2f79 100644 --- a/src/coreComponents/fileIO/Outputs/ChomboIO.hpp +++ b/src/coreComponents/fileIO/Outputs/ChomboIO.hpp @@ -90,6 +90,9 @@ class ChomboIO final : public OutputBase /// @endcond protected: + /** + * @copydoc OutputBase::getTimerCategory + */ logInfo::OutputTimerBase const & getTimerCategory() const override; private: diff --git a/src/coreComponents/fileIO/Outputs/OutputBase.hpp b/src/coreComponents/fileIO/Outputs/OutputBase.hpp index 1146d8aef6c..ae957e22213 100644 --- a/src/coreComponents/fileIO/Outputs/OutputBase.hpp +++ b/src/coreComponents/fileIO/Outputs/OutputBase.hpp @@ -35,7 +35,16 @@ namespace logInfo */ struct OutputTimers { + /** + * @brief Get the description of this timer + * @return String view containing the timer description + */ static std::string_view getDescription() { return "Output timing information"; } + + /** + * @brief Get the minimum log level for this timer + * @return Integer representing the minimum log level + */ static constexpr int getMinLogLevel() { return 1; } }; @@ -48,8 +57,11 @@ struct OutputTimers */ struct OutputTimerBase { + /** + * @brief Get the description of this timer + * @return String view containing the timer description + */ virtual std::string_view getDescription() const = 0; - virtual ~OutputTimerBase() = default; }; } @@ -132,7 +144,10 @@ class OutputBase : public ExecutableGroup /// Timer used to track duration of file writing operations for this specific output type std::chrono::system_clock::duration m_outputTimer; - /// Get the timer category for this specific output type + /** + * @brief Get the timer category for this output type + * @return Reference to the output timer base for timing statistics + */ virtual logInfo::OutputTimerBase const & getTimerCategory() const = 0; /// @copydoc geos::ExecutableGroup::cleanup diff --git a/src/coreComponents/fileIO/Outputs/RestartOutput.hpp b/src/coreComponents/fileIO/Outputs/RestartOutput.hpp index 91c2fb2954f..11c8715ed76 100644 --- a/src/coreComponents/fileIO/Outputs/RestartOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/RestartOutput.hpp @@ -80,6 +80,9 @@ class RestartOutput : public OutputBase /// @endcond protected: + /** + * @copydoc OutputBase::getTimerCategory + */ logInfo::OutputTimerBase const & getTimerCategory() const override; }; diff --git a/src/coreComponents/fileIO/Outputs/SiloOutput.hpp b/src/coreComponents/fileIO/Outputs/SiloOutput.hpp index 635ba196c98..6b0a371974f 100644 --- a/src/coreComponents/fileIO/Outputs/SiloOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/SiloOutput.hpp @@ -86,6 +86,9 @@ class SiloOutput : public OutputBase /// @endcond protected: + /** + * @copydoc OutputBase::getTimerCategory + */ logInfo::OutputTimerBase const & getTimerCategory() const override; private: diff --git a/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.hpp b/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.hpp index 18230805668..e2846f7c312 100644 --- a/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/TimeHistoryOutput.hpp @@ -115,6 +115,9 @@ class TimeHistoryOutput : public OutputBase #endif protected: + /** + * @copydoc OutputBase::getTimerCategory + */ logInfo::OutputTimerBase const & getTimerCategory() const override; private: diff --git a/src/coreComponents/fileIO/Outputs/VTKOutput.hpp b/src/coreComponents/fileIO/Outputs/VTKOutput.hpp index 0f112c6225e..bf36e900eaf 100644 --- a/src/coreComponents/fileIO/Outputs/VTKOutput.hpp +++ b/src/coreComponents/fileIO/Outputs/VTKOutput.hpp @@ -113,6 +113,9 @@ class VTKOutput : public OutputBase #endif protected: + /** + * @copydoc OutputBase::getTimerCategory + */ logInfo::OutputTimerBase const & getTimerCategory() const override; private: From 01a009f5baec0f6f05d77b72013b42930cd57346 Mon Sep 17 00:00:00 2001 From: "Victor A. P. Magri" <50467563+victorapm@users.noreply.github.com> Date: Fri, 6 Dec 2024 20:56:32 -0800 Subject: [PATCH 7/7] Update baselines --- .integrated_tests.yaml | 2 +- BASELINE_NOTES.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.integrated_tests.yaml b/.integrated_tests.yaml index 0ce10cbe33b..3aa31a7e4cb 100644 --- a/.integrated_tests.yaml +++ b/.integrated_tests.yaml @@ -1,6 +1,6 @@ baselines: bucket: geosx - baseline: integratedTests/baseline_integratedTests-pr3467-9212-976cc3b + baseline: integratedTests/baseline_integratedTests-pr3480-9217-caaecb8 allow_fail: all: '' streak: '' diff --git a/BASELINE_NOTES.md b/BASELINE_NOTES.md index 8f344877826..acbeb39e382 100644 --- a/BASELINE_NOTES.md +++ b/BASELINE_NOTES.md @@ -6,6 +6,10 @@ This file is designed to track changes to the integrated test baselines. Any developer who updates the baseline ID in the .integrated_tests.yaml file is expected to create an entry in this file with the pull request number, date, and their justification for rebaselining. These notes should be in reverse-chronological order, and use the following time format: (YYYY-MM-DD). +PR #3480 (2024-12-06) +===================== +Add "logLevel" parameter under /Problem/Outputs in baseline files + PR #3361 (2024-12-03) ===================== Revert default gravity treatment to old version. Make the way introduced in #3337 optional.