LCOV - code coverage report
Current view: top level - src/restart - RestartableDataWriter.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 60 66 90.9 %
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             : #include "RestartableDataWriter.h"
      11             : 
      12             : #include "DataIO.h"
      13             : #include "RestartableDataMap.h"
      14             : 
      15             : #include <fstream>
      16             : #include <system_error>
      17             : 
      18        9573 : RestartableDataWriter::RestartableDataWriter(MooseApp & app, RestartableDataMap & data)
      19        9573 :   : RestartableDataIO(app, data)
      20             : {
      21        9573 : }
      22             : 
      23       41839 : RestartableDataWriter::RestartableDataWriter(MooseApp & app, std::vector<RestartableDataMap> & data)
      24       41839 :   : RestartableDataIO(app, data)
      25             : {
      26       41839 : }
      27             : 
      28             : void
      29       51412 : RestartableDataWriter::write(std::ostream & header_stream, std::ostream & data_stream)
      30             : {
      31             :   // Set everything as not stored
      32      106420 :   for (const auto tid : make_range(dataSize()))
      33     1864759 :     for (auto & value : currentData(tid))
      34     1809751 :       value.setNotStored({});
      35             : 
      36             :   // Header
      37       51412 :   char id[] = {'R', 'D'};
      38       51412 :   header_stream.write(id, 2);
      39             : 
      40             :   // File version
      41       51412 :   auto file_version = CURRENT_BACKUP_FILE_VERSION;
      42       51412 :   dataStore(header_stream, file_version, nullptr);
      43             : 
      44             :   // Type hash for basic hash
      45       51412 :   std::size_t compare_hash_code = typeid(COMPARE_HASH_CODE_TYPE).hash_code();
      46       51412 :   dataStore(header_stream, compare_hash_code, nullptr);
      47             : 
      48             :   // Number of procs
      49       51412 :   auto n_procs = n_processors();
      50       51412 :   dataStore(header_stream, n_procs, nullptr);
      51             : 
      52             :   // Number of data
      53       51412 :   auto num_data = dataSize();
      54       51412 :   dataStore(header_stream, num_data, nullptr);
      55             : 
      56             :   // Size of data for each thread
      57      106420 :   for (const auto tid : make_range(dataSize()))
      58             :   {
      59       55008 :     std::size_t n_data = currentData(tid).size();
      60       55008 :     dataStore(header_stream, n_data, nullptr);
      61             :   }
      62             : 
      63             :   // Write out the RestartableData header, and store the actual data separately
      64      106415 :   for (const auto tid : make_range(dataSize()))
      65     1864710 :     for (auto & data : currentData(tid))
      66             :     {
      67             :       // Store the data
      68     1809707 :       const std::size_t data_start_position = static_cast<std::size_t>(data_stream.tellp());
      69     1809707 :       data.store(data_stream);
      70     1809703 :       std::size_t data_size = static_cast<std::size_t>(data_stream.tellp()) - data_start_position;
      71             : 
      72             :       // Store name, size, type hash, and type in the header
      73             :       mooseAssert(data.name().size(), "Empty name");
      74     1809703 :       std::string name = data.name();
      75     1809703 :       std::string type = data.typeId().name();
      76     1809703 :       std::size_t type_hash_code = data.typeId().hash_code();
      77     1809703 :       bool has_context = data.hasContext();
      78     1809703 :       dataStore(header_stream, name, nullptr);
      79     1809703 :       dataStore(header_stream, data_size, nullptr);
      80     1809703 :       dataStore(header_stream, type_hash_code, nullptr);
      81     1809703 :       dataStore(header_stream, type, nullptr);
      82     1809703 :       dataStore(header_stream, has_context, nullptr);
      83     1809703 :     }
      84       51408 : }
      85             : 
      86             : std::vector<std::filesystem::path>
      87       20179 : RestartableDataWriter::write(const std::filesystem::path & folder_base)
      88             : {
      89       20179 :   const auto header_file = restartableHeaderFile(folder_base);
      90       20179 :   const auto data_file = restartableDataFile(folder_base);
      91             : 
      92             :   // Make the folder if it doesn't exist
      93       20179 :   const auto dir = header_file.parent_path();
      94             :   mooseAssert(dir == data_file.parent_path(), "Inconsistent directories");
      95       20179 :   if (!std::filesystem::exists(dir))
      96             :   {
      97       18596 :     std::error_code err;
      98       18596 :     if (!std::filesystem::create_directory(dir, err))
      99           0 :       mooseError("Unable to create restart directory\n",
     100           0 :                  std::filesystem::absolute(dir),
     101             :                  "\n\n",
     102           0 :                  err.message());
     103             :   }
     104             : 
     105             :   // We want to keep track of the paths that we create so that we can
     106             :   // return them for file management later (primarily removing old checkpoints)
     107       20179 :   std::vector<std::filesystem::path> paths;
     108             : 
     109             :   // Helper for opening a stream for use
     110       80716 :   auto open = [&paths](const std::filesystem::path & filename)
     111             :   {
     112       40358 :     std::ofstream stream;
     113       40358 :     stream.open(filename.c_str(), std::ios::out | std::ios::binary);
     114       40358 :     if (!stream.is_open())
     115           0 :       mooseError(
     116           0 :           "Unable to open restart file ", std::filesystem::absolute(filename), " for writing");
     117       40358 :     paths.push_back(filename);
     118       40358 :     return stream;
     119           0 :   };
     120             : 
     121             :   // Open and write
     122       20179 :   auto header_stream = open(header_file);
     123       20179 :   auto data_stream = open(data_file);
     124       20179 :   write(header_stream, data_stream);
     125             : 
     126             :   // Update the folder's modified time to now for consistency
     127             :   // (this used in checking for the latest checkpoint)
     128       20175 :   const auto data_write_time = std::filesystem::last_write_time(header_file);
     129       20175 :   std::filesystem::last_write_time(dir, data_write_time);
     130             : 
     131       40350 :   return paths;
     132       20175 : }

Generated by: LCOV version 1.14