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

Supported openPMD Standard Doxygen Gitter chat Supported Platforms License DOI
CodeFactor LGTM: C/C++ LGTM: Python LGTM: Total alerts 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, ADIOS1, ADIOS2 and JSON. Writing & reading through those backends and their associated files is supported for serial and MPI-parallel workflows.



C++14 C++14 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& i : s.iterations ) {
std::cout << "Iteration: " << i.first << "\n";
for( auto const& m : i.second.meshes ) {
std::cout << " Mesh '" << m.first << "' attributes:\n";
for( auto const& val : m.second.attributes() )
std::cout << " " << val << '\n';
for( auto const& p : i.second.particles ) {
std::cout << " Particle species '" << p.first << "' attributes:\n";
for( auto const& val : p.second.attributes() )
std::cout << " " << val << '\n';


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))


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



  • CMake 3.15.0+
  • C++14 capable compiler, e.g. g++ 5.0+, clang 5.0+, VS 2017+

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.6 - 3.9
    • pybind11 2.6.2+
    • numpy 1.15+
    • mpi4py 2.1+ (optional, for MPI)
    • pandas 1.0+ (optional, for dataframes)
    • dask 2021+ (optional, for dask dataframes)


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:

<a href="">Spack</a>

Spack Version Spack Platforms Spack Use Case

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

<a href="">Conda</a>

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

<a href="">Brew</a>

Brew Version Brew Platforms Brew Use Case

brew tap openpmd/openpmd
brew install openpmd-api

<a href="">PyPI</a>

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, ADIOS1, 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 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:

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

From Source

Source Use Case

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

git clone
mkdir openPMD-api-build
cd openPMD-api-build
# optional: for full tests, with unzip
# for own install prefix append:
# for options append:
# -DopenPMD_USE_...=...
# e.g. for python support add:
cmake ../openPMD-api
cmake --build .
# optional
# 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_ADIOS1 AUTO/ON/OFF ADIOS1 backend (.bp files up to version BP3)
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
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_PYBIND11 ON/OFF pybind11 2.6.2+

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_EXAMPLES ON/OFF Build examples
openPMD_BUILD_CLI_TOOLS ON/OFF Build command-line tools

Linking to your project

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


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

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

find_package(openPMD 0.9.0 CONFIG)
target_link_libraries(YourTarget PRIVATE openPMD::openPMD)

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

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:

# set(openPMD_BUILD_SHARED_LIBS OFF) # precedence over BUILD_SHARED_LIBS if needed; or:
set(openPMD_INSTALL ${BUILD_SHARED_LIBS}) # only install if used as shared a library
GIT_TAG "dev")


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" ]
pkg-config --libs --static openPMD
# -L/usr/local/lib -L/usr/lib/x86_64-linux-gnu/openmpi/lib -lopenPMD -pthread /usr/lib/ -pthread /usr/lib/x86_64-linux-gnu/openmpi/lib/ /usr/lib/ /usr/lib/x86_64-linux-gnu/hdf5/openmpi/ /usr/lib/x86_64-linux-gnu/ /usr/lib/x86_64-linux-gnu/ /usr/lib/x86_64-linux-gnu/ /usr/lib/x86_64-linux-gnu/ -pthread /usr/lib/ -pthread /usr/lib/x86_64-linux-gnu/openmpi/lib/ /usr/lib/
pkg-config --libs openPMD
# -L${HOME}/somepath/lib -lopenPMD
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:

  • Axel Huebl (HZDR, now LBNL): project lead, releases, documentation, automated CI/CD, Python bindings, Dask, installation & packaging, prior reference implementations
  • Franz Poeschel (CASUS): JSON & ADIOS2 backend, data staging/streaming, reworked class design
  • Fabian Koller (HZDR): initial library design and implementation with HDF5 & ADIOS1 backend
  • Junmin Gu (LBNL): non-collective parallel I/O fixes, ADIOS improvements, benchmarks

Further thanks go to improvements and contributions from:


The openPMD-api authors acknowledge support via the following programs. This project has received funding from the European Unions Horizon 2020 research and innovation programme under grant agreement No 654220. 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 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.

Transitive Contributions

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

open series as read-only, fails if series is not found
Root level of the openPMD hierarchy.
Definition: Series.hpp:478