openPMD-api
Series.hpp
1 /* Copyright 2017-2021 Fabian Koller, Axel Huebl
2  *
3  * This file is part of openPMD-api.
4  *
5  * openPMD-api is free software: you can redistribute it and/or modify
6  * it under the terms of of either the GNU General Public License or
7  * the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * openPMD-api is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License and the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * and the GNU Lesser General Public License along with openPMD-api.
19  * If not, see <http://www.gnu.org/licenses/>.
20  */
21 #pragma once
22 
23 #include "openPMD/config.hpp"
24 #include "openPMD/backend/Attributable.hpp"
25 #include "openPMD/backend/Container.hpp"
26 #include "openPMD/IO/AbstractIOHandler.hpp"
27 #include "openPMD/IO/Access.hpp"
28 #include "openPMD/IO/Format.hpp"
29 #include "openPMD/Iteration.hpp"
30 #include "openPMD/IterationEncoding.hpp"
31 #include "openPMD/Streaming.hpp"
32 #include "openPMD/WriteIterations.hpp"
33 #include "openPMD/auxiliary/Option.hpp"
34 #include "openPMD/auxiliary/Variant.hpp"
35 #include "openPMD/backend/Attributable.hpp"
36 #include "openPMD/backend/Container.hpp"
37 #include "openPMD/config.hpp"
38 #include "openPMD/version.hpp"
39 
40 #if openPMD_HAVE_MPI
41 # include <mpi.h>
42 #endif
43 
44 #include <map>
45 #include <string>
46 
47 // expose private and protected members for invasive testing
48 #ifndef OPENPMD_private
49 # define OPENPMD_private private
50 #endif
51 
52 
53 namespace openPMD
54 {
55 class ReadIterations;
56 class Series;
57 class SeriesInterface;
58 
59 namespace internal
60 {
68 {
69 public:
70  explicit SeriesData() = default;
71 
72  SeriesData( SeriesData const & ) = delete;
73  SeriesData( SeriesData && ) = delete;
74 
75  SeriesData & operator=( SeriesData const & ) = delete;
76  SeriesData & operator=( SeriesData && ) = delete;
77 
78  virtual ~SeriesData() = default;
79 
81 
82  auxiliary::Option< WriteIterations > m_writeIterations;
83  auxiliary::Option< std::string > m_overrideFilebasedFilename;
84  std::string m_name;
85  std::string m_filenamePrefix;
86  std::string m_filenamePostfix;
87  int m_filenamePadding;
88  IterationEncoding m_iterationEncoding{};
89  Format m_format;
97  StepStatus m_stepStatus = StepStatus::NoStep;
98  bool m_parseLazily = false;
99  bool m_lastFlushSuccessful = true;
100 }; // SeriesData
101 
102 class SeriesInternal;
103 } // namespace internal
104 
113 {
114  friend class AttributableInterface;
115  friend class Iteration;
116  friend class Writable;
117  friend class SeriesIterator;
118  friend class internal::SeriesInternal;
119  friend class Series;
120  friend class WriteIterations;
121 
122 protected:
123  // Should not be called publicly, only by implementing classes
125 
126 public:
130  std::string openPMD() const;
136  SeriesInterface& setOpenPMD(std::string const& openPMD);
137 
141  uint32_t openPMDextension() const;
147  SeriesInterface& setOpenPMDextension(uint32_t openPMDextension);
148 
152  std::string basePath() const;
158  SeriesInterface& setBasePath(std::string const& basePath);
159 
164  std::string meshesPath() const;
170  SeriesInterface& setMeshesPath(std::string const& meshesPath);
171 
176  std::string particlesPath() const;
182  SeriesInterface& setParticlesPath(std::string const& particlesPath);
183 
188  std::string author() const;
194  SeriesInterface& setAuthor(std::string const& author);
195 
200  std::string software() const;
207  SeriesInterface& setSoftware(std::string const& newName, std::string const& newVersion = std::string("unspecified"));
208 
213  std::string softwareVersion() const;
221  [[deprecated("Set the version with the second argument of setSoftware()")]]
222  SeriesInterface& setSoftwareVersion(std::string const& softwareVersion);
223 
228  std::string date() const;
234  SeriesInterface& setDate(std::string const& date);
235 
240  std::string softwareDependencies() const;
246  SeriesInterface& setSoftwareDependencies(std::string const& newSoftwareDependencies);
247 
252  std::string machine() const;
258  SeriesInterface& setMachine(std::string const& newMachine);
259 
263  IterationEncoding iterationEncoding() const;
272  SeriesInterface& setIterationEncoding(IterationEncoding iterationEncoding);
273 
277  std::string iterationFormat() const;
288  SeriesInterface& setIterationFormat(std::string const& iterationFormat);
289 
293  std::string name() const;
294 
300  SeriesInterface& setName(std::string const& name);
301 
308  std::string backend() const;
309 
312  void flush();
313 
314 OPENPMD_private:
315  static constexpr char const * const BASEPATH = "/data/%T/";
316 
317  struct ParsedInput;
318  using iterations_t = decltype(internal::SeriesData::iterations);
319  using iterations_iterator = iterations_t::iterator;
320 
321  internal::SeriesData * m_series = nullptr;
322 
323  inline internal::SeriesData & get()
324  {
325  if( m_series )
326  {
327  return *m_series;
328  }
329  else
330  {
331  throw std::runtime_error(
332  "[Series] Cannot use default-constructed Series." );
333  }
334  }
335 
336  inline internal::SeriesData const & get() const
337  {
338  if( m_series )
339  {
340  return *m_series;
341  }
342  else
343  {
344  throw std::runtime_error(
345  "[Series] Cannot use default-constructed Series." );
346  } }
347 
348  std::unique_ptr< ParsedInput > parseInput(std::string);
349  void init(std::shared_ptr< AbstractIOHandler >, std::unique_ptr< ParsedInput >);
350  void initDefaults( IterationEncoding );
362  std::future< void > flush_impl(
363  iterations_iterator begin,
364  iterations_iterator end,
365  FlushLevel level,
366  bool flushIOHandler = true );
367  void flushFileBased( iterations_iterator begin, iterations_iterator end );
368  /*
369  * Group-based and variable-based iteration layouts share a lot of logic
370  * (realistically, the variable-based iteration layout only throws out
371  * one layer in the hierarchy).
372  * As a convention, methods that deal with both layouts are called
373  * .*GorVBased, short for .*GroupOrVariableBased
374  */
375  void flushGorVBased( iterations_iterator begin, iterations_iterator end );
376  void flushMeshesPath();
377  void flushParticlesPath();
378  void readFileBased( );
379  void readOneIterationFileBased( std::string const & filePath );
385  void readGorVBased( bool init = true );
386  void readBase();
387  std::string iterationFilename( uint64_t i );
388 
389  enum class IterationOpened : bool
390  {
391  HasBeenOpened,
392  RemainsClosed
393  };
394  /*
395  * For use by flushFileBased, flushGorVBased
396  * Open an iteration, but only if necessary.
397  * Only open if the iteration is dirty and if it is not in deferred
398  * parse state.
399  */
400  IterationOpened openIterationIfDirty( uint64_t index, Iteration iteration );
401  /*
402  * Open an iteration. Ensures that the iteration's m_closed status
403  * is set properly and that any files pertaining to the iteration
404  * is opened.
405  * Does not create files when called in CREATE mode.
406  */
407  void openIteration( uint64_t index, Iteration iteration );
408 
413  iterations_iterator
414  indexOf( Iteration const & );
415 
432  advance(
433  AdvanceMode mode,
435  iterations_iterator it,
436  Iteration & iteration );
437 }; // SeriesInterface
438 
439 namespace internal
440 {
442 {
443  friend struct SeriesShared;
444  friend class openPMD::Iteration;
445  friend class openPMD::Series;
446  friend class openPMD::Writable;
447 
448 public:
449 #if openPMD_HAVE_MPI
451  std::string const & filepath,
452  Access at,
453  MPI_Comm comm,
454  std::string const & options = "{}" );
455 #endif
456 
458  std::string const & filepath,
459  Access at,
460  std::string const & options = "{}" );
461  // @todo make AttributableInterface<>::linkHierarchy non-virtual
462  virtual ~SeriesInternal();
463 };
464 } // namespace internal
465 
476 class Series : public SeriesInterface
477 {
478 private:
479  std::shared_ptr< internal::SeriesInternal > m_series;
480 
481 public:
482  explicit Series();
483 
484 #if openPMD_HAVE_MPI
485  Series(
486  std::string const & filepath,
487  Access at,
488  MPI_Comm comm,
489  std::string const & options = "{}" );
490 #endif
491 
501  Series(
502  std::string const & filepath,
503  Access at,
504  std::string const & options = "{}" );
505 
506  virtual ~Series() = default;
507 
509 
516  operator bool() const;
517 
528  ReadIterations readIterations();
529 
542  WriteIterations writeIterations();
543 };
544 } // namespace openPMD
545 
546 // Make sure that this one is always included if Series.hpp is included,
547 // otherwise SeriesInterface::readIterations() cannot be used
548 #include "openPMD/ReadIterations.hpp"
Access
File access mode to use during IO.
Definition: Access.hpp:28
Definition: Series.hpp:441
Format
File format to use during IO.
Definition: Format.hpp:30
Logical compilation of data from one snapshot (e.g.
Definition: Iteration.hpp:39
StepStatus m_stepStatus
Whether a step is currently active for this iteration.
Definition: Series.hpp:97
StepStatus
Used in step-based mode (i.e.
Definition: Streaming.hpp:44
FlushLevel
Determine what items should be flushed upon Series::flush()
Definition: AbstractIOHandler.hpp:63
AdvanceStatus
In step-based mode (i.e.
Definition: Streaming.hpp:20
AdvanceMode
In step-based mode (i.e.
Definition: Streaming.hpp:33
Writing side of the streaming API.
Definition: WriteIterations.hpp:47
Reading side of the streaming API.
Definition: ReadIterations.hpp:92
Root level of the openPMD hierarchy.
Definition: Series.hpp:476
Simple Option type based on variantSrc::variant.
Definition: Option.hpp:47
Public definitions of openPMD-api.
Definition: Date.cpp:29
Layer to mirror structure of logical data and persistent data in file.
Definition: Writable.hpp:64
Layer to manage storage of attributes associated with file objects.
Definition: Attributable.hpp:115
Data members for Series.
Definition: Series.hpp:67
Definition: Attributable.hpp:68
Definition: ReadIterations.hpp:50
Implementation for the root level of the openPMD hierarchy.
Definition: Series.hpp:112
IterationEncoding
Encoding scheme of an Iterations Series&#39;.
Definition: IterationEncoding.hpp:32
Definition: Series.cpp:82