出典: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 の使い方を扱っています。