Run a complete diffusion step, managing solver order automatically. `step_idx`: 0-based index into timesteps `x0_buffer`: mutable buffer of previous x0 predictions (caller maintains) `ts_buffer`: mutable buffer of corresponding timesteps (caller maintains) Returns the updated sample.
(
&self,
v_pred: &Tensor,
step_idx: usize,
sample: &Tensor,
x0_buffer: &mut Vec<Tensor>,
ts_buffer: &mut Vec<usize>,
)
| 164 | /// |
| 165 | /// Returns the updated sample. |
| 166 | pub fn step( |
| 167 | &self, |
| 168 | v_pred: &Tensor, |
| 169 | step_idx: usize, |
| 170 | sample: &Tensor, |
| 171 | x0_buffer: &mut Vec<Tensor>, |
| 172 | ts_buffer: &mut Vec<usize>, |
| 173 | ) -> Result<Tensor> { |
| 174 | let t = self.timesteps[step_idx]; |
| 175 | let num_steps = self.timesteps.len(); |
| 176 | |
| 177 | // Convert v-prediction to x0 |
| 178 | let x0 = self.convert_v_to_x0(v_pred, t, sample)?; |
| 179 | |
| 180 | // Target: next timestep, or final_sigma=0 (perfectly clean) for last step |
| 181 | let is_final = step_idx + 1 >= num_steps; |
| 182 | let next_t = if !is_final { |
| 183 | Some(self.timesteps[step_idx + 1]) |
| 184 | } else { |
| 185 | None // final_sigmas_type="zero": target sigma=0, alpha=1 |
| 186 | }; |
| 187 | |
| 188 | // Use first order for: first step, last step (lower_order_final with final_sigma=0) |
| 189 | let use_first_order = step_idx == 0 |
| 190 | || is_final |
| 191 | || x0_buffer.is_empty(); |
| 192 | |
| 193 | let result = if is_final { |
| 194 | // final_sigmas_type="zero": last step returns x0 directly |
| 195 | // (sigma_t=0 means x_t = 0*sample - 1*(0-1)*x0 = x0) |
| 196 | x0.clone() |
| 197 | } else if use_first_order { |
| 198 | self.first_order_update(&x0, t, next_t.unwrap(), sample)? |
| 199 | } else { |
| 200 | let m1 = x0_buffer.last().unwrap(); |
| 201 | let s1 = *ts_buffer.last().unwrap(); |
| 202 | self.second_order_update(&x0, m1, t, s1, next_t.unwrap(), sample)? |
| 203 | }; |
| 204 | |
| 205 | // Update buffers (keep only last entry for second-order) |
| 206 | x0_buffer.clear(); |
| 207 | x0_buffer.push(x0); |
| 208 | ts_buffer.clear(); |
| 209 | ts_buffer.push(t); |
| 210 | |
| 211 | Ok(result) |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | // Keep the old name as an alias for backward compatibility |