Replies: 1 comment 1 reply
-
fn collapse_all_reset_on_contradiction_par(&mut self, rng: &mut SmallRng) -> u32 {
let rngs: Vec<_> = (0..rayon::current_num_threads())
.map(|_| SmallRng::seed_from_u64(rng.gen()))
.collect();
let (wfc, iterations) = rngs
.into_par_iter()
.flat_map_iter(|mut rng| {
let mut opt_wfc = Some(self.clone());
let mut attempts = 1;
std::iter::from_fn(move || {
// return None after we already consumed our wfc
let mut wfc = opt_wfc.take()?;
if let Some((index, tile)) = wfc.find_lowest_entropy(&mut rng) {
if wfc.collapse(index, tile) {
if attempts % 1000 == 0 {
println!("{}", attempts);
}
wfc.reset();
attempts += 1;
}
// put it back for the next `find_lowest_entropy` call
opt_wfc = Some(wfc);
// returning a `None` item gives `find_map_any` a chance to end
// this search if a different thread found something
Some(None)
} else {
// we're done here, return our wfc!
Some(Some((wfc, attempts)))
}
})
})
.find_map_any(std::convert::identity)
.unwrap();
*self = wfc;
iterations
} (It's possible that end condition is wrong, but I tried to replicate what I saw in your original code...) |
Beta Was this translation helpful? Give feedback.
-
Hi, I have a parallel search problem (Wave Function Collapse) that I'm using parallel iterators for:
I really don't like that I need the
stop_flag
AtomicBool
in order to control each thread. Commenting outstop_flag.store(true, Ordering::Relaxed);
leads to a situation where the iterator only finishes after every thread has finished; the opposite of what I want! Is there a more elegant way to do this?Beta Was this translation helpful? Give feedback.
All reactions