Repository navigation
madspace GPU runtime: histogram scratch, matrix element stream, rank-4 kernels, view rank check - #256
Merged
Merged
Conversation
…4 kernels, view rank check Found by the review that followed the HIP cut crash (#254), same class: silent or lucky on one platform, a fault on another. - op_histogram (GPU): reduce_by_key writes one key per bin plus the underflow and overflow bins, n_bins + 2, into a scratch buffer of n_bins: two doubles past its end at every histogram fill. - op_matrix_element (GPU): output_keys had output_count entries but the stream key was written at index output_count (heap overflow), and the call passed output_count, so umami never got the stream: every matrix element has run on the default stream since ffb1610, which meant to pass it. Now passed, so the matrix element runs in stream order with the rest of the function. (The madmatrix GPU template only puts all of its work on the given stream since the companion madmatrix PR; with madspace's own, blocking, streams the older libraries stay correct.) The unused extra input key is dropped. - run_kernel (GPU), rank 4: the bound check omitted size3, so only the first slice of the last dimension was computed (elementwise kernels, copies, zero and add-in-place of rank-4 tensors). - Tensor::view / flat_view: a view of more dimensions than the tensor has now throws instead of reading strides and shapes that were never set (the mechanism of the cut kernel crash); Sizes is zero-initialised and push_back bounded. Tests: madspace/tests/test_histogram_op.py (CPU semantics of the histogram: underflow, bins, overflow, per-event range); GPU CI job madspace_ops (madspace_ops_gpu.sh, madspace_checks.py) runs the histogram and a rank-4 elementwise kernel on the GPU runtime (inputs as torch device tensors) and compares them with the CPU runtime. Locally: the madspace suite (1722 passed, 11 skipped, no view rank error) and mg7 CPU runs of p p > j j and p p > e+ e- j.
oliviermattelaer
temporarily deployed
to
ceci-gpu
October 10, 2026 10:57 — with
GitHub Actions
Inactive
oliviermattelaer
temporarily deployed
to
ceci-gpu
October 10, 2026 11:04 — with
GitHub Actions
Inactive
torch imports typing_extensions, which EasyBuild 2024a provides through EBPYTHONPREFIXES (Python-bundle-PyPI): only the python3 of the modules reads it, not a venv made from it (manneback and lemaitre4: No module named 'typing_extensions'). madspace has no dependency and was built with that same interpreter.
oliviermattelaer
temporarily deployed
to
ceci-gpu
October 10, 2026 11:17 — with
GitHub Actions
Inactive
oliviermattelaer
temporarily deployed
to
ceci-gpu
October 10, 2026 11:17 — with
GitHub Actions
Inactive
Found by the new madspace_ops check on lemaitre4 (GPU vs CPU up to 16% in a bin): op_histogram sorted the bin indices with the weights, then sorted the now sorted indices again with the squared weights, which therefore stayed in the event order: each bin summed the squared weights of the wrong events (its statistical error), while the totals and the values were right. One sort_by_key now carries both arrays (zip iterator). madspace_checks.py reports the values and the squared values separately, and skips (visibly, not a failure) when the torch of the modules has no GPU support (manneback: the default PyTorch module is the CPU build).
oliviermattelaer
temporarily deployed
to
ceci-gpu
October 10, 2026 11:25 — with
GitHub Actions
Inactive
oliviermattelaer
temporarily deployed
to
ceci-gpu
October 10, 2026 11:25 — with
GitHub Actions
Inactive
theoheimel
approved these changes
Oct 12, 2026
Contributor
There was a problem hiding this comment.
The fixes look good.
What I would change (but that's work for a separate PR): instead of adding GPU-specific unit tests for madspace as done here, we should move the madspace unit tests from numpy to torch (which we already use for some tests anyways), so that the same tests run on CPU and GPU, and then run the full madspace unit test suite on CUDA and HIP through the new GPU CI.
…untime-fixes GPU CI: keep both new jobs, madspace_ops (this branch) and interference (main); stop_runner needs both.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found by the review that followed the HIP cut crash (#254). These bugs are of the same class: silent or lucky on one platform, a fault on another.
Fixes
op_histogram(GPU):reduce_by_keywritesn_bins + 2keys (the bins, plus the underflow and overflow bins) into a scratch buffer ofn_bins, so every histogram fill wrote two doubles past its end.op_matrix_element(GPU): heap overflow, and the stream was never passed.output_keyshadoutput_countentries, but the stream key was written at indexoutput_count.output_count, so umami never received madspace's stream. Every matrix element has run on the default stream since ffb1610, which meant to pass it (it moved the stream from an input key to an output key).run_kernel(GPU), rank 4: the bound check omittedsize3, so only the first slice of the last dimension was computed. This affects elementwise kernels, copies, zero and add-in-place of rank-4 tensors (e.g. PDF coefficient grids).op_histogram(GPU), squared values, found by the newmadspace_opscheck on lemaitre4 (GPU vs CPU up to 16% in a bin). The bin indices were sorted with the weights, then the already sorted indices were sorted again with the squared weights, which therefore stayed in event order. Each bin summed the squared weights of the wrong events, so the per-bin statistical errors of GPU histograms were wrong while the values and totals were right. Onesort_by_keynow carries both arrays (zip iterator).Tensor::view/flat_view: a view with more dimensions than its tensor now throws, instead of reading strides and shapes that were never set. That was the mechanism of the cut-kernel crash.Sizesis now zero-initialised andpush_backis bounded.Merge order with #255. #255 (madmatrix GPU, stacked on #244) makes the madmatrix GPU template put all of its work on the stream it is given; before it, some of the work went to the default stream.
Not in this PR:
Tests
madspace/tests/test_histogram_op.py: CPU semantics of the histogram (underflow, bins, overflow, per-event range).madspace_ops(madspace_ops_gpu.sh,madspace_checks.py) runs the histogram and a rank-4 elementwise kernel (x + xon batch × 2 × 3 × 4) on the GPU runtime and compares them with the CPU runtime. The inputs are torch device tensors, so torch must be importable after the modules are loaded; otherwise the job fails and says so.p p > j jandp p > e+ e- j;madspace_checks.pywith a numpy stand-in for torch.x + x: 0 of 98304 elements differ.madspace_opsis skipped: the defaultPyTorchmodule there (2.6.0-foss-2024a) is the CPU build;p p > t t~andp p > j jall pass.