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

Generated by: LCOV version 1.14