LCOV - code coverage report
Current view: top level - include/restart - RestartableDataReader.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 9a5f1f Lines: 12 12 100.0 %
Date: 2026-06-21 21:23:42 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include "RestartableDataIO.h"
      13             : 
      14             : #include "RestartableData.h"
      15             : #include "InputStream.h"
      16             : #include "MoosePassKey.h"
      17             : 
      18             : #include <sstream>
      19             : #include <utility>
      20             : 
      21             : /**
      22             :  * Reader for restartable data written by the RestartableDataWriter.
      23             :  */
      24             : class RestartableDataReader : public RestartableDataIO
      25             : {
      26             : public:
      27             :   RestartableDataReader(MooseApp & app, RestartableDataMap & data, const bool force = false);
      28             :   RestartableDataReader(MooseApp & app,
      29             :                         std::vector<RestartableDataMap> & data,
      30             :                         const bool force = false);
      31             : 
      32             :   /**
      33             :    * Structure that contains the input streams for the reader.
      34             :    * One for the header and one for the data.
      35             :    */
      36             :   struct InputStreams
      37             :   {
      38             :     std::unique_ptr<InputStream> header;
      39             :     std::unique_ptr<InputStream> data;
      40             :   };
      41             : 
      42             :   /**
      43             :    * Sets the input stream for reading from the stringstreams \p header_stream
      44             :    * and \p data_stream for the header and data, respectively.
      45             :    */
      46             :   void setInput(std::unique_ptr<std::stringstream> header_stream,
      47             :                 std::unique_ptr<std::stringstream> data_stream);
      48             :   /**
      49             :    * Sets the input stream for reading to the file with the folder base \p folder_base
      50             :    */
      51             :   void setInput(const std::filesystem::path & folder_base);
      52             : 
      53             :   /**
      54             :    * @return Whether or not this reader is currently restoring
      55             :    */
      56       96003 :   bool isRestoring() const { return _streams.data != nullptr; }
      57             : 
      58             :   /**
      59             :    * Restores \p value in place from the open reader if it is present in the checkpoint and
      60             :    * has not yet been loaded. Used to recover data (e.g. reporter values) that is declared
      61             :    * after the bulk restore pass while the reader window is still open.
      62             :    *
      63             :    * Requires that restore() has been called.
      64             :    *
      65             :    * @return Whether or not the value was restored
      66             :    */
      67             :   bool restoreDataIfAvailable(RestartableDataValue & value,
      68             :                               const THREAD_ID tid,
      69             :                               Moose::PassKey<MooseApp>);
      70             : 
      71             :   /**
      72             :    * Clears the contents of the reader (header stream, data stream, header)
      73             :    *
      74             :    * This returns ownership of the resulting input in the event that
      75             :    * it should be retained
      76             :    */
      77             :   InputStreams clear();
      78             : 
      79             :   /**
      80             :    * Restores the restartable data. The input must be set via setInput() first.
      81             :    *
      82             :    * A handle to the input is still kept after this restore is called! In order to
      83             :    * remove that handle, you must call clear()!
      84             :    *
      85             :    * @param filter_names A list of data names to only restore. If not provided,
      86             :    * restores all.
      87             :    */
      88             :   void restore(const DataNames & filter_names = {});
      89             : 
      90             :   /**
      91             :    * Restores the data with name \p data_name of type T.
      92             :    *
      93             :    * This is used to restore data that was never declared in the restart,
      94             :    * but was stored in the backup. You cannot call this if the data has
      95             :    * already been declared or restored.
      96             :    *
      97             :    * Requires that restore() is called first to load the headers.
      98             :    *
      99             :    * @param data_name The name of the data
     100             :    * @param tid The thread
     101             :    * @param context The data context (if any)
     102             :    * @param args Arguments to forward to the constructor of the object
     103             :    * @return The restored data
     104             :    */
     105             :   template <typename T, typename... Args>
     106             :   T & restoreData(const std::string & data_name,
     107             :                   const THREAD_ID tid = 0,
     108             :                   void * const context = nullptr,
     109             :                   Args &&... args);
     110             : 
     111             :   ///@{
     112             :   /*
     113             :    * Enable/Disable errors to allow meta data to be created/loaded on different number or
     114             :    * processors
     115             :    *
     116             :    * See LoadSurrogateModelAction for use case
     117             :    */
     118        3580 :   void setErrorOnLoadWithDifferentNumberOfProcessors(bool value)
     119             :   {
     120        3580 :     _error_on_different_number_of_processors = value;
     121        3580 :   }
     122             :   ///@}
     123             : 
     124             :   /**
     125             :    * @return Whether or not restartable data is available in the folder \p folder_base
     126             :    *
     127             :    * Will error if the header is available and the data is not, or if the data is
     128             :    * and the header is not.
     129             :    */
     130             :   static bool isAvailable(const std::filesystem::path & folder_base);
     131             : 
     132             :   /**
     133             :    * @return Whether or not data exists in the headers with the name
     134             :    * \p data_name with type T on thread \p tid
     135             :    *
     136             :    * Requires that restore() is called first to load the headers.
     137             :    */
     138             :   template <typename T>
     139          42 :   bool hasData(const std::string & data_name, const THREAD_ID tid = 0) const
     140             :   {
     141          42 :     return hasData(data_name, typeid(T), tid);
     142             :   }
     143             : 
     144             : private:
     145             :   /**
     146             :    * Struct that describes data in the header
     147             :    */
     148             :   struct HeaderEntry
     149             :   {
     150             :     /// The position in the stream at which this data is
     151             :     std::streampos position;
     152             :     /// The size of this data
     153             :     std::size_t size;
     154             :     /// The hash code for this data (typeid(T).hash_code())
     155             :     std::size_t type_hash_code;
     156             :     /// The type for this data
     157             :     std::string type;
     158             :     /// Whether or not this data had context
     159             :     bool has_context;
     160             :   };
     161             : 
     162             :   /**
     163             :    * @return Whether or not data exists in the headers with the name
     164             :    * \p data_name with type \p type on thread \p tid
     165             :    *
     166             :    * Requires that restore() is called first to load the headers.
     167             :    */
     168             :   bool
     169             :   hasData(const std::string & data_name, const std::type_info & type, const THREAD_ID tid) const;
     170             : 
     171             :   /**
     172             :    * Internal method for reading the header (stored by RestartableDataWriter)
     173             :    */
     174             :   std::vector<std::unordered_map<std::string, HeaderEntry>>
     175             :   readHeader(InputStream & header_input) const;
     176             : 
     177             :   /**
     178             :    * Internal method for deserializing (restoring from backup into a value)
     179             :    */
     180             :   void deserializeValue(InputStream & data_input,
     181             :                         RestartableDataValue & value,
     182             :                         const HeaderEntry & header_entry) const;
     183             : 
     184             :   /**
     185             :    * Checks whether or not we're currently restoring and errors if not
     186             :    */
     187             :   void requireRestoring() const;
     188             : 
     189             :   /**
     190             :    * @return The header entry for the data with name \p data_name on thread \p tid
     191             :    * if it exists, and nullptr otherwise.
     192             :    *
     193             :    * Requires that restore() is called first to load the headers.
     194             :    */
     195             :   const HeaderEntry * queryHeader(const std::string & data_name, const THREAD_ID tid) const;
     196             :   /**
     197             :    * @return The header entry for the data with name \p data_name on thread \p tid.
     198             :    *
     199             :    * Requires that restore() is called first to load the headers.
     200             :    */
     201             :   const HeaderEntry & getHeader(const std::string & data_name, const THREAD_ID tid) const;
     202             : 
     203             :   /**
     204             :    * @returns Whether or not the type \p type is the same as the type in \p header_entry
     205             :    *
     206             :    * We need this because this check depends on whether or not we do a string comparison
     207             :    */
     208             :   bool isSameType(const HeaderEntry & header_entry, const std::type_info & type) const;
     209             : 
     210             :   /**
     211             :    * Internal method for restoring a new data value
     212             :    */
     213             :   RestartableDataValue & restoreData(const std::string & data_name,
     214             :                                      std::unique_ptr<RestartableDataValue> value,
     215             :                                      const THREAD_ID tid);
     216             :   /// The inputs for reading
     217             :   InputStreams _streams;
     218             : 
     219             :   /// The loaded headers from the restart
     220             :   std::vector<std::unordered_map<std::string, HeaderEntry>> _header;
     221             : 
     222             :   /// Whether or not we're currently restoring
     223             :   bool _is_restoring;
     224             : 
     225             :   /// Whether or not to error with a different number of processors
     226             :   bool _error_on_different_number_of_processors;
     227             : 
     228             :   /// Whether or not to forcefully attempt to read despite incompatibilities
     229             :   const bool _force;
     230             : };
     231             : 
     232             : template <typename T, typename... Args>
     233             : T &
     234          20 : RestartableDataReader::restoreData(const std::string & data_name,
     235             :                                    const THREAD_ID tid /* = 0 */,
     236             :                                    void * const context /* = nullptr */,
     237             :                                    Args &&... args)
     238             : {
     239          20 :   std::unique_ptr<RestartableDataValue> T_data =
     240             :       std::make_unique<RestartableData<T>>(data_name, context, std::forward<Args>(args)...);
     241          30 :   auto & value = restoreData(data_name, std::move(T_data), tid);
     242          10 :   auto T_value = dynamic_cast<RestartableData<T> *>(&value);
     243             :   mooseAssert(T_value, "Bad cast");
     244          20 :   return T_value->set();
     245          20 : }

Generated by: LCOV version 1.14