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/IO/AbstractIOHandler.hpp"
24 #include "openPMD/IO/Access.hpp"
25 #include "openPMD/IO/Format.hpp"
26 #include "openPMD/Iteration.hpp"
27 #include "openPMD/IterationEncoding.hpp"
28 #include "openPMD/Streaming.hpp"
29 #include "openPMD/WriteIterations.hpp"
30 #include "openPMD/auxiliary/Option.hpp"
31 #include "openPMD/auxiliary/Variant.hpp"
32 #include "openPMD/backend/Attributable.hpp"
33 #include "openPMD/backend/Container.hpp"
34 #include "openPMD/config.hpp"
35 #include "openPMD/version.hpp"
36 
37 #if openPMD_HAVE_MPI
38 #include <mpi.h>
39 #endif
40 
41 #include <map>
42 #include <string>
43 
44 // expose private and protected members for invasive testing
45 #ifndef OPENPMD_private
46 #define OPENPMD_private private
47 #endif
48 
49 namespace openPMD
50 {
51 class ReadIterations;
52 class Series;
53 class SeriesInterface;
54 
55 namespace internal
56 {
64  {
65  public:
66  explicit SeriesData() = default;
67 
68  SeriesData(SeriesData const &) = delete;
69  SeriesData(SeriesData &&) = delete;
70 
71  SeriesData &operator=(SeriesData const &) = delete;
72  SeriesData &operator=(SeriesData &&) = delete;
73 
74  virtual ~SeriesData() = default;
75 
76  Container<Iteration, uint64_t> iterations{};
77 
78  auxiliary::Option<WriteIterations> m_writeIterations;
79  auxiliary::Option<std::string> m_overrideFilebasedFilename;
80  std::string m_name;
81  std::string m_filenamePrefix;
82  std::string m_filenamePostfix;
83  int m_filenamePadding;
84  IterationEncoding m_iterationEncoding{};
85  Format m_format;
93  StepStatus m_stepStatus = StepStatus::NoStep;
94  bool m_parseLazily = false;
95  bool m_lastFlushSuccessful = true;
96  }; // SeriesData
97 
98  class SeriesInternal;
99 } // namespace internal
100 
111 {
112  friend class AttributableInterface;
113  friend class Iteration;
114  friend class Writable;
115  friend class SeriesIterator;
116  friend class internal::SeriesInternal;
117  friend class Series;
118  friend class WriteIterations;
119 
120 protected:
121  // Should not be called publicly, only by implementing classes
123 
124 public:
130  std::string openPMD() const;
139  SeriesInterface &setOpenPMD(std::string const &openPMD);
140 
146  uint32_t openPMDextension() const;
155  SeriesInterface &setOpenPMDextension(uint32_t openPMDextension);
156 
161  std::string basePath() const;
169  SeriesInterface &setBasePath(std::string const &basePath);
170 
176  std::string meshesPath() const;
186  SeriesInterface &setMeshesPath(std::string const &meshesPath);
187 
193  std::string particlesPath() const;
203  SeriesInterface &setParticlesPath(std::string const &particlesPath);
204 
210  std::string author() const;
217  SeriesInterface &setAuthor(std::string const &author);
218 
224  std::string software() const;
233  SeriesInterface &setSoftware(
234  std::string const &newName,
235  std::string const &newVersion = std::string("unspecified"));
236 
242  std::string softwareVersion() const;
252  [[deprecated(
253  "Set the version with the second argument of "
254  "setSoftware()")]] SeriesInterface &
255  setSoftwareVersion(std::string const &softwareVersion);
256 
261  std::string date() const;
267  SeriesInterface &setDate(std::string const &date);
268 
274  std::string softwareDependencies() const;
283  setSoftwareDependencies(std::string const &newSoftwareDependencies);
284 
290  std::string machine() const;
297  SeriesInterface &setMachine(std::string const &newMachine);
298 
302  IterationEncoding iterationEncoding() const;
320  SeriesInterface &setIterationEncoding(IterationEncoding iterationEncoding);
321 
327  std::string iterationFormat() const;
339  SeriesInterface &setIterationFormat(std::string const &iterationFormat);
340 
344  std::string name() const;
345 
352  SeriesInterface &setName(std::string const &name);
353 
360  std::string backend() const;
361 
364  void flush();
365 
366  OPENPMD_private:
367  static constexpr char const * const BASEPATH = "/data/%T/";
368 
369  struct ParsedInput;
370  using iterations_t = decltype(internal::SeriesData::iterations);
371  using iterations_iterator = iterations_t::iterator;
372 
373  internal::SeriesData *m_series = nullptr;
374 
375  inline internal::SeriesData &get()
376  {
377  if (m_series)
378  {
379  return *m_series;
380  }
381  else
382  {
383  throw std::runtime_error(
384  "[Series] Cannot use default-constructed Series.");
385  }
386  }
387 
388  inline internal::SeriesData const &get() const
389  {
390  if (m_series)
391  {
392  return *m_series;
393  }
394  else
395  {
396  throw std::runtime_error(
397  "[Series] Cannot use default-constructed Series.");
398  }
399  }
400 
401  std::unique_ptr<ParsedInput> parseInput(std::string);
402  void init(std::shared_ptr<AbstractIOHandler>, std::unique_ptr<ParsedInput>);
403  void initDefaults(IterationEncoding);
415  std::future<void> flush_impl(
416  iterations_iterator begin,
417  iterations_iterator end,
418  internal::FlushParams flushParams,
419  bool flushIOHandler = true);
420  void flushFileBased(
421  iterations_iterator begin,
422  iterations_iterator end,
423  internal::FlushParams flushParams);
424  /*
425  * Group-based and variable-based iteration layouts share a lot of logic
426  * (realistically, the variable-based iteration layout only throws out
427  * one layer in the hierarchy).
428  * As a convention, methods that deal with both layouts are called
429  * .*GorVBased, short for .*GroupOrVariableBased
430  */
431  void flushGorVBased(
432  iterations_iterator begin,
433  iterations_iterator end,
434  internal::FlushParams flushParams);
435  void flushMeshesPath();
436  void flushParticlesPath();
437  void readFileBased();
438  void readOneIterationFileBased(std::string const &filePath);
444  void readGorVBased(bool init = true);
445  void readBase();
446  std::string iterationFilename(uint64_t i);
447 
448  enum class IterationOpened : bool
449  {
450  HasBeenOpened,
451  RemainsClosed
452  };
453  /*
454  * For use by flushFileBased, flushGorVBased
455  * Open an iteration, but only if necessary.
456  * Only open if the iteration is dirty and if it is not in deferred
457  * parse state.
458  */
459  IterationOpened openIterationIfDirty(uint64_t index, Iteration iteration);
460  /*
461  * Open an iteration. Ensures that the iteration's m_closed status
462  * is set properly and that any files pertaining to the iteration
463  * is opened.
464  * Does not create files when called in CREATE mode.
465  */
466  void openIteration(uint64_t index, Iteration iteration);
467 
472  iterations_iterator indexOf(Iteration const &);
473 
489  AdvanceStatus advance(
490  AdvanceMode mode,
492  iterations_iterator it,
493  Iteration &iteration);
494 }; // SeriesInterface
495 
496 namespace internal
497 {
499  : public SeriesData
500  , public SeriesInterface
501  {
502  friend struct SeriesShared;
503  friend class openPMD::Iteration;
504  friend class openPMD::Series;
505  friend class openPMD::Writable;
506 
507  public:
508 #if openPMD_HAVE_MPI
510  std::string const &filepath,
511  Access at,
512  MPI_Comm comm,
513  std::string const &options = "{}");
514 #endif
515 
517  std::string const &filepath,
518  Access at,
519  std::string const &options = "{}");
520  // @todo make AttributableInterface<>::linkHierarchy non-virtual
521  virtual ~SeriesInternal();
522  };
523 } // namespace internal
524 
537 class Series : public SeriesInterface
538 {
539 private:
540  std::shared_ptr<internal::SeriesInternal> m_series;
541 
542  // constructor from private parts
543  Series(std::shared_ptr<internal::SeriesInternal>);
544 
545 public:
546  explicit Series();
547 
548 #if openPMD_HAVE_MPI
549  Series(
550  std::string const &filepath,
551  Access at,
552  MPI_Comm comm,
553  std::string const &options = "{}");
554 #endif
555 
565  Series(
566  std::string const &filepath,
567  Access at,
568  std::string const &options = "{}");
569 
570  virtual ~Series() = default;
571 
573 
580  operator bool() const;
581 
592  ReadIterations readIterations();
593 
606  WriteIterations writeIterations();
607 };
608 } // namespace openPMD
609 
610 // Make sure that this one is always included if Series.hpp is included,
611 // otherwise SeriesInterface::readIterations() cannot be used
612 #include "openPMD/ReadIterations.hpp"
Access
File access mode to use during IO.
Definition: Access.hpp:27
Definition: Series.hpp:498
Format
File format to use during IO.
Definition: Format.hpp:29
Logical compilation of data from one snapshot (e.g.
Definition: Iteration.hpp:40
StepStatus m_stepStatus
Whether a step is currently active for this iteration.
Definition: Series.hpp:93
StepStatus
Used in step-based mode (i.e.
Definition: Streaming.hpp:44
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:46
Reading side of the streaming API.
Definition: ReadIterations.hpp:90
Root level of the openPMD hierarchy.
Definition: Series.hpp:537
Simple Option type based on variantSrc::variant.
Definition: Option.hpp:45
Public definitions of openPMD-api.
Definition: Date.cpp:28
Layer to mirror structure of logical data and persistent data in file.
Definition: Writable.hpp:63
Layer to manage storage of attributes associated with file objects.
Definition: Attributable.hpp:128
Data members for Series.
Definition: Series.hpp:63
Definition: Attributable.hpp:68
Definition: ReadIterations.hpp:48
Parameters recursively passed through the openPMD hierarchy when flushing.
Definition: AbstractIOHandler.hpp:103
Implementation for the root level of the openPMD hierarchy.
Definition: Series.hpp:110
IterationEncoding
Encoding scheme of an Iterations Series&#39;.
Definition: IterationEncoding.hpp:32
Definition: Series.cpp:92