fix(gaps): G4 — re-enable all rtx-transformers Phase 2/3 modules (222 compile errors fixed)

Uncommented all deferred modules in lib.rs and fixed API drift across ~60 files in
9 module groups: continual, curriculum, meta, modular, neural_ode, graph, kan,
perceiver, distributed/pipeline_parallelism.

Common patterns fixed across modules:
- Tensor::randn/zeros/ones([a,b]) → (&[a,b], device)? (slice + Result)
- Result<T, TensorError> → .map_err(Into::into)? in TransformerError contexts
- Device by value → &device references
- &Tensor where Tensor expected → .clone()
- tensor.relu()/tanh()/sigmoid() as methods not ops functions
- Tensor arithmetic returning Result: (a + b)? → (a.clone() + b)?
- shape literals → shape.dims() for Shape type
- sum(n) → sum(Some(n)), mean(None) → mean(&[], false)
- i64 indices → usize where required
- backward(x) → backward(x, None)
- Borrow conflicts on self.field resolved by extracting to locals before mut borrow
- BatchingStats private fields → pub(crate)
- TransformerError::Serialization → ::SerializationError
- Add scalar to tensor: (t + 0.1)? → t.add_scalar(0.1)?

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-26 16:08:02 +00:00
co-authored by Claude Sonnet 4.6
parent 448c0a0be5
commit a08adfbf57
106 changed files with 2165 additions and 1897 deletions
@@ -95,29 +95,25 @@ impl Default for SolverStats {
/// Trait for ODE solvers
pub trait ODESolver: Send + Sync {
/// Solve ODE from t0 to t1 with initial condition y0
fn solve<F>(
fn solve(
&self,
ode_func: &F,
ode_func: &dyn ODEFunc,
y0: &Tensor,
t_span: &[f32],
rtol: f32,
atol: f32,
) -> Result<(Tensor, SolverStats)>
where
F: ODEFunc;
) -> Result<(Tensor, SolverStats)>;
/// Take a single integration step
fn step<F>(
fn step(
&self,
ode_func: &F,
ode_func: &dyn ODEFunc,
t: f32,
y: &Tensor,
step_size: f32,
rtol: f32,
atol: f32,
) -> Result<StepResult>
where
F: ODEFunc;
) -> Result<StepResult>;
/// Get solver name for debugging
fn name(&self) -> &'static str;
@@ -139,16 +135,14 @@ impl EulerSolver {
}
impl ODESolver for EulerSolver {
fn solve<F>(
fn solve(
&self,
ode_func: &F,
ode_func: &dyn ODEFunc,
y0: &Tensor,
t_span: &[f32],
_rtol: f32,
_atol: f32,
) -> Result<(Tensor, SolverStats)>
where
F: ODEFunc,
{
if t_span.is_empty() {
return Err(NeuralODEError::InvalidInput("Empty time span".to_string()));
@@ -198,17 +192,15 @@ impl ODESolver for EulerSolver {
Ok((output, stats))
}
fn step<F>(
fn step(
&self,
ode_func: &F,
ode_func: &dyn ODEFunc,
t: f32,
y: &Tensor,
step_size: f32,
_rtol: f32,
_atol: f32,
) -> Result<StepResult>
where
F: ODEFunc,
{
// Euler step: y_{n+1} = y_n + h * f(t_n, y_n)
let dy_dt = ode_func.forward(t, y)?;
@@ -244,16 +236,14 @@ impl RungeKutta4Solver {
}
impl ODESolver for RungeKutta4Solver {
fn solve<F>(
fn solve(
&self,
ode_func: &F,
ode_func: &dyn ODEFunc,
y0: &Tensor,
t_span: &[f32],
_rtol: f32,
_atol: f32,
) -> Result<(Tensor, SolverStats)>
where
F: ODEFunc,
{
if t_span.is_empty() {
return Err(NeuralODEError::InvalidInput("Empty time span".to_string()));
@@ -303,17 +293,15 @@ impl ODESolver for RungeKutta4Solver {
Ok((output, stats))
}
fn step<F>(
fn step(
&self,
ode_func: &F,
ode_func: &dyn ODEFunc,
t: f32,
y: &Tensor,
step_size: f32,
_rtol: f32,
_atol: f32,
) -> Result<StepResult>
where
F: ODEFunc,
{
let h = step_size;
let h_half = h * 0.5;
@@ -391,22 +379,20 @@ impl Dopri5Solver {
}
}
let error_norm = error_vec.pow_scalar(2.0)?.sum()?.sqrt()?.to_scalar::<f32>()?;
let error_norm = error_vec.pow_scalar(2.0)?.sum(None)?.sqrt()?.to_scalar::<f32>()?;
Ok(error_norm)
}
}
impl ODESolver for Dopri5Solver {
fn solve<F>(
fn solve(
&self,
ode_func: &F,
ode_func: &dyn ODEFunc,
y0: &Tensor,
t_span: &[f32],
rtol: f32,
atol: f32,
) -> Result<(Tensor, SolverStats)>
where
F: ODEFunc,
{
if t_span.is_empty() {
return Err(NeuralODEError::InvalidInput("Empty time span".to_string()));
@@ -479,17 +465,15 @@ impl ODESolver for Dopri5Solver {
Ok((output, stats))
}
fn step<F>(
fn step(
&self,
ode_func: &F,
ode_func: &dyn ODEFunc,
t: f32,
y: &Tensor,
step_size: f32,
rtol: f32,
atol: f32,
) -> Result<StepResult>
where
F: ODEFunc,
{
let h = step_size;
@@ -596,7 +580,7 @@ mod tests {
assert!(stats.n_fe > 0);
assert_eq!(stats.n_rejected, 0); // Fixed step solver
let result_slice = result.to_vec::<f32>().unwrap();
let result_slice = result.to_vec().unwrap();
assert!((result_slice[0] - 1.0).abs() < 1e-6); // Initial condition
assert!(result_slice[1] < 1.0); // Should decay
}
@@ -614,7 +598,7 @@ mod tests {
assert_eq!(result.shape(), &[2, 1]);
let result_slice = result.to_vec::<f32>().unwrap();
let result_slice = result.to_vec().unwrap();
let expected = (-1.0_f32).exp(); // Analytical solution: e^(-t)
// RK4 should be more accurate than Euler
@@ -634,7 +618,7 @@ mod tests {
assert_eq!(result.shape(), &[2, 1]);
let result_slice = result.to_vec::<f32>().unwrap();
let result_slice = result.to_vec().unwrap();
let expected = (-1.0_f32).exp();
// Adaptive solver should be very accurate
@@ -684,7 +668,7 @@ mod tests {
let (result, _) = solver.solve(&dynamics, &y0, &t_span, 1e-3, 1e-6).unwrap();
assert_eq!(result.shape(), &[1, 2]); // Single time point
let result_slice = result.to_vec::<f32>().unwrap();
let result_slice = result.to_vec().unwrap();
assert_eq!(result_slice, vec![1.0, 1.0]); // Should return initial condition
}
@@ -701,11 +685,11 @@ mod tests {
// For now, we need to solve each sample individually
// In a full implementation, we'd support batch solving natively
for i in 0..3 {
let y0_single = y0_batch.slice(0, i..i+1).unwrap().squeeze(0).unwrap();
let y0_single = y0_batch.narrow(0, i, 1).unwrap().squeeze(Some(0)).unwrap();
let (result, _) = solver.solve(&dynamics, &y0_single, &t_span, 1e-3, 1e-6).unwrap();
assert_eq!(result.shape(), &[2, 2]);
let result_slice = result.to_vec::<f32>().unwrap();
let result_slice = result.to_vec().unwrap();
assert!(result_slice[0] >= result_slice[2]); // Should decay over time
}
}