Help with Rust errors

Dear community,

I find Rust absolutely amazing and I started implementing some DeepLearning with it. However, when scaling the algorithm to multiple dimensions using Vec, I seem to be facing some trouble. Can anybody please help me with my code? Many thanks in advance:

pub struct ConfigMetadata {
    pub start: Vec<f32>,
    pub step_size: f32,
    pub precision: f32,
    pub max_epochs: i32,
    pub derrivatives:  Vec<fn(f32) -> f32>,
    pub epoch_printer: fn(i32, Vec<f32>, f32, Option<f32>),
}

pub struct GrandientDescent {}
impl GrandientDescent {
    pub fn run(config_metadata: &ConfigMetadata) -> (bool, Vec<f32>, i32) {
        let mut next = config_metadata.start.clone();
        let mut current_x = Vec::new();
        let mut epochs = 0;
        for epoch in 0..config_metadata.max_epochs {
            current_x= next.clone();
            for dimmension in 0..config_metadata.derrivatives.len(){
                next[dimmension] = current_x[dimmension] - config_metadata.step_size * (config_metadata.derrivatives[dimmension])(current_x[dimmension]);
                let loss = next[dimmension] - current_x[dimmension];

                (config_metadata.epoch_printer)(epoch, current_x, loss, None);
                epochs += 1;
                if loss.abs() <= config_metadata.precision {
                    return (true, current_x, epochs)
                }
            }
        }
        (false, Vec::with_capacity(0), epochs)
    }
}
...
let (found, minimum_x, epochs) = GrandientDescent::run(&config_metadata);

The error is:

>error[E0382]: borrow of moved value: `current_x`
>  --> src/optimizers.rs:20:36
>15 |         let mut current_x = Vec::new();
>   |             ------------- move occurs because `current_x` has type `std::vec::Vec<f32>`, which does not implement the `Copy` trait
>...
>20 |                 next[dimmension] = current_x[dimmension] - config_metadata.step_size * (config_metadata.derrivatives[dimmension])(current_x[dimmension]);
>   |                                    ^^^^^^^^^ value borrowed here after move
>...
>23 |                 (config_metadata.epoch_printer)(epoch, current_x, loss, None);
>   |                                                        --------- value moved here, in previous iteration of loop

So the actual error is on the line with next[dimmension] = current_x[dimmension]

Hi, the compiler is saying that since current_x isn't Copy and epoch_printer takes it by value it is moved. But you are in a loop so when the next iteration happens current_x isn't there anymore.

There are a few ways to solve it but epoch_printer should probably take a reference instead of a value.

1 Like

I think the compiler error was a bit misleading, I looked at where it marked lines 15 and 20 but did not go further and did not see the call. The error made no sense to me, hence the question.

Indeed, as you pointed out, with the call to epoch_printer all does make sense! Many thanks!
I applied your correction as follows, now works:

(config_metadata.epoch_printer)(epoch, current_x.clone(), loss, None);