LCOV - code coverage report
Current view: top level - src/restart - RestartableDataWriter.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 60 66 90.9 %
Date: 2026-05-29 20:35:17 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       11326 : RestartableDataWriter::RestartableDataWriter(MooseApp & app, RestartableDataMap & data)
      19       11326 :   : RestartableDataIO(app, data)
      20             : {
      21       11326 : }
      22             : 
      23       45637 : RestartableDataWriter::RestartableDataWriter(MooseApp & app, std::vector<RestartableDataMap> & data)
      24       45637 :   : RestartableDataIO(app, data)
      25             : {
      26       45637 : }
      27             : 
      28             : void
      29       56963 : RestartableDataWriter::write(std::ostream & header_stream, std::ostream & data_stream)
      30             : {
      31             :   // Set everything as not stored
      32      117790 :   for (const auto tid : make_range(dataSize()))
      33     2176493 :     for (auto & value : currentData(tid))
      34     2115666 :       value.setNotStored({});
      35             : 
      36             :   // Header
      37       56963 :   char id[] = {'R', 'D'};
      38       56963 :   header_stream.write(id, 2);
      39             : 
      40             :   // File version
      41       56963 :   auto file_version = CURRENT_BACKUP_FILE_VERSION;
      42       56963 :   dataStore(header_stream, file_version, nullptr);
      43             : 
      44             :   // Type hash for basic hash
      45       56963 :   std::size_t compare_hash_code = typeid(COMPARE_HASH_CODE_TYPE).hash_code();
      46       56963 :   dataStore(header_stream, compare_hash_code, nullptr);
      47             : 
      48             :   // Number of procs
      49       56963 :   auto n_procs = n_processors();
      50       56963 :   dataStore(header_stream, n_procs, nullptr);
      51             : 
      52             :   // Number of data
      53       56963 :   auto num_data = dataSize();
      54       56963 :   dataStore(header_stream, num_data, nullptr);
      55             : 
      56             :   // Size of data for each thread
      57      117790 :   for (const auto tid : make_range(dataSize()))
      58             :   {
      59       60827 :     std::size_t n_data = currentData(tid).size();
      60       60827 :     dataStore(header_stream, n_data, nullptr);
      61             :   }
      62             : 
      63             :   // Write out the RestartableData header, and store the actual data separately
      64      117786 :   for (const auto tid : make_range(dataSize()))
      65     2176453 :     for (auto & data : currentData(tid))
      66             :     {
      67             :       // Store the data
      68     2115630 :       const std::size_t data_start_position = static_cast<std::size_t>(data_stream.tellp());
      69     2115630 :       data.store(data_stream);
      70     2115627 :       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     2115627 :       std::string name = data.name();
      75     2115627 :       std::string type = data.typeId().name();
      76     2115627 :       std::size_t type_hash_code = data.typeId().hash_code();
      77     2115627 :       bool has_context = data.hasContext();
      78     2115627 :       dataStore(header_stream, name, nullptr);
      79     2115627 :       dataStore(header_stream, data_size, nullptr);
      80     2115627 :       dataStore(header_stream, type_hash_code, nullptr);
      81     2115627 :       dataStore(header_stream, type, nullptr);
      82     2115627 :       dataStore(header_stream, has_context, nullptr);
      83     2115627 :     }
      84       56960 : }
      85             : 
      86             : std::vector<std::filesystem::path>
      87       24182 : RestartableDataWriter::write(const std::filesystem::path & folder_base)
      88             : {
      89       24182 :   const auto header_file = restartableHeaderFile(folder_base);
      90       24182 :   const auto data_file = restartableDataFile(folder_base);
      91             : 
      92             :   // Make the folder if it doesn't exist
      93       24182 :   const auto dir = header_file.parent_path();
      94             :   mooseAssert(dir == data_file.parent_path(), "Inconsistent directories");
      95       24182 :   if (!std::filesystem::exists(dir))
      96             :   {
      97       20888 :     std::error_code err;
      98       20888 :     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       24182 :   std::vector<std::filesystem::path> paths;
     108             : 
     109             :   // Helper for opening a stream for use
     110       48364 :   auto open = [&paths](const std::filesystem::path & filename)
     111             :   {
     112       48364 :     std::ofstream stream;
     113       48364 :     stream.open(filename.c_str(), std::ios::out | std::ios::binary);
     114       48364 :     if (!stream.is_open())
     115           0 :       mooseError(
     116           0 :           "Unable to open restart file ", std::filesystem::absolute(filename), " for writing");
     117       48364 :     paths.push_back(filename);
     118       48364 :     return stream;
     119           0 :   };
     120             : 
     121             :   // Open and write
     122       24182 :   auto header_stream = open(header_file);
     123       24182 :   auto data_stream = open(data_file);
     124       24182 :   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       24179 :   const auto data_write_time = std::filesystem::last_write_time(header_file);
     129       24179 :   std::filesystem::last_write_time(dir, data_write_time);
     130             : 
     131       48358 :   return paths;
     132       24179 : }

Generated by: LCOV version 1.14