Dispatch scaled softmax on GPU: output[row,j] = softmax(input[row,j] * scale). If seq_len > 0, applies causal mask.
(
&self,
input: &Tensor,
rows: usize,
cols: usize,
scale: f32,
seq_len: usize,
)
| 883 | /// Dispatch scaled softmax on GPU: output[row,j] = softmax(input[row,j] * scale). |
| 884 | /// If seq_len > 0, applies causal mask. |
| 885 | fn dispatch_softmax( |
| 886 | &self, |
| 887 | input: &Tensor, |
| 888 | rows: usize, |
| 889 | cols: usize, |
| 890 | scale: f32, |
| 891 | seq_len: usize, |
| 892 | ) -> Result<Tensor> { |
| 893 | let dtype = input.dtype(); |
| 894 | let shape = input.shape().clone(); |
| 895 | let n = input.elem_count(); |
| 896 | |
| 897 | let buf_in = self.get_or_upload(input)?; |
| 898 | let buf_out = self.alloc_output(n); |
| 899 | |
| 900 | let result = self.dispatch_compute( |
| 901 | "scaled_softmax", |
| 902 | &[buf_in.buffer, self.dummy_buf.buffer, buf_out.buffer], |
| 903 | &buf_out, |
| 904 | n, |
| 905 | &[rows as u32, cols as u32, scale.to_bits(), seq_len as u32], |
| 906 | (rows as u32, 1, 1), // one workgroup per row |
| 907 | ); |
| 908 | |
| 909 | let tensor = Self::from_f32_vec(result, shape.dims(), dtype)?; |
| 910 | self.cache_activation(tensor.id(), buf_out); |
| 911 | Ok(tensor) |
| 912 | } |
| 913 | |
| 914 | // ── GPU matmul ─────────────────────────────────────────────────── |
| 915 |
no test coverage detected