h5

出典:h5cpp/docs/USAGE.md

h5cpp の使い方

ビルドの基本は README を参照してください。 保存形式は h5c の FORMAT.md と共通です。

ビルド設定

CMakeUserPresets.json で intel / gnu、並列版では intel-mpi / gnu-mpi を継承し、CMAKE_PREFIX_PATH と CMAKE_INSTALL_PREFIX を設定します。

C++20 は H5CPP_CXX_STANDARD=20 または intel-cxx20 preset で選択します。 標準ライブラリが対応していれば h5cpp::span は std::span になります。 未対応でも h5cpp の span インターフェースを使えます。 たとえば icpx と GCC 8.5 の libstdc++ の組み合わせでは、C++20 モードでも std::span は使えません。必要なら新しい libstdc++ を選択してください。

ターゲットとヘッダー

target 用途・依存先
h5cpp::h5cpp_serial 逐次 API。h5c::h5c_serial に依存
h5cpp::h5cpp_parallel 並列 API。serial と h5c::h5c_parallel に依存。H5CPP_ENABLE_PARALLEL=ON のとき提供
h5cpp::h5cpp 逐次構成では serial、並列構成では serial + parallel
ヘッダー 型
h5cpp/h5cpp.hpp h5cpp::file
h5cpp/h5cpp_mpi.hpp h5cpp::parallel_file
h5cpp/h5cpp_viz.hpp h5cpp::viz
h5cpp/h5cpp_viz_mpi.hpp h5cpp::parallel_viz

HDF5 の include / library パスは target から引き継がれます。 リンクまで MPI 不要にするには Serial HDF5 で構成した h5c を使い、 H5CPP_ENABLE_PARALLEL=OFF にしてください。

所有権と例外

file、parallel_file、viz、parallel_viz はファイルを所有し、 コピーできません。move で所有権を移します。デストラクタはファイルを閉じ、 例外を投げません。close の失敗を確認するには明示的に close() を呼びます。 並列オブジェクトは全ランクで close をそろえ、MPI 終了前に破棄してください。

c_handle() とファイルの hid() は借用ハンドルです。呼び出し側で解放せず、 所有するオブジェクトが閉じられた後は使わないでください。 読み込みで返る std::vector・std::string は呼び出し側が所有します。

I/O の失敗は std::runtime_error を継承する h5cpp::error で通知されます。 what() で説明、status() で h5c のエラーコードを確認できます。

h5cpp::file f("result.h5", h5cpp::mode::read);
try {
    auto values = f.read<double>("/optional");
} catch (const h5cpp::error& e) {
    if (e.status() != H5C_ERR_NOT_FOUND) throw;
}

コンテナによる読み書き

mode::read は既存ファイルの読み取り、readwrite は読み書き、 truncate は新規作成または既存ファイルの切り詰めです。

h5cpp::file f("result.h5", h5cpp::mode::truncate);
std::vector<double> values = {1, 2, 3, 4, 5, 6};
f.write("/values", values, {3, 2});
auto got = f.read<double>("/values");
auto meta = f.info("/values");    // dims, type, count
f.read_into("/values", values, meta.dims);
f.close();

shape は std::vector<std::size_t> です。 次元順序 に従って指定します。 write(path, vector) では 1 次元になります。shape を渡す場合、vector の 要素数は shape の積と一致させます。read_into() は既存バッファに読み込みます。 生ポインタ版もあり、std::array などは .data() と shape を渡して使えます。 生ポインタではバッファ長を検査しないため、必要な要素数を確保してください。 既存 dataset を異なる shape で置き換える場合は write() の末尾に true を渡します。

スカラーには write_scalar() / read_scalar<T>()、文字列には write_string() / read_string() を使います。属性は write_attr_str()、 write_attr_scalar()、write_attr_array() と対応する read メソッドを使います。 数値配列属性の入出力は std::vector<T>、要素数の問い合わせは attr_length() です。 文字列の相互運用制約は 保存形式 を参照してください。

テンプレートの対応型は float、double、std::int32_t、std::int64_t、 h5c_bool_t です。bool と std::vector<bool> は使えません。

std::vector<h5c_bool_t> flags = {H5C_TRUE, H5C_FALSE};
h5cpp::file flags_file("flags.h5", h5cpp::mode::truncate);
flags_file.write("/flags", flags);
flags_file.close();

成分配列と span

成分ごとに分かれたバッファは、長さ付きの h5cpp::span で渡せます。 span はバッファを所有しないため、呼び出しが終わるまで元の配列を有効に保ちます。 各成分の長さは一致させてください。

h5cpp::file f("velocity.h5", h5cpp::mode::truncate);
std::vector<double> u(n), v(n), w(n);
f.write_interleaved<double>("/velocity", {u, v, w});
f.read_interleaved<double>("/velocity", {u, v, w});
auto y = f.read_component<double>("/velocity", 1);  // 成分番号は 0-origin
f.close();

ポインタと長さからは h5cpp::span<const double>(ptr, n) を作れます。 保存配置とテンソル成分順は 多成分フィールド を参照してください。

並列 I/O

MPI 初期化後に parallel_file を開きます。

#include <h5cpp/h5cpp_mpi.hpp>

std::vector<double> local(nlocal * 3);
h5cpp::parallel_file f("out.h5", h5cpp::mode::truncate);  // MPI_COMM_WORLD
f.write("/coords", local, {nlocal, 3});
auto meta = f.info("/coords");       // local / global の dataset_info
auto block = f.local_block("/coords"); // offset, count
auto got = f.read<double>("/coords");
f.close();

communicator と MPI-IO hint はコンストラクタの第 3・第 4 引数に渡します。 communicator は close まで有効に保ってください。 分割条件・collective の呼び出し規則は h5c の並列 API と共通です。C++ ではコンストラクタ、close、読み書き、info()、local_block()、 partition() を全ランクでそろえます。属性を書く場合も全ランクで同じ値を渡します。 set_collective(false) は転送モードを変えます。全ランクで同じ設定にしてください。 exists()、attr_exists()、is_collective()、comm() はローカルな参照です。

partition() は全ランクの境界を vector で返します。 read_rows<T>(path, offset, count) は通常 dataset の連続行を vector に読み込み、 保存済み partition を参照しません。成分配列には逐次版と同じ write_interleaved() / read_interleaved() を使えます。

コンテナ長などの C++ 側の検査はローカルに例外を投げます。 一部ランクだけ例外で抜け、他ランクが collective 操作を続けないようにしてください。

可視化

可視化用 HDF5 の出力は USAGE-visualization.md を 参照してください。逐次の h5cpp::viz と、それを継承して communicator を取る h5cpp::parallel_viz の使い方を扱っています。