Hello!
I am doing a project where I try to identify parallel opportunities in rust code automatically and then generate recommendations to implement them with known patterns. I orientate myself on a previous project that auto generates OpenMP directives for example above the loop head for doall/reduction patterns for example. I am trying to do this with rayon for rust.
in particular, I want to use rayon to implement a simple loop reduction pattern.
for i in 0..iterations {
a = a + 1;
b = b * 5;
c = c - 2;
print(a)
}
for example in above loop in OpenMP this could be trivially parallelized with a
#pragma omp parallel reduction(+ :a) reduction(* :b) reduction(- :c)
with rayon I would do it with one variable and generate a range
let sum = (1..iterations)
.into_par_iter()
.reduce(|| a,
|_, _| a + 1);
however I had trouble doing it with multiple variables and one iterator. would I need to have the above piece of code for every variable that I want to reduce? as I understand, I cannot return a tuple from a one dimensional collection that was turned into a parallel iterator?
additionally, what if I want to execute some other code within each iteration like the print in the above example. would I chain a foreach after the reduce?
another issue I have faced is when I try to write to an array inside the closure of the foreach I get the error:
let mut
(0..arr.len()).into_par_iter()
.for_each(|i| arr[i] = 0 );
closures cannot mutate their captured variables
where I am trying to imitate the simple
#pragma omp parallel
for(int i = 0; i<n; i++9 {
arr[i] = 0;
}
no race condition could occur with this example because there is no inter loop dependency, no two threads would manipulate the array at the same index.
what works here is
arr.par_iter_mut()
.for_each(|x| {
*x = 0;
});
but again, what if I want to use multiple array like in the swap example, what if I need the index of the current element?
is there a way I can achieve what I am trying to do or do I need to rethink this implementation?
as I understand, rayon is particularly useful when you have a collection you want to iterate over, however in my case I am mostly iterating through looks with an index to achieve all sorts of things not just collection processing.
thanks!