Cannot borrow `graph` as immutable because it is also borrowed as mutable

Hello, i have the following error:

This is the code:

fn floyd_version_parallel(graph: &mut Array2<f32>) {
for k in 0..MAX {
    graph.row_mut(k + 1).iter_mut().enumerate().for_each(|(i, ij)| {
        for j in 0..MAX {
            unsafe {
                let sum = *graph.uget((i, k)) + *graph.uget((k, j));
                if sum < *ij {
                    *ij = sum;
                }
            }
        }
    });
}
}

This is a playground of my code.

I'm using ndarray. I need to iterate over a row, access to other cells and modify a value.

I spent a lot of hours and i don't know how to solve it. Any ideas ? Thank you so much !

You can transform the nested loops a bit so that the borrows occur outside of the mutable iterator, and then loop over the iterator instead of calling for_each with a closure: playground

Disclaimer: I can't check whether this transformation behaves the same as you expect, but it seems ok. I'm also very weary of using unsafe, but I won't question your decision here. Presumably you understand all of the risks. But this code does deserve some comments documenting why it's actually safe.

1 Like

@parasyte Thank you so much ! I forgot to modify my code. Following your implementation, i need something like this:

fn floyd_version_parallel(graph: &mut Array2<f32>) {
for k in 0..MAX {
    for i in 0..MAX {
        let row_elemnt = graph.get((i, k)).unwrap();

        for (j, ij) in graph.row_mut(k + 1).iter_mut().enumerate() {
            let sum = row_elemnt + graph.get((k, j)).unwrap();
            if sum < *ij {
                *ij = sum;
            }
        }
    }
}

}

and of course it's happen the same, i cant do graph.get((k, j)).unwrap() because of borrowed. Any other ideas ? Thank you again

I edit the playground with the code.

Whew, I finally found a way to create multiple disjoint mutable slices of an ndarray. Here's what I believe is a working example: playground