From c3ab8b2b498263067e20691474b05db080e118ad Mon Sep 17 00:00:00 2001 From: singhpratech <42719720+singhpratech@users.noreply.github.com> Date: Wed, 29 Jul 2026 18:26:12 -0400 Subject: [PATCH] Update gpudb to v0.3.0 --- extensions/gpudb/description.yml | 104 ++++++++++++++----------------- 1 file changed, 48 insertions(+), 56 deletions(-) diff --git a/extensions/gpudb/description.yml b/extensions/gpudb/description.yml index ca7ea714e..5c18733cc 100644 --- a/extensions/gpudb/description.yml +++ b/extensions/gpudb/description.yml @@ -1,7 +1,7 @@ extension: name: gpudb description: GPU-accelerated analytical operators for DuckDB on NVIDIA CUDA and Apple Silicon Metal. First SQL execution engine that targets Apple Silicon GPUs. - version: 0.1.3 + version: 0.3.0 language: C++ build: cmake license: Apache-2.0 @@ -12,12 +12,12 @@ extension: repo: github: singhpratech/duckdbgpumetaldbram - ref: 018d8a306ac2903f64c3391d42c59038b4fc2c28 + ref: 2f416b1037a5d22662bd67b7fda26f0b96b82858 docs: hello_world: | LOAD gpudb; - -- GPU-accelerated SUM (CUDA on NVIDIA, Metal on Apple Silicon, CPU fallback otherwise) + -- Drop-in aggregates (BIGINT and DOUBLE overloads) SELECT gpu_sum(value::BIGINT) FROM range(1000000) AS t(value); -- Verify against native sum @@ -26,53 +26,45 @@ docs: sum(value::BIGINT) AS native FROM range(1000000) AS t(value); extended_description: | - `gpudb` adds GPU-accelerated aggregate operators that DuckDB transparently - dispatches to: + `gpudb` adds drop-in aggregate functions: - * `gpu_sum(BIGINT)` — GPU SUM - * `gpu_min(BIGINT)` — GPU MIN - * `gpu_max(BIGINT)` — GPU MAX + * `gpu_sum(BIGINT | DOUBLE)` + * `gpu_min(BIGINT | DOUBLE)` + * `gpu_max(BIGINT | DOUBLE)` - On NVIDIA hardware (CUDA backend, sm_70+) these run on the device with - PCIe-amortized transfer. On Apple Silicon (Metal backend, M1+) they use - the unified memory architecture so transfer cost is zero. + Smaller integer types (`INTEGER`, `SMALLINT`, `TINYINT`) widen implicitly + to the `BIGINT` overload. All three work in plain aggregation, `GROUP BY`, + and window frames (`OVER ()`, `OVER (ORDER BY ...)`, + `OVER (PARTITION BY ... ORDER BY ...)`), and match native DuckDB + semantics: empty input and all-NULL groups return SQL `NULL` (v0.2.0), + and the `DOUBLE` min/max overloads use the same NaN-aware total order as + native DuckDB — NaN sorts greatest (v0.3.0). - **v0.1.3** ships a hybrid Metal GROUP BY that auto-dispatches between two - paths per query: a 32K-partition slot-lock hash aggregate (sweet spot at - 1024 ≤ unique ≤ 16M) and an optimized multi-pass radix sort (very low or - very high cardinality). This flipped TPC-H SF10 GROUP BY l_orderkey from - CPU 1.78× faster (v0.1.2) to Metal 1.30× faster. + **v0.3.0** replaces the buffered v0.1.x aggregate path with streaming + accumulator states. End-to-end queries through the SQL aggregates now run + at parity with native DuckDB (1.00–1.20× on rewritten TPC-H queries), + where v0.1.x could be substantially slower on the same queries. DuckDB + feeds aggregates pre-grouped 2048-row chunks, so the SQL aggregate path + deliberately streams running accumulators instead of round-tripping + chunks through the GPU. - A hybrid CPU/GPU planner picks the backend that wins for each cardinality - regime — this addresses the open problem from Rosenfeld/Breß CSUR 2022 - and Cao SIGMOD 2024. + The GPU backends (CUDA on NVIDIA sm_70+, Metal on Apple Silicon M1+) + power the operator-level engine and benchmark tooling that ship in the + source tree, where whole columns are resident on the device. Headline + operator-level results, all traceable to rows in the project's + append-only BENCHMARK.md with reproduction steps: - Apple Silicon (M4 Max) vs DuckDB CPU 16-thread (the actual CLI default, - not single-thread). All cells trace to BENCHMARK.md rows: - * TPC-H SF10 multi-agg fusion l_quantity: Metal 25.5× - * TPC-H SF10 multi-agg fusion l_extendedprice: Metal 22.0× - * TPC-H SF10 multi-agg fusion l_orderkey: Metal 9.7× - * 1B int64 SUM HOT (resident column): Metal 2.6× - * 500M × 1M GROUP BY synthetic: Metal 3.4× - * 1B × 1M GROUP BY synthetic: Metal 3.2× - * TPC-H SF10 GROUP BY l_extendedprice (1.35M unique): Metal 3.9× - * TPC-H SF10 GROUP BY l_orderkey (15M unique): Metal 1.30× - * TPC-H SF1 GROUP BY l_orderkey (1.5M unique): Metal 1.40× - * Honest loss documented: TPC-H SF10 GROUP BY l_quantity (50 unique): - CPU 14× faster (structural — L1-resident hash table on CPU) + * Apple M4 Max vs DuckDB CPU 16-thread: multi-aggregate fusion over + TPC-H SF10 columns 9.7×–25.5×; SF10 GROUP BY at 1.35M unique keys + 3.9×; honest loss documented at 50 unique keys (CPU 14× faster, + structural). + * NVIDIA RTX 4090: resident-column SUM ~17.9×; GROUP BY 50M rows × + 10M unique groups 13.7× (vs single-thread CPU baseline). - NVIDIA RTX 4090 (CUDA, vs single-thread CPU baseline): - * Peak SUM ratio: ~22.8× (size-dependent, resident column) - * GROUP BY 50M rows × 10M unique groups: 21.8× - * TPC-H SF1 GROUP BY (6M × 1.5M unique): 3.56× (re-bench post-launch) - - The extension auto-selects the best backend at load time. If no GPU is - available it falls back cleanly to the CPU implementation — same SQL - surface either way. Community-extension binaries are built without the - CUDA toolchain for now (CPU fallback on Linux; full Metal on Apple - Silicon); build from source for the CUDA backend. Honest benchmark - notes (where GPU loses to CPU) are documented in the project's - BENCHMARK.md (append-only log). + Community-extension binaries are built without the CUDA toolchain for + now (full Metal path on Apple Silicon; clean CPU fallback on Linux); + build from source for the CUDA backend. If no GPU is available the + extension falls back cleanly — same SQL surface either way. Source: https://github.com/singhpratech/duckdbgpumetaldbram @@ -83,15 +75,15 @@ docs: Falls back to CPU otherwise. known_limitations: | - * Float64 SUM on Apple Silicon falls back to host loop (Apple GPUs - do not implement IEEE-754 doubles in MSL); same correctness, no - GPU speedup for that one type. - * GROUP BY currently supports BIGINT keys + BIGINT SUM; broader - type coverage planned in v0.2. - * Window functions: SUM OVER (), SUM OVER (ORDER BY), and - SUM OVER (PARTITION BY ... ORDER BY ...) all supported and - verified against native sum() in the SQL test suite. - * GROUP BY at very low cardinality (≤ 1K unique): CPU dominates - structurally (L1-resident hash). Auto-dispatch routes these to the - radix-opt path; for the bottom of the curve CPU still wins (e.g., - TPC-H SF10 l_quantity at 50 unique groups: CPU 14× faster). + * `gpu_sum(BIGINT)` wraps on int64 overflow where native `sum()` + promotes to `HUGEINT`. + * `HUGEINT`, `DECIMAL`, and `FLOAT` arguments implicitly cast to the + `DOUBLE` overload — values beyond 2^53 lose precision where native + aggregates are exact, and the result type is `DOUBLE`. `VARCHAR` + arguments are a binder error (native `min`/`max` compare + lexicographically). Use native aggregates where those types matter. + * Apple GPUs do not implement IEEE-754 doubles in MSL; operator-level + f64 work on Metal runs on host. This does not affect the SQL + aggregate path. + * `GPUDB_FORCE_BACKEND` no longer affects the SQL aggregate path as of + v0.3.0 (operator-level tools still honor backend selection).