onnxruntime
50c95100 - webgpu: Add session-level buffer pool for graph capture reuse (#28761)

Commit
28 days ago
webgpu: Add session-level buffer pool for graph capture reuse (#28761) ## Summary - Introduces `SessionBufferPool` that lets a session hold on to retired generator buffer caches (storage + uniform) and seed them into newly created generators. - Adds provider option `ep.webgpuexecutionprovider.sessionBufferPoolGenerations` to bound how many generations of retired buffers are kept (default `1`; set to `0` to disable). - Wires the WebGPU EP to donate a retiring `BufferManager`'s cache into the pool and absorb pooled buffers when a new `BufferManager` is created for the next generator. - The pool is only created when graph capture is enabled AND the option is > 0, so non-graph-capture sessions are unaffected. ## Motivation With graph capture enabled, each generator owns its own per-graph `BufferManager`. When the generator is destroyed (e.g., per-request in GenAI), the entire buffer cache is thrown away and the next generator must reallocate all storage and uniform buffers from scratch, increasing cold-start latency and GPU memory churn. By keeping a small pool of recently-retired buffer slots at the session level, the next generator can reuse them and skip reallocation entirely after the first cycle. ## Test plan - [x] Build ORT (Windows, D3D12) with ``--use_webgpu`` — clean build. - [x] ``lintrunner -a`` reports no lint issues. - [x] Verified end-to-end with GenAI on phi4 + WebGPU graph capture using two scripts: - ``verify_multi_gen.py``: sequential and overlapping generators all produce matching, coherent output. - ``verify_max_length_change.py``: generators with varying ``max_length`` all coherent. - [x] With diagnostic prints (since removed), confirmed that after the first generator donates buffers, subsequent generators report ``storage hits=171 misses=0, uniform hits=296 misses=0``, i.e., the pool actually engages and eliminates reallocation. ## Notes - Pairs with a GenAI-side change that invokes ``SessionReleaseCapturedGraph`` from ``State::~State()`` so the per-graph ``BufferManager`` is actually released and its buffers reach the pool.
Author
Parents
Loading