@@ -58,11 +58,22 @@ class LoraRefBase : public KernelGenerator {
5858 jit_constants.add (make_type_jit_constants (" ACCUMULATOR" , params.get_input_layout (0 ).data_type ));
5959 jit_constants.add (make_type_jit_constants (" STATE" , params.get_input_layout (2 ).data_type ));
6060
61- jit_constants.make (" MAX_LORA_RANK" , 256 );
62-
6361 LayoutJitter alpha_state_dims (params.input_layouts [3 ], params.in_port_to_shape_info_offset .at (3 ));
6462 jit_constants.make (" LORA_RANK" , alpha_state_dims.dim (ChannelName::FEATURE ));
6563
64+ // MAX_LORA_RANK is the compile-time size/stride of the kernels' SLM buffers
65+ // (fma_buff/reduce/tmp_buf, and MAX_GEMMA_N = MAX_LORA_RANK * LORA_COUNT). The LoRA
66+ // rank is a static model property and every access stays within [0, LORA_RANK), so
67+ // size the buffers to the actual rank (rounded up to the subgroup size, capped at the
68+ // historical 256 upper bound) instead of always reserving 256. This keeps the SLM
69+ // footprint proportional to the rank: it avoids local-memory overflow on small-SLM
70+ // iGPUs without a matrix engine (clBuildProgram CL_OUT_OF_RESOURCES) and improves
71+ // occupancy on all devices, while leaving MAX_GEMMA_SGK / dispatch unchanged.
72+ size_t actual_lora_rank = extract_channel (ChannelName::FEATURE , params.input_layouts [3 ]);
73+ size_t mlr_subgroup = params.get_input_layout (0 ).data_type == ov::element::f16 ? 16ul : 8ul ;
74+ size_t max_lora_rank = std::min<size_t >(256ul , round_up_to (std::max<size_t >(actual_lora_rank, 1ul ), mlr_subgroup));
75+ jit_constants.make (" MAX_LORA_RANK" , max_lora_rank);
76+
6677 jit_constants.make (" LORA_COUNT" , get_lora_count (params));
6778
6879 return jit_constants;
0 commit comments