Problem
The Loss trait in src/loss/mod.rs has no Send + Sync bounds:
pub trait Loss {
fn compute(&self, y_pred: &Vector<f32>, y_true: &Vector<f32>) -> f32;
fn name(&self) -> &str;
}
Entrenar uses multithreaded training loops and needs to share loss functions across threads. Without Send + Sync, loss functions from aprender cannot be used in Arc<dyn Loss> or sent to worker threads.
Proposed Fix
pub trait Loss: Send + Sync {
fn compute(&self, y_pred: &Vector<f32>, y_true: &Vector<f32>) -> f32;
fn name(&self) -> &str;
}
All existing implementations (MSELoss, MAELoss, HuberLoss, etc.) are plain structs with no interior mutability, so they already satisfy Send + Sync — this is a zero-breaking-change addition.
Context
Entrenar delegates forward loss computation to aprender's standalone functions (mse_loss, mae_loss, huber_loss). Adding Send + Sync to the trait would also allow entrenar to accept Box<dyn Loss + Send + Sync> for dynamic dispatch in training loops.
Cross-ref: entrenar docs/specifications/simplify-entrenar.md Section 6
Problem
The
Losstrait insrc/loss/mod.rshas noSend + Syncbounds:Entrenar uses multithreaded training loops and needs to share loss functions across threads. Without
Send + Sync, loss functions from aprender cannot be used inArc<dyn Loss>or sent to worker threads.Proposed Fix
All existing implementations (
MSELoss,MAELoss,HuberLoss, etc.) are plain structs with no interior mutability, so they already satisfySend + Sync— this is a zero-breaking-change addition.Context
Entrenar delegates forward loss computation to aprender's standalone functions (
mse_loss,mae_loss,huber_loss). AddingSend + Syncto the trait would also allow entrenar to acceptBox<dyn Loss + Send + Sync>for dynamic dispatch in training loops.Cross-ref: entrenar
docs/specifications/simplify-entrenar.mdSection 6