Repository navigation
Core: primitive.benchmark(), warmUp() and kernelLabels(); misc/node_device.mjs for Node scripts - #86
Merged
Merged
Conversation
…evice.mjs for Node scripts
Timing a primitive well (warm up so the GPU is at full clock, time several
executes, label the per-kernel times) was rewritten in every script, and
the one that left out the warm-up made a V100 look 10x slower. Creating a
device in Node had its own pitfalls (keep create()'s result referenced,
timestamp rounding, features, limits), copied in each script.
- BasePrimitive.kernelLabels(): the kernels' labels, in the order of
getTimingResult()'s GPU times (nested primitives included).
- BasePrimitive.warmUp(args, warmMs = 200): back to back, doubling trials
until one execute keeps the GPU busy for 20 ms.
- BasePrimitive.benchmark({ ...executeArgs, warmMs, repeats, trials }):
warm up, time `repeats` executes, return medians per trial, per kernel
with GPU timestamps (else CPU timing).
- misc/node_device.mjs: nodeGPU() and createNodeDevice() (full-resolution
timestamps, instance kept referenced, subgroups and timestamps when
available, the adapter's largest limits, WebGPU globals).
- misc/benchmark_node.mjs: benchmark() over DLDFScan, HierarchicalScan,
OneSweep, Histogram and MultisplitPerm, with --kernels for per-kernel times.
- regression_node.mjs uses primitive.warmUp() (its executes are untimed)
and nodeGPU(); test_wgsl_functions_node.mjs and list_adapters.mjs use
nodeGPU(). Types and docs/timing-strategy.md ("Benchmarking a primitive").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kfNC6id65zEHzuAAH4jtJ
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.
The last item on the "move it into core" list: benchmarking a primitive, and setting up a device in Node.
Why
regression_node.mjs, the MultisplitPerm and histogram benchmark scripts, the sort diagnostic and the paper's bench. The sort diagnostic left out the warm-up, and the V100's idle clock-down made it look 10× slow.create()'s result referenced, or Dawn tears the device down;Core
primitive.kernelLabels(): the kernels' labels, in the order ofgetTimingResult()'s GPU times, nested primitives included.primitive.warmUp(args, warmMs = 200): runs the primitive back to back, doublingtrialsuntil one execute keeps the GPU busy for 20 ms.primitive.benchmark({ ...executeArgs, warmMs, repeats, trials }): warms up, timesrepeatsexecutes, and returns medians per trial, per kernel with GPU timestamps (or CPU timing without them):Node (
misc/, not part of the library:src/also runs in browsers)misc/node_device.mjs:nodeGPU()andcreateNodeDevice(). They give full-resolution timestamps, keep the instance referenced, request subgroups and timestamps when available along with the adapter's largest limits, and set WebGPU's globals.misc/benchmark_node.mjs [primitives] [log2 sizes] [--kernels]:benchmark()over DLDFScan, HierarchicalScan, OneSweep, Histogram and MultisplitPerm. It replaces the one-off benchmark scripts.regression_node.mjsnow usesprimitive.warmUp(), whose executes aren't timed, andnodeGPU().test_wgsl_functions_node.mjsandlist_adapters.mjsusenodeGPU().Checked (lavapipe)
main.list_adaptersandbenchmark_node.mjs: both work. Every primitive is benchmarked, with per-kernel labels that include nested kernels (HierarchicalScan's partials scan, MultisplitPerm's DLDFScan).Independent of #84 and #85.
Generated by Claude Code