Git Product home page Git Product logo

openpmd / openpmd-api Goto Github PK

View Code? Open in Web Editor NEW
133.0 11.0 51.0 21.96 MB

:floppy_disk: C++ & Python API for Scientific I/O

Home Page: https://openpmd-api.readthedocs.io

License: GNU Lesser General Public License v3.0

CMake 3.28% C++ 89.91% Shell 0.18% PowerShell 0.14% Python 5.94% Dockerfile 0.48% Singularity 0.07%
openpmd openscience hdf5 adios mpi hpc research file-handling python3 opendata

openpmd-api's Introduction

C++ & Python API for Scientific I/O with openPMD

Supported openPMD Standard Doxygen Gitter chat Supported Platforms License DOI CodeFactor Coverage Status Documentation Status Linux/OSX Build Status dev Windows Build Status dev PyPI Wheel Release Nightly Packages Status Coverity Scan Build Status

openPMD is an open meta-data schema that provides meaning and self-description for data sets in science and engineering. See the openPMD standard for details of this schema.

This library provides a reference API for openPMD data handling. Since openPMD is a schema (or markup) on top of portable, hierarchical file formats, this library implements various backends such as HDF5, ADIOS2 and JSON. Writing & reading through those backends and their associated files are supported for serial and MPI-parallel workflows.

Usage

C++

C++17 C++17 API: Beta

#include <openPMD/openPMD.hpp>
#include <iostream>

// ...

auto s = openPMD::Series("samples/git-sample/data%T.h5", openPMD::Access::READ_ONLY);

for( auto const & [step, it] : s.iterations ) {
    std::cout << "Iteration: " << step << "\n";

    for( auto const & [name, mesh] : it.meshes ) {
        std::cout << "  Mesh '" << name << "' attributes:\n";
        for( auto const& val : mesh.attributes() )
            std::cout << "    " << val << '\n';
    }

    for( auto const & [name, species] : it.particles ) {
        std::cout << "  Particle species '" << name << "' attributes:\n";
        for( auto const& val : species.attributes() )
            std::cout << "    " << val << '\n';
    }
}

Python

Python3 Python3 API: Beta

import openpmd_api as io

# ...

series = io.Series("samples/git-sample/data%T.h5", io.Access.read_only)

for k_i, i in series.iterations.items():
    print("Iteration: {0}".format(k_i))

    for k_m, m in i.meshes.items():
        print("  Mesh '{0}' attributes:".format(k_m))
        for a in m.attributes:
            print("    {0}".format(a))

    for k_p, p in i.particles.items():
        print("  Particle species '{0}' attributes:".format(k_p))
        for a in p.attributes:
            print("    {0}".format(a))

More!

Curious? Our manual shows full read & write examples, both serial and MPI-parallel!

Dependencies

Required:

  • CMake 3.15.0+
  • C++17 capable compiler, e.g., g++ 7+, clang 7+, MSVC 19.15+, icpc 19+, icpx

Shipped internally in share/openPMD/thirdParty/:

I/O backends:

while those can be built either with or without:

  • MPI 2.1+, e.g. OpenMPI 1.6.5+ or MPICH2

Optional language bindings:

  • Python:
    • Python 3.8 - 3.12
    • pybind11 2.11.1+
    • numpy 1.15+
    • mpi4py 2.1+ (optional, for MPI)
    • pandas 1.0+ (optional, for dataframes)
    • dask 2021+ (optional, for dask dataframes)
  • CUDA C++ (optional, currently used only in tests)

Installation

Spack Package Conda Package Brew Package PyPI Package From Source

Our community loves to help each other. Please report installation problems in case you should get stuck.

Choose one of the install methods below to get started:

Spack Version Spack Platforms Spack Use Case

# optional:               +python -adios2 -hdf5 -mpi
spack install openpmd-api
spack load openpmd-api

Conda Version Conda Platforms Conda Use Case Conda Downloads

# optional:                      OpenMPI support  =*=mpi_openmpi*
# optional:                        MPICH support  =*=mpi_mpich*
conda create -n openpmd -c conda-forge openpmd-api
conda activate openpmd

Brew Version Brew Platforms Brew Use Case

brew tap openpmd/openpmd
brew install openpmd-api

PyPI Version PyPI Platforms PyPI Use Case PyPI Format PyPI Downloads

On very old macOS versions (<10.9) or on exotic processor architectures, this install method compiles from source against the found installations of HDF5, ADIOS2, and/or MPI (in system paths, from other package managers, or loaded via a module system, ...).

# we need pip 19 or newer
# optional:                   --user
python3 -m pip install -U pip

# optional:                        --user
python3 -m pip install openpmd-api

If MPI-support shall be enabled, we always have to recompile:

# optional:                                    --user
python3 -m pip install -U pip packaging setuptools wheel
python3 -m pip install -U cmake

# optional:                                                                   --user
openPMD_USE_MPI=ON python3 -m pip install openpmd-api --no-binary openpmd-api

For some exotic architectures and compilers, you might need to disable a compiler feature called link-time/interprocedural optimization if you encounter linking problems:

export CMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF
# optional:                                                --user
python3 -m pip install openpmd-api --no-binary openpmd-api

Additional CMake options can be passed via individual environment variables, which need to be prefixed with openPMD_CMAKE_.

From Source

Source Use Case

openPMD-api can also be built and installed from source using CMake:

git clone https://github.com/openPMD/openPMD-api.git

mkdir openPMD-api-build
cd openPMD-api-build

# optional: for full tests, with unzip
../openPMD-api/share/openPMD/download_samples.sh

# for own install prefix append:
#   -DCMAKE_INSTALL_PREFIX=$HOME/somepath
# for options append:
#   -DopenPMD_USE_...=...
# e.g. for python support add:
#   -DopenPMD_USE_PYTHON=ON -DPython_EXECUTABLE=$(which python3)
cmake ../openPMD-api

cmake --build .

# optional
ctest

# sudo might be required for system paths
cmake --build . --target install

The following options can be added to the cmake call to control features. CMake controls options with prefixed -D, e.g. -DopenPMD_USE_MPI=OFF:

CMake Option Values Description
openPMD_USE_MPI AUTO/ON/OFF Parallel, Multi-Node I/O for clusters
openPMD_USE_HDF5 AUTO/ON/OFF HDF5 backend (.h5 files)
openPMD_USE_ADIOS2 AUTO/ON/OFF ADIOS2 backend (.bp files in BP3, BP4 or higher)
openPMD_USE_PYTHON AUTO/ON/OFF Enable Python bindings
openPMD_USE_INVASIVE_TESTS ON/OFF Enable unit tests that modify source code 1
openPMD_USE_VERIFY ON/OFF Enable internal VERIFY (assert) macro independent of build type 2
openPMD_INSTALL ON/OFF Add installation targets
openPMD_INSTALL_RPATH ON/OFF Add RPATHs to installed binaries
Python_EXECUTABLE (newest found) Path to Python executable

1 e.g. changes C++ visibility keywords, breaks MSVC 2 this includes most pre-/post-condition checks, disabling without specific cause is highly discouraged

Additionally, the following libraries are shipped internally. The following options allow to switch to external installs:

CMake Option Values Library Version
openPMD_USE_INTERNAL_CATCH ON/OFF Catch2 2.13.10+
openPMD_USE_INTERNAL_PYBIND11 ON/OFF pybind11 2.11.1+
openPMD_USE_INTERNAL_JSON ON/OFF NLohmann-JSON 3.9.1+
openPMD_USE_INTERNAL_TOML11 ON/OFF toml11 3.7.1+

By default, this will build as a shared library (libopenPMD.[so|dylib|dll]) and installs also its headers. In order to build a static library, append -DBUILD_SHARED_LIBS=OFF to the cmake command. You can only build a static or a shared library at a time.

By default, the Release version is built. In order to build with debug symbols, pass -DCMAKE_BUILD_TYPE=Debug to your cmake command.

By default, tests, examples and command line tools are built. In order to skip building those, pass OFF to these cmake options:

CMake Option Values Description
openPMD_BUILD_TESTING ON/OFF Build tests
openPMD_BUILD_EXAMPLES ON/OFF Build examples
openPMD_BUILD_CLI_TOOLS ON/OFF Build command-line tools
openPMD_USE_CUDA_EXAMPLES ON/OFF Use CUDA in examples

Linking to your project

The install will contain header files and libraries in the path set with -DCMAKE_INSTALL_PREFIX.

CMake

If your project is using CMake for its build, one can conveniently use our provided openPMDConfig.cmake package, which is installed alongside the library.

First set the following environment hint if openPMD-api was not installed in a system path:

# optional: only needed if installed outside of system paths
export CMAKE_PREFIX_PATH=$HOME/somepath:$CMAKE_PREFIX_PATH

Use the following lines in your project's CMakeLists.txt:

# supports:                       COMPONENTS MPI NOMPI HDF5 ADIOS2
find_package(openPMD 0.15.0 CONFIG)

if(openPMD_FOUND)
    target_link_libraries(YourTarget PRIVATE openPMD::openPMD)
endif()

Alternatively, add the openPMD-api repository source directly to your project and use it via:

add_subdirectory("path/to/source/of/openPMD-api")

target_link_libraries(YourTarget PRIVATE openPMD::openPMD)

For development workflows, you can even automatically download and build openPMD-api from within a depending CMake project. Just replace the add_subdirectory call with:

include(FetchContent)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
set(openPMD_BUILD_CLI_TOOLS OFF)
set(openPMD_BUILD_EXAMPLES OFF)
set(openPMD_BUILD_TESTING OFF)
set(openPMD_BUILD_SHARED_LIBS OFF)  # precedence over BUILD_SHARED_LIBS if needed
set(openPMD_INSTALL OFF)            # or instead use:
# set(openPMD_INSTALL ${BUILD_SHARED_LIBS})  # only install if used as a shared library
set(openPMD_USE_PYTHON OFF)
FetchContent_Declare(openPMD
  GIT_REPOSITORY "https://github.com/openPMD/openPMD-api.git"
  GIT_TAG        "0.15.0")
FetchContent_MakeAvailable(openPMD)

Manually

If your (Linux/OSX) project is build by calling the compiler directly or uses a manually written Makefile, consider using our openPMD.pc helper file for pkg-config, which are installed alongside the library.

First set the following environment hint if openPMD-api was not installed in a system path:

# optional: only needed if installed outside of system paths
export PKG_CONFIG_PATH=$HOME/somepath/lib/pkgconfig:$PKG_CONFIG_PATH

Additional linker and compiler flags for your project are available via:

# switch to check if openPMD-api was build as static library
# (via BUILD_SHARED_LIBS=OFF) or as shared library (default)
if [ "$(pkg-config --variable=static openPMD)" == "true" ]
then
    pkg-config --libs --static openPMD
    # -L/usr/local/lib -L/usr/lib/x86_64-linux-gnu/openmpi/lib -lopenPMD -pthread /usr/lib/libmpi.so -pthread /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi_cxx.so /usr/lib/libmpi.so /usr/lib/x86_64-linux-gnu/hdf5/openmpi/libhdf5.so /usr/lib/x86_64-linux-gnu/libsz.so /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/x86_64-linux-gnu/libdl.so /usr/lib/x86_64-linux-gnu/libm.so -pthread /usr/lib/libmpi.so -pthread /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi_cxx.so /usr/lib/libmpi.so
else
    pkg-config --libs openPMD
    # -L${HOME}/somepath/lib -lopenPMD
fi

pkg-config --cflags openPMD
# -I${HOME}/somepath/include

Author Contributions

openPMD-api is developed by many people. It was initially started by the Computational Radiation Physics Group at HZDR as successor to libSplash, generalizing the successful HDF5 & ADIOS1 implementations in PIConGPU. The following people and institutions contributed to openPMD-api:

Maintained by the following research groups:

Further thanks go to improvements and contributions from:

Grants

The openPMD-api authors acknowledge support via the following programs. Supported by the CAMPA collaboration, a project of the U.S. Department of Energy, Office of Science, Office of Advanced Scientific Computing Research and Office of High Energy Physics, Scientific Discovery through Advanced Computing (SciDAC) program. Previously supported by the Consortium for Advanced Modeling of Particles Accelerators (CAMPA), funded by the U.S. DOE Office of Science under Contract No. DE-AC02-05CH11231. Supported by the Exascale Computing Project (17-SC-20-SC), a collaborative effort of two U.S. Department of Energy organizations (Office of Science and the National Nuclear Security Administration). This project has received funding from the European Unions Horizon 2020 research and innovation programme under grant agreement No 654220. This work was partially funded by the Center of Advanced Systems Understanding (CASUS), which is financed by Germany's Federal Ministry of Education and Research (BMBF) and by the Saxon Ministry for Science, Culture and Tourism (SMWK) with tax funds on the basis of the budget approved by the Saxon State Parliament. Supported by the HElmholtz Laser Plasma Metadata Initiative (HELPMI) project (ZT-I-PF-3-066), funded by the "Initiative and Networking Fund" of the Helmholtz Association in the framework of the "Helmholtz Metadata Collaboration" project call 2022.

Transitive Contributions

openPMD-api stands on the shoulders of giants and we are grateful for the following projects included as direct dependencies:

openpmd-api's People

Contributors

amundson avatar ax3l avatar bernhardmgruber avatar c0nsultant avatar cfgrote avatar dependabot[bot] avatar dernils-git avatar dpgrote avatar eschnett avatar franzpoeschel avatar gridley avatar gtrichardson avatar guj avatar iliancs avatar jeanbez avatar ldamorim avatar lucafedeli88 avatar mpark avatar nlohmann avatar philsquared avatar pordyna avatar pre-commit-ci[bot] avatar prometheuspi avatar psychocoderhpc avatar sbastrakov avatar skalarproduktraum avatar stanczakdominik avatar titoiride avatar toruniina avatar wjakob avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openpmd-api's Issues

Writing and Reading Non-openPMD Infos

It would be necessary to allow storing non-openPMD information as well.

In the simple case, this means adding additional, user-defined attributes to records, record-components and paths.

In the more complex case, application specific states such as RNG states, unqiue-number-generator states, etc. need to be stored as records outside of the openPMD-interpreted paths.

load/storeChunk: slice view

The A.storeChunk(data, offset, extent) and A.loadChunk(data, chunk_offset, chunk_extent) methods should for syntactic sugar provide a slice-view access of the form:

// write (copy)
A[view] = data;

// returns: std::unique_ptr< A.dtype >
auto B = A[view];
// hm, maybe that's not possible, so let's say something like
auto B = A[view].astype< some_dtype >();

ParalleIOTest failing

@C0nsultant currently, the ParalleIOTest.cpp does not compile.

Issues are:

  • access to the Series() object
  • changed API of the loadChunk() member function.

I think the first issue is solvable via

diff --git a/test/ParallelIOTest.cpp b/test/ParallelIOTest.cpp
index cef531f..b45c9e6 100755
--- a/test/ParallelIOTest.cpp
+++ b/test/ParallelIOTest.cpp
@@ -35,9 +35,9 @@ BOOST_AUTO_TEST_CASE(git_hdf5_sample_content_test)
     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
     /* only a 3x3x3 chunk of the actual data is hardcoded. every worker reads 1/3 */
     uint64_t rank = mpi_rank % 3;
-    Series o = Series("../samples/git-sample/",
-                      "data00000%T.h5",
-                      true);
+    Series o = Series::read("../samples/git-sample/",
+                            "data00000%T.h5",
+                            true);
 
 
     {

Can you please provide a PR that fixes the test?

python API: Dask Compatible

Idea for the future:

When we read data in the python API, we should make sure this is compatible and possible to be distributed for compute tasks inside dask. See the hdf5 read example within. (Similar to pyDive, but more powerful.)

Handle possible combinations of backends and MPI gracefully

This will result in a more general solution of #108.

Currently, all backends that are MPI-aware only provide their MPI-aware interfaces if both MPI and the required libraries are available. As such, these combinations are handled well:

  • noMPI+noBACKEND
  • noMPI+BACKEND
  • MPI+BACKEND

If MPI is available, but the backend is inactive, there is no constructor with an interface matching the calls in the MPI-aware AbstractIOHandler::createIOHandler.
Possible solutions include explicitly treating the combination MPI+noBACKEND in AbstractIOHandler::createIOHandler (not preferred) or in the backend itself (preferred).

CMake target: openPMD

We currently build two "library" targets, core and io.

We should add a general "openPMD" target (with associated libopenPMD.[a|so]) so we do not confuse people.

Remove Boost Dependency

Please replace boost MPL lists with mp11 lists.
Requires Boost 1.66.0+

Update: oh wait, that is only boost variant you are controlling, right?

Anyway, careful with global BOOST_MPL_ defines in-code! Better set them in CMake as PUBLIC target properties since downstream code might use BOOST_MPL as well! (and the compile-time impact of BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS might be big).

There are also other C++11 libs of variant that we could consider to use in order to avoid Boost::MPL modifications.

Possible candidates for C++11 variants:

Possible replacements for C++11 filesystem (we require directory traversal, listing and creation):

loadChunk: std::future?

We could .loadChunk() let return a std::future which would make it on "simple use" (not using the result val -> destroyed) a blocking operation and on extended use (using the future) a nice C++11-ish object.

Any comments?

The question is then still how to bind the async functionality to Python...

Docs: Example Codes

Add compiling, self-contained examples for

  • serial read
  • serial write
  • parallel read
  • parallel write

Add them in the manual and CI.

Please keep them as short and to the point as possible and place them in examples/ with meaningful names such as serial-reader.cpp, parallel-writer.cpp, etc.

Then soft-link and include those examples in docs/source/usage/serial.rst (parallel.rst)

Python MPI Support

Part of #32: Add MPI support to the Python API with mpi4py.
As in the C++ API, MPI support must be provided optionally.

Example implementations of pybind11 + mpi4py:

Pickle Support

Add pickle support to user-facing classes and states.

We have to check if that is entirely possible and if things like file-handles need to be restored/properly shut down/etc. Probably depends on #171 as well.

MPI_INFO_ENV

Currently the parallel test fails due to a missing MPI_INFO_ENV in mpi.h.

Please be aware this is an MPI 3.0+ feature:
https://www.open-mpi.org/doc/v2.0/man3/MPI_Info_env.3.php

While requesting MPI 2.3+ support is very common, MPI 3+ is not necessarily yet common (standard: 2012) but might be acceptable nowadays. This just means our OpenMPI/MPICH/... dependencies need to be "quite recent" (in HPC terms).

Affects issues in:

  • src/IO/HDF5/ParallelHDF5IOHandler.cpp

Adhere to CRP C++ Style Guide

https://github.com/ComputationalRadiationPhysics/contributing/blob/master/codingGuideLines/cpp.md
What this project does not do:

  • doxygen @file ... documentation
  • wrap at line 80 (we do 120-ish)
  • no code alignment
  • indentation inside the deepest namespace
  • spaces around parameters in single-argument functions
  • trailing return type declaration (for lambdas, AFAIK auto is never used for function defs)
  • function/method specifier on newline
  • newline after and before ( / ) of function signature
  • parent classes are indented and placed on a new line
  • constructor : on same line (we do newline)

What this project does not do consistently:

  • copyright notice in every file
  • namespace structure (per dir, see #82)
  • lowercase foldernames (e.g. IO , ADIOS , HDF5 )
  • indent of 4
  • camelcase (some non-exposed internal functions use underscores, on purpose)
  • closing of multiline comments on newline
  • spaces around binary operators
  • newline on each , in function signatures
  • single spaces around & (reference) and * (pointer) (most often the left one is omitted)
  • initialization over assignment
  • indented case statements
  • prefix T_ for template parameters
  • case for template names
  • each template parameter is on a separate line
  • spaces around parameters in template instantiation (we try hard, but might have missed a few)

JSON

A (serial-only) JSON IO-backend would be cool.

uint64_t should be used for all extents

I am not sure if 32bit systems should be supported but if than uint64_t should be used for all extents instead of size_t. size_t is 32bit on 32bit systems and can result in issues with offsets or extents over 4GiB.
I saw in the code that offset and extent is defined as uint64_t but on many other places size_t is used.

HighFive: C++ API HDF5

TIL: https://github.com/BlueBrain/HighFive

A third-party, C++(11) API for HDF5, even supporting parallel I/O :)

(Note: we stay with the official C-API for our HDF5 backend now. But if we want to try this C++ library, we would write a second HighFive backend for it.)

We currently implement serial & parallel HDF5 via the official HDF5 C-API.

Additionally, we could implement another HDF5 backend via HighFive's C++ API.

Sphinx: C++/Py Side-By-Side

We should add a little CSS hack in docs/source/_static/ that layouts directly following C++ and Python code blocks side-by-side.

Depends on

CTest: Add targets

Add test targets to CMakeLists.txt so one can directly build & run the tests with make test

MeshRecordComponent: Frontend

The MeshRecordComponent is currently located in the backend but used in the user-frontend.

It should therefore be moved accordingly.

poc_HDF5writer: Segfault / Uninit Values

The HDF5 writer POC binary segfaults on some machines. Checking it with valgrind reviles some jumps/moves depending on uninitialized values:

Software

  • gcc 4.9.2
  • HDF5 1.10.0.1
  • OpenMPI 2.0.2 (MPI: 3.1)
  • valgrind 3.12.0.SVN

on Debian 9.3 (64bit)

Valgrind

valgrind ./bin/poc_HDF5writer 
==14663== Memcheck, a memory error detector
==14663== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==14663== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==14663== Command: ./bin/poc_HDF5writer
==14663== 
Unknown compression format zlib. This might mean that compression will not be enabled.
==14663== Conditional jump or move depends on uninitialised value(s)
==14663==    at 0x510D43A: boost::filesystem::path::filename() const (in /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.62.0)
==14663==    by 0x5106787: boost::filesystem::detail::create_directories(boost::filesystem::path const&, boost::system::error_code*) (in /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.62.0)
==14663==    by 0x4E69CD: boost::filesystem::create_directories(boost::filesystem::path const&) (operations.hpp:566)
==14663==    by 0x4D8AFA: HDF5IOHandlerImpl::createFile(Writable*, std::map<std::string, Variadic<ArgumentDatatype<std::string, std::vector<unsigned long, std::allocator<unsigned long> >, void*, std::shared_ptr<void>, Datatype, boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool>, std::shared_ptr<std::vector<unsigned long, std::allocator<unsigned long> > >, std::shared_ptr<Datatype>, std::shared_ptr<boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool> >, std::shared_ptr<std::vector<std::string, std::allocator<std::string> > > > >, std::less<std::string>, std::allocator<std::pair<std::string const, ArgumentDatatype<std::string, std::vector<unsigned long, std::allocator<unsigned long> >, void*, std::shared_ptr<void>, Datatype, boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool>, std::shared_ptr<std::vector<unsigned long, std::allocator<unsigned long> > >, std::shared_ptr<Datatype>, std::shared_ptr<boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool> >, std::shared_ptr<std::vector<std::string, std::allocator<std::string> > > > > > > const&) (HDF5IOHandler.cpp:167)
==14663==    by 0x4D8697: HDF5IOHandlerImpl::flush() (HDF5IOHandler.cpp:94)
==14663==    by 0x4E681B: HDF5IOHandler::flush() (HDF5IOHandler.cpp:1434)
==14663==    by 0x48824D: Series::flushGroupBased() (Series.cpp:496)
==14663==    by 0x487E80: Series::flush() (Series.cpp:454)
==14663==    by 0x410C56: write2() (writer.cpp:150)
==14663==    by 0x412694: main (writer.cpp:206)
==14663== 
==14663== Conditional jump or move depends on uninitialised value(s)
==14663==    at 0x510D44A: boost::filesystem::path::filename() const (in /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.62.0)
==14663==    by 0x5106787: boost::filesystem::detail::create_directories(boost::filesystem::path const&, boost::system::error_code*) (in /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.62.0)
==14663==    by 0x4E69CD: boost::filesystem::create_directories(boost::filesystem::path const&) (operations.hpp:566)
==14663==    by 0x4D8AFA: HDF5IOHandlerImpl::createFile(Writable*, std::map<std::string, Variadic<ArgumentDatatype<std::string, std::vector<unsigned long, std::allocator<unsigned long> >, void*, std::shared_ptr<void>, Datatype, boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool>, std::shared_ptr<std::vector<unsigned long, std::allocator<unsigned long> > >, std::shared_ptr<Datatype>, std::shared_ptr<boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool> >, std::shared_ptr<std::vector<std::string, std::allocator<std::string> > > > >, std::less<std::string>, std::allocator<std::pair<std::string const, ArgumentDatatype<std::string, std::vector<unsigned long, std::allocator<unsigned long> >, void*, std::shared_ptr<void>, Datatype, boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool>, std::shared_ptr<std::vector<unsigned long, std::allocator<unsigned long> > >, std::shared_ptr<Datatype>, std::shared_ptr<boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool> >, std::shared_ptr<std::vector<std::string, std::allocator<std::string> > > > > > > const&) (HDF5IOHandler.cpp:167)
==14663==    by 0x4D8697: HDF5IOHandlerImpl::flush() (HDF5IOHandler.cpp:94)
==14663==    by 0x4E681B: HDF5IOHandler::flush() (HDF5IOHandler.cpp:1434)
==14663==    by 0x48824D: Series::flushGroupBased() (Series.cpp:496)
==14663==    by 0x487E80: Series::flush() (Series.cpp:454)
==14663==    by 0x410C56: write2() (writer.cpp:150)
==14663==    by 0x412694: main (writer.cpp:206)
==14663== 
==14663== Use of uninitialised value of size 8
==14663==    at 0x510D4AA: boost::filesystem::path::filename() const (in /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.62.0)
==14663==    by 0x5106787: boost::filesystem::detail::create_directories(boost::filesystem::path const&, boost::system::error_code*) (in /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.62.0)
==14663==    by 0x4E69CD: boost::filesystem::create_directories(boost::filesystem::path const&) (operations.hpp:566)
==14663==    by 0x4D8AFA: HDF5IOHandlerImpl::createFile(Writable*, std::map<std::string, Variadic<ArgumentDatatype<std::string, std::vector<unsigned long, std::allocator<unsigned long> >, void*, std::shared_ptr<void>, Datatype, boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool>, std::shared_ptr<std::vector<unsigned long, std::allocator<unsigned long> > >, std::shared_ptr<Datatype>, std::shared_ptr<boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool> >, std::shared_ptr<std::vector<std::string, std::allocator<std::string> > > > >, std::less<std::string>, std::allocator<std::pair<std::string const, ArgumentDatatype<std::string, std::vector<unsigned long, std::allocator<unsigned long> >, void*, std::shared_ptr<void>, Datatype, boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool>, std::shared_ptr<std::vector<unsigned long, std::allocator<unsigned long> > >, std::shared_ptr<Datatype>, std::shared_ptr<boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool> >, std::shared_ptr<std::vector<std::string, std::allocator<std::string> > > > > > > const&) (HDF5IOHandler.cpp:167)
==14663==    by 0x4D8697: HDF5IOHandlerImpl::flush() (HDF5IOHandler.cpp:94)
==14663==    by 0x4E681B: HDF5IOHandler::flush() (HDF5IOHandler.cpp:1434)
==14663==    by 0x48824D: Series::flushGroupBased() (Series.cpp:496)
==14663==    by 0x487E80: Series::flush() (Series.cpp:454)
==14663==    by 0x410C56: write2() (writer.cpp:150)
==14663==    by 0x412694: main (writer.cpp:206)
==14663== 
==14663== Invalid read of size 1
==14663==    at 0x510D4AA: boost::filesystem::path::filename() const (in /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.62.0)
==14663==    by 0x5106787: boost::filesystem::detail::create_directories(boost::filesystem::path const&, boost::system::error_code*) (in /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.62.0)
==14663==    by 0x4E69CD: boost::filesystem::create_directories(boost::filesystem::path const&) (operations.hpp:566)
==14663==    by 0x4D8AFA: HDF5IOHandlerImpl::createFile(Writable*, std::map<std::string, Variadic<ArgumentDatatype<std::string, std::vector<unsigned long, std::allocator<unsigned long> >, void*, std::shared_ptr<void>, Datatype, boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool>, std::shared_ptr<std::vector<unsigned long, std::allocator<unsigned long> > >, std::shared_ptr<Datatype>, std::shared_ptr<boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool> >, std::shared_ptr<std::vector<std::string, std::allocator<std::string> > > > >, std::less<std::string>, std::allocator<std::pair<std::string const, ArgumentDatatype<std::string, std::vector<unsigned long, std::allocator<unsigned long> >, void*, std::shared_ptr<void>, Datatype, boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool>, std::shared_ptr<std::vector<unsigned long, std::allocator<unsigned long> > >, std::shared_ptr<Datatype>, std::shared_ptr<boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool> >, std::shared_ptr<std::vector<std::string, std::allocator<std::string> > > > > > > const&) (HDF5IOHandler.cpp:167)
==14663==    by 0x4D8697: HDF5IOHandlerImpl::flush() (HDF5IOHandler.cpp:94)
==14663==    by 0x4E681B: HDF5IOHandler::flush() (HDF5IOHandler.cpp:1434)
==14663==    by 0x48824D: Series::flushGroupBased() (Series.cpp:496)
==14663==    by 0x487E80: Series::flush() (Series.cpp:454)
==14663==    by 0x410C56: write2() (writer.cpp:150)
==14663==    by 0x412694: main (writer.cpp:206)
==14663==  Address 0x10079f34a7 is not stack'd, malloc'd or (recently) free'd
==14663== 
==14663== 
==14663== Process terminating with default action of signal 11 (SIGSEGV)
==14663==  Access not within mapped region at address 0x10079F34A7
==14663==    at 0x510D4AA: boost::filesystem::path::filename() const (in /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.62.0)
==14663==    by 0x5106787: boost::filesystem::detail::create_directories(boost::filesystem::path const&, boost::system::error_code*) (in /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.62.0)
==14663==    by 0x4E69CD: boost::filesystem::create_directories(boost::filesystem::path const&) (operations.hpp:566)
==14663==    by 0x4D8AFA: HDF5IOHandlerImpl::createFile(Writable*, std::map<std::string, Variadic<ArgumentDatatype<std::string, std::vector<unsigned long, std::allocator<unsigned long> >, void*, std::shared_ptr<void>, Datatype, boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool>, std::shared_ptr<std::vector<unsigned long, std::allocator<unsigned long> > >, std::shared_ptr<Datatype>, std::shared_ptr<boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool> >, std::shared_ptr<std::vector<std::string, std::allocator<std::string> > > > >, std::less<std::string>, std::allocator<std::pair<std::string const, ArgumentDatatype<std::string, std::vector<unsigned long, std::allocator<unsigned long> >, void*, std::shared_ptr<void>, Datatype, boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool>, std::shared_ptr<std::vector<unsigned long, std::allocator<unsigned long> > >, std::shared_ptr<Datatype>, std::shared_ptr<boost::variant<char, unsigned char, short, int, long, unsigned short, unsigned int, unsigned long, float, double, long double, std::string, std::vector<char, std::allocator<char> >, std::vector<short, std::allocator<short> >, std::vector<int, std::allocator<int> >, std::vector<long, std::allocator<long> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::vector<unsigned short, std::allocator<unsigned short> >, std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<unsigned long, std::allocator<unsigned long> >, std::vector<float, std::allocator<float> >, std::vector<double, std::allocator<double> >, std::vector<long double, std::allocator<long double> >, std::vector<std::string, std::allocator<std::string> >, std::array<double, 7ul>, bool> >, std::shared_ptr<std::vector<std::string, std::allocator<std::string> > > > > > > const&) (HDF5IOHandler.cpp:167)
==14663==    by 0x4D8697: HDF5IOHandlerImpl::flush() (HDF5IOHandler.cpp:94)
==14663==    by 0x4E681B: HDF5IOHandler::flush() (HDF5IOHandler.cpp:1434)
==14663==    by 0x48824D: Series::flushGroupBased() (Series.cpp:496)
==14663==    by 0x487E80: Series::flush() (Series.cpp:454)
==14663==    by 0x410C56: write2() (writer.cpp:150)
==14663==    by 0x412694: main (writer.cpp:206)
==14663==  If you believe this happened as a result of a stack
==14663==  overflow in your program's main thread (unlikely but
==14663==  possible), you can try to increase the size of the
==14663==  main thread stack using the --main-stacksize= flag.
==14663==  The main thread stack size used in this run was 8388608.
==14663== 
==14663== HEAP SUMMARY:
==14663==     in use at exit: 243,674 bytes in 2,984 blocks
==14663==   total heap usage: 3,463 allocs, 479 frees, 436,960 bytes allocated
==14663== 
==14663== LEAK SUMMARY:
==14663==    definitely lost: 0 bytes in 0 blocks
==14663==    indirectly lost: 0 bytes in 0 blocks
==14663==      possibly lost: 0 bytes in 0 blocks
==14663==    still reachable: 243,674 bytes in 2,984 blocks
==14663==                       of which reachable via heuristic:
==14663==                         stdstring          : 2,372 bytes in 64 blocks
==14663==         suppressed: 0 bytes in 0 blocks
==14663== Rerun with --leak-check=full to see details of leaked memory
==14663== 
==14663== For counts of detected and suppressed errors, rerun with: -v
==14663== Use --track-origins=yes to see where uninitialised values come from
==14663== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
Segmentation fault

Namespace Per Dir

Follow-up to #81.

Each directory inside include/openPMD/ should define everything in a namespace with the same name as the dir.

  • backend/ (openPMD::backend)
  • IO/ (openPMD::IO)
    • ADIOS/ (openPMD::IO::ADIOS)
    • HDF5/ (openPMD::IO::HDF5)

Rename Variadic to Variant

The generic storage used for e.g. Attribute values was initially designed to store arbitrary datatypes, hence the name Variadic was chosen.

During developement it became pretty obvious that a restriction to a finite, predefined set of datatypes is the more sensible way. Since boost/mpark/std variants do exactly that, they have been used all along.

I propose to rename the auxiliary class Variadic to Variant to reflect this decision.

Series Constructor: Path & File?

Do we really need both a path and a file (prefix) attribute in the (Series) constructors?

Probably it is also possible just to pass one string and split to basename with boost, similar to yt and openPMD-viewer.

C++ code style & static code analysis in CI

It would be desirable to also have multiple checks for code quality, code style and static analysis of the code, independent of the compiler.

Possible code style checkers:

Possible code analysis tools:

Test / Code coverage:

Structure: openPMD/ dir and namespace

All includes should be inside a openPMD/ directory for grouping and additionally in an openPMD:: namespace. A collective openPMD/openPMD.hpp include file would be nice as well.

Travis: OSX

Add a single OSX build to the travis build matrix.

Docs: How to Write a Backend

Write a document documenting how to implement and what the concepts of a (new) backend are.

The according file to modify is:

  • docs/source/dev/backend.rst

Move to openPMD org

When the first examples build, move the repo to github.com/openPMD and fork back

HDF5 Closing: uninitialised byte(s)

Running valgrind on the SerialIOTests reviles uninitialised bytes in HDF5 close.

Maybe check what's given into HDF5IOHandlerImpl::~HDF5IOHandlerImpl() in file HDF5IOHandler.cpp:69?

Note: I did run the binary without downloaded sample files.

valgrind bin/SerialIOTests

# [...]
==14254== Syscall param write(buf) points to uninitialised byte(s)
==14254==    at 0x6E75190: __write_nocancel (syscall-template.S:84)
==14254==    by 0x5B2DA35: ??? (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B277CB: H5FD_write (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B0E94F: H5F__accum_flush (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B0A15B: H5F_flush (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B0A82A: H5F_dest (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B0AF2C: H5F_try_close (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B0B180: H5F_close (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B83BEE: H5I_dec_ref (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B83D7B: H5I_dec_app_ref (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B05898: H5Fclose (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5D526A: HDF5IOHandlerImpl::~HDF5IOHandlerImpl() (HDF5IOHandler.cpp:69)
==14254==  Address 0x8bb3d4a is 2,490 bytes inside a block of size 4,104 alloc'd
==14254==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==14254==    by 0x5B3170C: H5FL_blk_malloc (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B322F3: H5FL_blk_realloc (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B0DAB4: ??? (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B0F35F: H5F__accum_write (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B12509: H5F_block_write (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5AADDE7: H5C__flush_single_entry (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5AAEF24: H5C_flush_cache (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5A86F1C: H5AC_flush (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B0A100: H5F_flush (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B0A82A: H5F_dest (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==    by 0x5B0AF2C: H5F_try_close (in /usr/lib/x86_64-linux-gnu/libhdf5_openmpi.so.100.0.1)
==14254==
# [...]

Test cases with 0-sized reads & writes

To verify the desired parallel behaviour, we should add tests where multiple participants from an MPI-communicator contribute 0-sized chunks to a collective IO operation.

A minimal example would consist of 3 ranks with multiple tested combinations of empty/non-empty chunks.

CMake: Component NOMPI

We should add a CMake component NOMPI to our configuration package to allow explicitly searching for no-MPI installs in find_package.

Fix Clang Warnings

We should fix all the clang (5.0) warnings that are currently raised in the code.

We should try to aim to be warning free with the following compiler flags:

export CXXFLAGS="-Wall -Wextra -Woverloaded-virtual -Wshadow"

Example: MPI Benchmark

We need to add a parallel read & write MPI benchmark at some point, that can be scaled with ranks e.g. for 3D meshes and large particle records.

It can then measure performance in terms of bandwidth, etc.

Versioning Scheme

Versioning of the lib can be tricky since the openPMD base standard also has a version and we want to avoid confusion.

The idea I came up with yet was to use always the same major version of openPMD-api as the base standard and try to support all minor versions of this major (but not previous major versions; see updater).

The only problem comes in when we want to do incompatible API changes within a major version, which would break the usual semantic versioning of openPMD-api.

In the README (badges & test) and in openPMD/version.hpp defines we then define additional macros (C++: done already; Py: Needs Exposure) that expose which min and max of the openPMD standard are supported.

Of course we could also just do a simple, independent semantic versioning of openPMD-api (with the docs as mentioned above) but I would bet this will confuse people a lot...

CI: Appveyor

Add appveyor to CI for testing Windows platforms.

Serial testing and python support is probably sufficient.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.