1use anyhow::Result;
8use spark_runtime::gpu::{DevicePtr, GpuBackend};
9use spark_runtime::kv_cache::PagedKvCache;
10
11use super::Qwen3SsmLayer;
12use super::ple_seq::ple_seq_state;
13use crate::layer::{ForwardContext, GdnPrefillBuffers, LayerState, TransformerLayer};
14
15impl TransformerLayer for Qwen3SsmLayer {
16 fn gdn_woa_stash_seq_floats(&self) -> Option<usize> {
17 self.woa_stash_seq_floats_impl()
18 }
19
20 fn gdn_woa_bind(&self, flag: DevicePtr, stash: DevicePtr, seqs: usize) {
21 self.woa_bind_impl(flag, stash, seqs)
22 }
23
24 fn gdn_fold_accepted(
25 &self,
26 gpu: &dyn GpuBackend,
27 h_table: DevicePtr,
28 na_tab: DevicePtr,
29 k_rows: usize,
30 n: usize,
31 stream: u64,
32 ) -> Result<bool> {
33 self.fold_accepted_impl(gpu, h_table, na_tab, k_rows, n, stream)
34 }
35
36 fn as_any_mut(&mut self) -> Option<&mut dyn std::any::Any> {
39 Some(self)
40 }
41
42 fn decode_prestage(
45 &self,
46 token: u32,
47 state: &mut dyn LayerState,
48 gpu: &dyn GpuBackend,
49 stream: u64,
50 ) -> Result<()> {
51 if let Some(ple) = self.ple.as_ref() {
52 let st = ple_seq_state(ple, state, gpu)?;
53 ple.prestage(st, &[token], gpu, stream)?;
54 }
55 Ok(())
56 }
57
58 fn has_aux_state(&self) -> bool {
59 self.ple.is_some()
60 }
61
62 fn decode_graph_unsupported(&self) -> bool {
66 self.ple.is_some()
67 }
68
69 fn snapshot_aux(
70 &self,
71 state: &dyn LayerState,
72 gpu: &dyn GpuBackend,
73 stream: u64,
74 ) -> Result<Option<Vec<u8>>> {
75 let Some(ple) = self.ple.as_ref() else {
76 return Ok(None);
77 };
78 let ssm = state
79 .as_any()
80 .downcast_ref::<crate::layer::SsmLayerState>()
81 .ok_or_else(|| anyhow::anyhow!("PLE host layer state is not SsmLayerState"))?;
82 match ssm.ple.as_ref() {
83 Some(st) => Ok(Some(ple.snapshot_aux(st, gpu, stream)?)),
84 None => Ok(None),
87 }
88 }
89
90 fn restore_aux(
91 &self,
92 state: &mut dyn LayerState,
93 blob: &[u8],
94 gpu: &dyn GpuBackend,
95 stream: u64,
96 ) -> Result<()> {
97 let ple = self
98 .ple
99 .as_ref()
100 .ok_or_else(|| anyhow::anyhow!("restore_aux: no PLE on this layer"))?;
101 let st = ple_seq_state(ple, state, gpu)?;
102 ple.restore_aux(st, blob, gpu, stream)
103 }
104
105 fn decode_prestage_rearm(&self, state: &mut dyn LayerState) {
106 if let Some(ple) = self.ple.as_ref()
107 && let Some(ssm) = state
108 .as_any_mut()
109 .downcast_mut::<crate::layer::SsmLayerState>()
110 && let Some(st) = ssm.ple.as_mut()
111 {
112 ple.rearm(st);
113 }
114 }
115
116 fn decode(
117 &self,
118 hidden: DevicePtr,
119 residual: DevicePtr,
120 state: &mut dyn LayerState,
121 kv_cache: &mut PagedKvCache,
122 seq_len: usize,
123 block_table: &mut Vec<u32>,
124 disk_block_ids: &mut Vec<u32>,
125 disk_last_offloaded_per_layer: &mut Vec<u32>,
126 ctx: &ForwardContext,
127 stream: u64,
128 ) -> Result<()> {
129 if self.hc.is_some() {
130 return self.decode_inner_hc(hidden, state, ctx, stream);
131 }
132 self.decode_inner(
133 hidden,
134 residual,
135 state,
136 kv_cache,
137 seq_len,
138 block_table,
139 disk_block_ids,
140 disk_last_offloaded_per_layer,
141 ctx,
142 stream,
143 )
144 }
145
146 fn decode_batched(
147 &self,
148 hidden: DevicePtr,
149 residual: DevicePtr,
150 num_tokens: usize,
151 state: &mut dyn LayerState,
152 _kv_cache: &mut PagedKvCache,
153 _seq_len: usize,
154 _block_table: &mut Vec<u32>,
155 _disk_block_ids: &mut Vec<u32>,
156 _disk_last_offloaded_per_layer: &mut Vec<u32>,
157 ctx: &ForwardContext,
158 stream: u64,
159 ) -> Result<()> {
160 self.refuse_batched_under_hc("decode_batched")?;
165 self.decode_batched_inner(
166 hidden,
167 residual,
168 num_tokens,
169 super::trait_decode_batched::GdnStates::Single(state),
170 ctx,
171 stream,
172 )
173 }
174
175 fn decode_verify_multi<'a, 'b: 'a>(
176 &self,
177 hidden: DevicePtr,
178 residual: DevicePtr,
179 n_seqs: usize,
180 ks: &[usize],
181 states: &'a mut [&'b mut (dyn LayerState + 'static)],
182 _kv_cache: &mut PagedKvCache,
183 wy_tables: DevicePtr,
184 ctx: &ForwardContext,
185 stream: u64,
186 ) -> Result<()> {
187 self.refuse_batched_under_hc("decode_verify_multi")?;
188 anyhow::ensure!(
189 states.len() == n_seqs && ks.len() == n_seqs,
190 "decode_verify_multi: states/ks/n mismatch"
191 );
192 let num_tokens: usize = ks.iter().sum();
193 self.decode_batched_inner(
194 hidden,
195 residual,
196 num_tokens,
197 super::trait_decode_batched::GdnStates::Multi {
198 states,
199 ks,
200 wy_tables,
201 },
202 ctx,
203 stream,
204 )
205 }
206
207 fn decode_multi_seq<'a, 'b: 'a>(
208 &self,
209 hidden: DevicePtr,
210 residual: DevicePtr,
211 num_seqs: usize,
212 states: &'a mut [&'b mut (dyn LayerState + 'static)],
213 kv_cache: &mut PagedKvCache,
214 seq_lens: &[usize],
215 block_tables: &[Vec<u32>],
216 ctx: &ForwardContext,
217 stream: u64,
218 ) -> Result<()> {
219 if self.hc.is_some() {
220 return self.decode_multi_seq_inner_hc(hidden, num_seqs, states, seq_lens, ctx, stream);
224 }
225 self.decode_multi_seq_inner(
226 hidden,
227 residual,
228 num_seqs,
229 states,
230 kv_cache,
231 seq_lens,
232 block_tables,
233 ctx,
234 stream,
235 )
236 }
237
238 fn prefill(
239 &self,
240 hidden: DevicePtr,
241 residual: DevicePtr,
242 num_tokens: usize,
243 state: &mut dyn LayerState,
244 kv_cache: &mut PagedKvCache,
245 seq_len_start: usize,
246 block_table: &mut Vec<u32>,
247 disk_block_ids: &mut Vec<u32>,
248 disk_last_offloaded_per_layer: &mut Vec<u32>,
249 kv_write_start: usize,
250 ctx: &ForwardContext,
251 stream: u64,
252 ) -> Result<()> {
253 if self.hc.is_some() {
257 return self.prefill_inner_hc(hidden, num_tokens, state, seq_len_start, ctx, stream);
258 }
259 self.prefill_inner(
260 hidden,
261 residual,
262 num_tokens,
263 state,
264 kv_cache,
265 seq_len_start,
266 block_table,
267 disk_block_ids,
268 disk_last_offloaded_per_layer,
269 kv_write_start,
270 ctx,
271 stream,
272 )
273 }
274
275 fn is_ssm_layer(&self) -> bool {
276 self.is_ssm_layer_inner()
277 }
278
279 fn prefill_phase1(
280 &self,
281 hidden: DevicePtr,
282 residual: DevicePtr,
283 num_tokens: usize,
284 state: &mut dyn LayerState,
285 kv_cache: &mut PagedKvCache,
286 seq_len_start: usize,
287 block_table: &mut Vec<u32>,
288 disk_block_ids: &mut Vec<u32>,
289 disk_last_offloaded_per_layer: &mut Vec<u32>,
290 kv_write_start: usize,
291 gdn_bufs: &GdnPrefillBuffers,
292 token_offset: usize,
293 ctx: &ForwardContext,
294 stream: u64,
295 ) -> Result<()> {
296 self.prefill_phase1_inner(
297 hidden,
298 residual,
299 num_tokens,
300 state,
301 kv_cache,
302 seq_len_start,
303 block_table,
304 disk_block_ids,
305 disk_last_offloaded_per_layer,
306 kv_write_start,
307 gdn_bufs,
308 token_offset,
309 ctx,
310 stream,
311 )
312 }
313
314 fn prefill_phase1_proj_batched(
315 &self,
316 hidden_stacked: DevicePtr,
317 residual_stacked: DevicePtr,
318 total_tokens: usize,
319 gdn_bufs: &GdnPrefillBuffers,
320 ctx: &ForwardContext,
321 stream: u64,
322 ) -> Result<()> {
323 self.prefill_phase1_proj_batched_inner(
324 hidden_stacked,
325 residual_stacked,
326 total_tokens,
327 gdn_bufs,
328 ctx,
329 stream,
330 )
331 }
332
333 fn prefill_phase1_conv1d_one(
334 &self,
335 state: &mut dyn LayerState,
336 token_offset: usize,
337 len: usize,
338 gdn_bufs: &GdnPrefillBuffers,
339 ctx: &ForwardContext,
340 stream: u64,
341 ) -> Result<()> {
342 self.prefill_phase1_conv1d_one_inner(state, token_offset, len, gdn_bufs, ctx, stream)
343 }
344
345 fn prefill_phase1_l2_batched(
346 &self,
347 total_tokens: usize,
348 gdn_bufs: &GdnPrefillBuffers,
349 ctx: &ForwardContext,
350 stream: u64,
351 ) -> Result<()> {
352 self.prefill_phase1_l2_batched_inner(total_tokens, gdn_bufs, ctx, stream)
353 }
354
355 fn prefill_gdn_full(
356 &self,
357 state: &mut dyn LayerState,
358 gdn_bufs: &GdnPrefillBuffers,
359 ctx: &ForwardContext,
360 stream: u64,
361 ) -> Result<()> {
362 self.prefill_gdn_full_inner(state, gdn_bufs, ctx, stream)
363 }
364
365 fn prefill_gdn_full_batched(
366 &self,
367 h_state_ptrs: DevicePtr,
368 gdn_bufs: &GdnPrefillBuffers,
369 batch_size: u32,
370 chunk_len: u32,
371 ctx: &ForwardContext,
372 stream: u64,
373 ) -> Result<()> {
374 self.prefill_gdn_full_batched_inner(
375 h_state_ptrs,
376 gdn_bufs,
377 batch_size,
378 chunk_len,
379 ctx,
380 stream,
381 )
382 }
383
384 fn prefill_gdn_full_batched_fla_varlen(
385 &self,
386 h_state_ptrs: DevicePtr,
387 gdn_bufs: &GdnPrefillBuffers,
388 batch_size: u32,
389 cu_seqlens: DevicePtr,
390 max_num_chunks: u32,
391 total_nt: usize,
392 max_seqlen: u32,
393 ctx: &ForwardContext,
394 stream: u64,
395 ) -> Result<bool> {
396 self.prefill_gdn_full_batched_fla_varlen_inner(
397 h_state_ptrs,
398 gdn_bufs,
399 batch_size,
400 cu_seqlens,
401 max_num_chunks,
402 total_nt,
403 max_seqlen,
404 ctx,
405 stream,
406 )
407 }
408
409 fn prefill_phase3(
410 &self,
411 hidden: DevicePtr,
412 residual: DevicePtr,
413 num_tokens: usize,
414 gdn_bufs: &GdnPrefillBuffers,
415 token_offset: usize,
416 ctx: &ForwardContext,
417 stream: u64,
418 ) -> Result<()> {
419 self.prefill_phase3_inner(
420 hidden,
421 residual,
422 num_tokens,
423 gdn_bufs,
424 token_offset,
425 ctx,
426 stream,
427 )
428 }
429
430 fn alloc_state(&self, gpu: &dyn GpuBackend) -> Result<Box<dyn LayerState>> {
431 self.alloc_state_inner(gpu)
432 }
433
434 fn release_state(&self, state: &mut dyn LayerState, gpu: &dyn GpuBackend) -> Result<()> {
441 let Some(ssm) = state
442 .as_any_mut()
443 .downcast_mut::<crate::layer::SsmLayerState>()
444 else {
445 return Ok(());
446 };
447 let Some(mut st) = ssm.ple.take() else {
448 return Ok(());
449 };
450 let Some(ple) = self.ple.as_ref() else {
451 anyhow::bail!("release_state: PLE seq state present but layer has no PLE");
452 };
453 ple.release_seq_state(&mut st, gpu)
454 }
455}