3

This question is analogical to Parallel write to array with an indices array except that I guarantee the indices to be unique.

let indices = [1, 4, 7, 8];
let mut arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

indices.iter_par().for_each(|x| {
    arr[x] = some_function(x);
});

Is there a way to achieve this in Rayon? Perhaps I should somehow use unsafe, because obviously borrow checker can't verify uniqueness of indices.

1
  • Sharing a mutable container seems to be a (soft) anti-pattern with rayon. Something like fold/reduce into hasmap can be an alternative, depending on the actual task. Commented Jan 25, 2022 at 12:58

1 Answer 1

2

You can certainly do it with unsafe, for example by sending a pointer to the threads:

// thin wrapper over pointer to make it Send/Sync
#[derive(Copy, Clone)]
struct Pointer(*mut u32);
unsafe impl Send for Pointer {}
unsafe impl Sync for Pointer {}

let indices = [1, 4, 7, 8];
let mut arr = [1u32, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let arr_ptr = Pointer(arr.as_mut_ptr());

indices.into_par_iter().for_each(move |x| {
    // safety:
    // * `indices` must be unique and point inside `arr`
    // * `place` must not leak outside the closure
    // * no element of `array` that is in `indices` may be accessed by
    //   some other thread while this is running
    let place = unsafe { &mut *{arr_ptr}.0.add(x) };
    *place = some_function(x);
});

But I'd reserve that kind of thing to use only as last resort. Once you introduce ad-hoc unsafe like this in your code base, you never know when you'll make a misstep and make your program vulnerable to random crashes and corruptions.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.