Skip to content

Commit 4244f32

Browse files
committed
Merge branch 'staging' into release
2 parents 6f2a140 + 81c12c3 commit 4244f32

227 files changed

Lines changed: 85658 additions & 469 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767

6868
steps:
6969
- name: Checkout
70-
uses: actions/checkout@v4
70+
uses: actions/checkout@v6
7171
with:
7272
fetch-depth: 0
7373

@@ -131,7 +131,7 @@ jobs:
131131
set -euxo pipefail
132132
133133
brew update
134-
brew install cmake ninja hdf5
134+
brew install --quiet cmake ninja hdf5
135135
136136
HDF5_PREFIX="$(brew --prefix hdf5)"
137137
@@ -195,7 +195,7 @@ jobs:
195195
- name: Restore HDF5 1.10.10 cache
196196
if: runner.os == 'Windows'
197197
id: cache-hdf5
198-
uses: actions/cache/restore@v4
198+
uses: actions/cache/restore@v5
199199
with:
200200
path: ${{ runner.temp }}\hdf5-${{ env.HDF5_VERSION }}-install
201201
key: hdf5-${{ runner.os }}-${{ matrix.compiler }}-${{ env.HDF5_VERSION }}-${{ env.HDF5_CACHE_VERSION }}
@@ -241,7 +241,7 @@ jobs:
241241
242242
- name: Save HDF5 1.10.10 cache
243243
if: runner.os == 'Windows' && steps.cache-hdf5.outputs.cache-hit != 'true'
244-
uses: actions/cache/save@v4
244+
uses: actions/cache/save@v5
245245
with:
246246
path: ${{ runner.temp }}\hdf5-${{ env.HDF5_VERSION }}-install
247247
key: ${{ steps.cache-hdf5.outputs.cache-primary-key }}
@@ -282,6 +282,7 @@ jobs:
282282
-DCMAKE_CXX_STANDARD=23
283283
-DCMAKE_BUILD_TYPE=Release
284284
-DH5CPP_BUILD_TESTS=ON
285+
-DH5CPP_BUILD_EXAMPLES=ON
285286
)
286287
287288
if [[ -n "${HDF5_ROOT:-}" ]]; then
@@ -339,7 +340,7 @@ jobs:
339340
340341
- name: Upload Status Artifact
341342
if: always()
342-
uses: actions/upload-artifact@v4
343+
uses: actions/upload-artifact@v7
343344
with:
344345
name: status-${{ matrix.os }}-${{ matrix.compiler }}
345346
path: badge-status/status-${{ matrix.os }}-${{ matrix.compiler }}.json
@@ -359,7 +360,7 @@ jobs:
359360
sudo apt-get install -y jq curl
360361
361362
- name: Download all status artifacts
362-
uses: actions/download-artifact@v4
363+
uses: actions/download-artifact@v8
363364
with:
364365
path: badge-status
365366
pattern: status-*
@@ -430,7 +431,7 @@ jobs:
430431
431432
- name: Upload badges artifact
432433
if: always()
433-
uses: actions/upload-artifact@v4
434+
uses: actions/upload-artifact@v7
434435
with:
435436
name: ${{ github.ref_name == 'staging' && 'badges-staging' || 'badges' }}
436437
path: ${{ github.ref_name == 'staging' && 'badges-staging' || 'badges' }}
@@ -456,7 +457,7 @@ jobs:
456457

457458
steps:
458459
- name: Checkout
459-
uses: actions/checkout@v4
460+
uses: actions/checkout@v6
460461
with:
461462
fetch-depth: 0
462463

@@ -488,7 +489,8 @@ jobs:
488489
-DCMAKE_CXX_COMPILER=g++-14 \
489490
-DCMAKE_C_FLAGS="--coverage -O0 -g" \
490491
-DCMAKE_CXX_FLAGS="--coverage -O0 -g" \
491-
-DH5CPP_BUILD_TESTS=ON
492+
-DH5CPP_BUILD_TESTS=ON \
493+
-DH5CPP_BUILD_EXAMPLES=ON
492494
493495
- name: Build
494496
shell: bash
@@ -530,7 +532,7 @@ jobs:
530532
lcov --gcov-tool /usr/bin/gcov-14 --list coverage.info
531533
532534
- name: Upload coverage reports to Codecov
533-
uses: codecov/codecov-action@v5
535+
uses: codecov/codecov-action@v6
534536
with:
535537
files: ./coverage.info
536538
disable_search: true

.github/workflows/docs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ jobs:
1313

1414
steps:
1515
- name: Checkout repo
16-
uses: actions/checkout@v4
16+
uses: actions/checkout@v6
1717

1818
- name: Set up Python
19-
uses: actions/setup-python@v5
19+
uses: actions/setup-python@v6
2020
with:
2121
python-version: '3.x'
2222

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ endif()
4242
# ─── Options ──────────────────────────────────────────────────────────────────────
4343
option(H5CPP_BUILD_EXAMPLES "Build examples" OFF)
4444
option(H5CPP_BUILD_TESTS "Build tests" OFF)
45+
option(H5CPP_BUILD_BENCH "Build benches" OFF)
4546
option(H5CPP_USE_LIBDEFLATE "Use libdeflate for H5CPP deflate/gzip filters when available" ON)
4647
option(H5CPP_REQUIRE_LIBDEFLATE "Fail configuration if H5CPP_USE_LIBDEFLATE is ON and libdeflate is not found" OFF)
4748
option(H5CPP_INSTALL_LIBDEFLATE "Install the resolved libdeflate header and library with H5CPP" OFF)
@@ -103,6 +104,8 @@ if(MPI_FOUND AND HDF5_IS_PARALLEL)
103104
endif()
104105

105106
# ─── Include Directories & Libraries ──────────────────────────────────────────────
107+
find_package(ZLIB REQUIRED)
108+
106109
list(APPEND H5CPP_INCLUDE_DIRS
107110
${CMAKE_CURRENT_SOURCE_DIR}
108111
${HDF5_INCLUDE_DIRS}
@@ -198,6 +201,10 @@ if(H5CPP_BUILD_TESTS AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt)
198201
add_subdirectory(test)
199202
endif()
200203

204+
if(H5CPP_BUILD_BENCH AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/bench/CMakeLists.txt)
205+
add_subdirectory(bench)
206+
endif()
207+
201208
# ─── Install Rules ────────────────────────────────────────────────────────────────
202209
if(WIN32)
203210
set(INSTALL_DIR_CMAKE "${CMAKE_INSTALL_PREFIX}/share/h5cpp/cmake")

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[![CI](https://github.com/vargalabs/h5cpp/actions/workflows/ci.yml/badge.svg)](https://github.com/vargalabs/h5cpp/actions/workflows/ci.yml)
2-
[![codecov](https://codecov.io/gh/vargalabs/h5cpp/branch/main/graph/badge.svg)](https://app.codecov.io/gh/vargalabs/h5cpp/tree/main)
2+
[![codecov](https://codecov.io/gh/vargalabs/h5cpp/branch/release/graph/badge.svg)](https://app.codecov.io/gh/vargalabs/h5cpp/tree/release)
33
[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
44
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.20123216.svg)](https://doi.org/10.5281/zenodo.20123216)
55
[![GitHub release](https://img.shields.io/github/v/release/vargalabs/h5cpp.svg)](https://github.com/vargalabs/h5cpp/releases)

bench/CMakeLists.txt

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# SPDX-License-Identifier: MIT
2+
# This file is part of H5CPP.
3+
# Copyright (c) 2025-2026 Varga Labs, Toronto, ON, Canada.
4+
5+
find_package(ZLIB REQUIRED)
6+
7+
set(INCLUDE_DIRS
8+
${CMAKE_CURRENT_SOURCE_DIR}/..
9+
${HDF5_C_INCLUDE_DIRS}
10+
)
11+
12+
set(LIBS
13+
${HDF5_LIBRARIES}
14+
ZLIB::ZLIB
15+
libh5cpp-libdeflate
16+
)
17+
18+
# ─── nanobench harness (vendored single header) ─────────────────────────────────────
19+
set(HARNESS_SOURCES
20+
${CMAKE_CURRENT_SOURCE_DIR}/harness/nanobench.h
21+
)
22+
23+
# ─── Common bench compile settings ──────────────────────────────────────────────────
24+
function(add_bench file_name)
25+
set(options)
26+
set(one_value_args)
27+
set(multi_value_args LIBRARIES)
28+
cmake_parse_arguments(ARG "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
29+
30+
add_executable(bench-${file_name} workloads/${file_name}.cpp ${HARNESS_SOURCES})
31+
target_include_directories(bench-${file_name} PRIVATE ${INCLUDE_DIRS})
32+
target_link_libraries(bench-${file_name} PRIVATE ${LIBS} ${ARG_LIBRARIES})
33+
# Intentionally not adding -Wall -Wextra: h5cpp core headers have
34+
# pre-existing warnings that would pollute bench output. The bench
35+
# code itself is simple and checked with the same rigor as tests.
36+
set_target_properties(bench-${file_name} PROPERTIES
37+
CXX_STANDARD 17
38+
CXX_STANDARD_REQUIRED ON
39+
CXX_EXTENSIONS OFF
40+
)
41+
endfunction()
42+
43+
# ─── Workload benches ───────────────────────────────────────────────────────────────
44+
add_bench(sequential)
45+
add_bench(filesystem_ceiling)
46+
add_bench(containers)
47+
add_bench(chunked_filtered)
48+
add_bench(high_throughput)
49+
add_bench(small_object)
50+
51+
# ─── Aggregate target ───────────────────────────────────────────────────────────────
52+
add_custom_target(h5cpp-bench DEPENDS
53+
bench-sequential
54+
bench-filesystem_ceiling
55+
bench-containers
56+
bench-chunked_filtered
57+
bench-high_throughput
58+
bench-small_object
59+
)

bench/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# h5cpp Bench Suite
2+
3+
Reproducible performance benchmarks for h5cpp I/O throughput claims.
4+
5+
## Quick Start
6+
7+
```bash
8+
cmake -B build -DH5CPP_BUILD_BENCH=ON -DCMAKE_BUILD_TYPE=Release
9+
cmake --build build --target h5cpp-bench
10+
./build/bench/bench-sequential
11+
```
12+
13+
## Design
14+
15+
See `tasks/h5cpp-performance-evaluation-framework-design.md` in the workspace repo for the full architecture report.
16+
17+
## Workloads
18+
19+
| Bench | What It Measures |
20+
|-------|------------------|
21+
| `bench-sequential` | 1D `vector<double>` write/read throughput at 1K–10M elements |
22+
| `bench-filesystem_ceiling` | Raw `fwrite`/`fread` bandwidth ceiling on `/dev/shm` |
23+
| `bench-containers` | h5cpp high-level vs raw HDF5 C API overhead |
24+
| `bench-chunked_filtered` | Chunked write with gzip, zstd, lz4, shuffle+gzip |
25+
| `bench-high_throughput` | Standard path (direct chunk comparison deferred) |
26+
| `bench-small_object` | Latency for single values, 4 KB vectors, structs |
27+
28+
## Output
29+
30+
Each bench prints a markdown table to stdout. To suppress the table and emit JSON:
31+
32+
```bash
33+
./build/bench/bench-sequential > /dev/null 2> results.json
34+
```
35+
36+
*(JSON export is a v2 enhancement; currently stdout only.)*
37+
38+
## Methodology
39+
40+
- Files are created on `/dev/shm` (tmpfs) to eliminate disk variance.
41+
- Synthetic data uses a fixed seed (`42`) for reproducible compression ratios.
42+
- Each benchmark case runs enough iterations for nanobench to reach statistical stability.
43+
44+
## CI
45+
46+
The `bench` job runs on `ubuntu-24.04 / gcc-14` in Release mode. It is **advisory only** — never blocks merge.

bench/fixtures/synthetic.hpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2025-2026 Varga Labs, Toronto, ON, Canada.
3+
#pragma once
4+
5+
#include <vector>
6+
#include <random>
7+
#include <cstddef>
8+
9+
namespace bench::fixture {
10+
11+
// Deterministic pseudo-random data generator for reproducible benchmarks.
12+
// Same seed => same bytes => same compression ratios.
13+
class Synthetic {
14+
public:
15+
explicit Synthetic(std::uint64_t seed = 42) : rng_(seed) {}
16+
17+
std::vector<double> doubles(std::size_t n) {
18+
std::vector<double> out(n);
19+
std::uniform_real_distribution<double> dist(-1.0, 1.0);
20+
for (auto& v : out) v = dist(rng_);
21+
return out;
22+
}
23+
24+
std::vector<std::uint8_t> bytes(std::size_t n) {
25+
std::vector<std::uint8_t> out(n);
26+
std::uniform_int_distribution<int> dist(0, 255);
27+
for (auto& v : out) v = static_cast<std::uint8_t>(dist(rng_));
28+
return out;
29+
}
30+
31+
private:
32+
std::mt19937_64 rng_;
33+
};
34+
35+
} // namespace bench::fixture

bench/harness/config.hpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2025-2026 Varga Labs, Toronto, ON, Canada.
3+
#pragma once
4+
5+
#include <vector>
6+
#include <cstdlib>
7+
#include <cstddef>
8+
9+
namespace bench {
10+
11+
inline bool is_ci() {
12+
const char* env = std::getenv("H5CPP_BENCH_CI");
13+
return env && env[0] == '1';
14+
}
15+
16+
// Returns tiny sizes for CI (smoke test only) or 1GB/10GB for real benchmarking.
17+
inline std::vector<std::size_t> payload_sizes() {
18+
if (is_ci()) {
19+
return {1'000}; // 8 KB — enough to exercise the code path
20+
}
21+
return {
22+
125'000'000, // 1 GB
23+
1'250'000'000, // 10 GB
24+
};
25+
}
26+
27+
// Single default payload size for benches that don't sweep sizes.
28+
inline std::size_t default_payload_size() {
29+
return is_ci() ? 1'000 : 125'000'000; // 8 KB vs 1 GB
30+
}
31+
32+
} // namespace bench

0 commit comments

Comments
 (0)