Skip to content

feat: migrate remaining ListOffsetArray CUDA kernels to cuda.compute - #4483

Open
ianna wants to merge 15 commits into
scikit-hep:mainfrom
ianna:ianna/cuda-compute-listoffsetarray
Open

ianna wants to merge 15 commits into
scikit-hep:mainfrom
ianna:ianna/cuda-compute-listoffsetarray

Conversation

@ianna

@ianna ianna commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Migrate five ListOffsetArray CUDA kernel families from RawKernel dispatch to cuda.compute: flatten_offsets, toRegularArray, rpad_axis1, drop_none_indexes, and reduce_nonlocal_outstartsstops_64. Remove their raw registrations and sources, preserving canonical CPU errors, partial output, untouched buffer capacity, and current-stream execution.

The deprecated reduce_local_nextparents_64 converter has no live layout callers and is excluded from this migration and its performance gate. Its original raw source, registrations, canonical specification, existing cases, and CPU ABI remain available. No replacement or new converter tests are included.

The nonlocal-range implementation preserves interior holes and uses a host-known segment-width hint. Materialize positions before segmented reduction to avoid the stateful iterator path implicated in launch failures. A fresh-process CUDA smoke step localizes nonlocal-range failures.

Align the drop_none_indexes reference with the bounds check already present in C++, document contracts, add canonical cases, regenerate signatures/tests, and provide focused CPU/GPU checks and benchmarks. Padding widens narrow input offsets on-device before invoking the canonical matching-type length kernel, and its scan forwards the current CuPy stream.

Validation: 257 focused local checks pass, including padding across signed/unsigned offset widths, empty/nonzero-origin layouts, typetracer forms, and scan stream forwarding. Lint, formatting, generation, and diff checks pass. Actual GPU confirmation and comparative performance measurements remain pending; no speedup is claimed.

Independent main-based branch. Related work: #4464 (nonlocal ranges), #4481/#4484 (returned-KernelError test adapter sets must be combined on merge), #4482 (segment-size-hint synchronization), and #4461 (unused prototypes). Tracking issue: #4463.

No C++ implementation, dependency, awkward-cpp version, or dependency-pin changes.

AI assistance was used for implementation, diagnosis, and validation.

@github-actions github-actions Bot added the type/feat PR title type: feat (set automatically) label Oct 25, 2026
@ianna

ianna commented Oct 25, 2026

Copy link
Copy Markdown
Member Author

partially fixes #3793

@codecov

codecov Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.58590% with 129 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.26%. Comparing base (d5c2812) to head (2cef587).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/awkward/_connect/cuda/_listoffsetarray.py 52.44% 68 Missing ⚠️
src/awkward/_connect/cuda/_prepared_gather.py 79.46% 61 Missing ⚠️

❌ Your patch check has failed because the patch coverage (71.58%) is below the target coverage (98.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
Files with missing lines Coverage Δ
src/awkward/_backends/cupy.py 97.72% <ø> (ø)
src/awkward/_connect/cuda/__init__.py 91.89% <ø> (ø)
src/awkward/_connect/cuda/_compute.py 47.08% <100.00%> (+1.67%) ⬆️
src/awkward/_kernels.py 95.80% <100.00%> (ø)
src/awkward/contents/listoffsetarray.py 89.31% <100.00%> (+0.01%) ⬆️
src/awkward/_connect/cuda/_prepared_gather.py 79.46% <79.46%> (ø)
src/awkward/_connect/cuda/_listoffsetarray.py 52.44% <52.44%> (ø)

... and 2 files with indirect coverage changes

@github-actions

Copy link
Copy Markdown
Contributor

The documentation preview is ready to be viewed at https://preview.awkward-array.org/PR4483/

@ianna

ianna commented Oct 26, 2026

Copy link
Copy Markdown
Member Author

GPU validation and performance update for 2cef587a8822ec7e689d733d8d0079e1a848fd26, compared with baseline 7c403344b574980bbb020f98dc2a7b1bd5f80324 on an NVIDIA A100-PCIE-40GB (Della).

Canonical parity passed and the kernel measurements completed. The benchmark harness is in ianna/awkward-matrix#1. JIT warmup is excluded; timings are unprofiled medians, with trace/allocation measurements collected in separate passes.

Completed public operations

These measurements include the public call, result construction, stream completion, and deferred-error draining on both revisions. CPU reference checks and input preparation are outside timing. Five repeats of 50 calls follow 20 warmup calls per workload.

Public workload Baseline completed µs Candidate completed µs Candidate / baseline
ak.to_regular, 32 × 8 910.226 945.912 1.039
ak.to_regular, 4096 × 8 942.441 1009.583 1.071
ak.to_regular, 32 × 4096 803.139 837.779 1.043
ak.drop_none, 32 × 8 2533.539 2542.877 1.004
ak.drop_none, 4096 × 8 2543.619 2560.801 1.007
ak.drop_none, 32 × 4096 3475.740 2652.975 0.763
Irregular ak.to_regular, 32 × 8 940.758 927.653 0.986
Irregular ak.to_regular, 4096 × 8 950.641 978.223 1.029
Irregular ak.to_regular, 32 × 4096 812.331 804.542 0.990

Long-list public drop_none completes about 24% faster; short-list completion stays within 1%. Valid to_regular is 4–7% slower, adding approximately 35–67 µs. For each irregular workload, all 250 measured baseline errors surfaced during the final drain, while all 250 candidate errors surfaced during the public call.

Kernel-level results and tradeoffs

The separate kernel comparison already includes completion/error draining in total_us; the public benchmark adds the surrounding operation and metadata/result construction.

  • flatten_offsets: total latency is within approximately 2% of baseline across the measured shapes, with no added synchronization or temporary allocations.
  • Nonlocal ranges: short-group total latency improves by 37–39%. Long groups are approximately 4% slower after restoring parallel reduction, resolving the earlier serial-scan regression.
  • Long-list drop_none_indexes: total latency improves from 1168.250 to 285.074 µs (about 76% faster). Pool temporary peak grows from 2560 to 11776 bytes. Short-list total latency stays within 4% of baseline.
  • toRegularArray: 64-row validation chunks reduce pool temporary peaks to 512 bytes for 32 rows and 1536 bytes for 4096 rows (the earlier candidate used 55296 bytes at 4096 rows). Kernel total latency remains approximately 31–32% above baseline for 32 rows and 70% above baseline for 4096 rows.
  • drop_none_indexes and toRegularArray each retain one synchronization and an 8-byte DToH status read to preserve immediate canonical errors. The baseline kernels defer errors. Long-list drop-none host-call latency remains higher despite faster completion.

All measured public cases are below the public report's 10% completed-latency regression threshold. The separate kernel review gate still fails for the remaining toRegularArray regressions and long-list drop-none host latency; the public results do not override that gate. These results support reviewing the gains, immediate-error behavior, and remaining costs explicitly rather than treating the migration as a blanket performance improvement. The crossover for tiled drop-none counting remains a metadata-based heuristic; mixed-length lists and additional GPUs still need benchmarking.

Benchmark runs: kernel comparison 16263457; completed public operations 16265084.

This summary and the benchmark tooling were prepared with AI assistance; the reported numbers come from the GPU runs supplied by Ianna.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/feat PR title type: feat (set automatically)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant