[GPU]Performance optimizing to RMS and MVN#36747
Conversation
…MVN dispatching & kernel algorithm, and improving HW utilization to close to 100% bandwidth, clears 2 Omni targets.
There was a problem hiding this comment.
Pull request overview
This PR updates the Intel GPU kernel selector + OpenCL kernels for MVN and RMS “bfyx_opt” implementations to use a more generalized workgroup (LWS) selection strategy and adaptive register-caching vs reread behavior, aiming to improve throughput across varying sequence widths and dynamic shapes.
Changes:
- Generalized LWS selection (power-of-two, ~8 elements per work-item) for MVN and RMS selectors.
- Added JIT-controlled caching vs reread behavior (
*_STACK_SIZE,*_REREAD_INPUT) and new kernel code paths (vectorized IO for RMS; fused mean/variance accumulation for MVN). - Added RMS subgroup-aware reduction modes (
ONE_SUBGROUP_ROW/MULTI_SUBGROUP_ROW) and revised SLM usage.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/plugins/intel_gpu/src/kernel_selector/kernels/rms/rms_kernel_bfyx_opt.cpp | Generalized RMS dispatch/JIT constants (LWS selection, stack sizing, reread flags, subgroup-row mode flags). |
| src/plugins/intel_gpu/src/kernel_selector/kernels/mvn/mvn_kernel_bfyx_opt.cpp | Generalized MVN dispatch/JIT constants (LWS selection, stack sizing, reread flags, dynamic-vs-static JIT control). |
| src/plugins/intel_gpu/src/kernel_selector/cl_kernels/rms_gpu_bfyx_opt.cl | RMS kernel refactor: vectorized reads/writes, subgroup-row reduction variants, cache-or-reread input path. |
| src/plugins/intel_gpu/src/kernel_selector/cl_kernels/mvn_gpu_bfyx_opt.cl | MVN kernel refactor: single-pass sum+sumSq accumulation, cache-or-reread input path, updated normalization math. |
| float red_sq = work_group_reduce_add(my_sq); | ||
| float my_variance = red_sq / data_set_size - my_sum_mean * my_sum_mean; | ||
| # if defined EPS_OUTSIDE_SQRT |
| if (is_decimal_number(data_set_size)) { | ||
| const size_t static_data_set_size = std::stoul(data_set_size); | ||
| const size_t lws = get_generalized_lws(static_data_set_size, dispatchData.maxSlmSize); | ||
| const size_t required_stack = get_stack_size(static_data_set_size, lws); |
| MakeJitConstant("DATA_SIZE", data_size), | ||
| MakeJitConstant("LWS", lws_0), | ||
| MakeJitConstant("SLM_SIZE", dispatchData.maxSlmSize), | ||
| MakeJitConstant("STACK_SIZE", stack_size) | ||
| MakeJitConstant("STACK_SIZE", stack_size), | ||
| MakeJitConstant("SUBGROUP_BLOCK_SIZE", 8), |
e-ddykim
left a comment
There was a problem hiding this comment.
Looks good to me. Please check my comments.
| uses_runtime_lws = false; | ||
| } | ||
| jit.AddConstants({ | ||
| MakeJitConstant("IS_DYNAMIC", uses_runtime_lws), |
There was a problem hiding this comment.
IS_DYNAMIC is already defined here.
This could trigger a macro redefinition error in a debug build. If overriding the existing value is intended, please consider removing the definition from kernel_base.
| #if SUBGROUP_BLOCK_SIZE == 1 | ||
| #define BLOCK_READ(ptr, offset) DT_INPUT_BLOCK_READ(ptr, offset) | ||
| #define BLOCK_WRITE(ptr, offset, val) DT_OUTPUT_BLOCK_WRITE(ptr, offset, val) | ||
| #define ACC_TYPE ACCUMULATOR_TYPE | ||
| #define TO_ACC_TYPE(x) TO_ACCUMULATOR_TYPE(x) | ||
| #define OUTPUT_VEC_TYPE OUTPUT_TYPE | ||
| #else |
There was a problem hiding this comment.
SUBGROUP_BLOCK_SIZE is always 8 now. Please check whether these dead codes can be safely removed.
p-durandin
left a comment
There was a problem hiding this comment.
Looks like extension of #36587
@ceciliapeng2011 please address @alvoron comments here
Performance optimize to mvn_gpu_bfyx_opt and rms_gpu_bfyx_opt kernels.
Details:
Implemented a generalized MVN scheduling rule that selects the largest power-of-two workgroup size while keeping about 8 normalized elements per work-item, replacing shape-specific tuning. Added adaptive register-caching with automatic fallback to reread mode when stack pressure is high, so the kernel keeps high bandwidth efficiency across varying sequence widths and dynamic shapes.
Implemented the same generalized workgroup selection strategy for RMS, with subgroup-aware reduction paths: one-subgroup rows bypass SLM/barriers, while multi-subgroup rows use lightweight partial reduction in SLM. Added adaptive cache-or-reread behavior plus vectorized IO fast paths, improving robustness and throughput for generalized (non-bucketed) shapes.
Tickets:
AI Assistance: