rayon-rs / rayon

Rayon: A data parallelism library for Rust
Apache License 2.0
10.8k stars 493 forks source link

Possible to implement IntoParallelIter for &mut [T] too? #22

Closed polyfractal closed 8 years ago

polyfractal commented 8 years ago

So I was attempting to use into_par_iter() on something that needed mutability, and ran into what seems like a limitation.

My setup is a cellular automata grid. A single Grid holds a vector of Pages, and each Page holds a vector of Cells. The goal was to into_par_iter() over the pages, since they can be processed independently. However, the grow() method on each Page requires mutability because they modify their state internally...which seems to be a problem.

A rough outline:

pub struct Grid {
    pages: Vec<Page>
}

impl Grid {
  fn start(&mut self) {
      loop {
          let active_cells =  (&mut self.pages).into_par_iter()
              .map(|page| page.grow(GrowthPhase::Axon))
              .sum();

            //error: cannot borrow immutable borrowed content `*page` as mutable
            //  .map(|page| page.grow(GrowthPhase::Axon))
            //              ^~~~

          if active_cells == 0 {
              break;
          }
      }
  }
}

pub struct Page {
    cells: Vec<Cell>
}

impl Page {
    pub fn grow(&mut self, phase: GrowthPhase) -> u32 {
        // modifies state internally here
    }
}

Would it be possible for Rayon to support this, or is there something subtle I'm missing? Thanks!

nikomatsakis commented 8 years ago

I haven't read your code in detail, but it should be possible to support mutable references, I just didn't spend any time on extending the par_iter API in a while. I am trying to carve out some time in the next few weeks.