From e31c07fd3557b2f3313f559704186b618fec7baa Mon Sep 17 00:00:00 2001 From: Hubert Hirtz Date: Wed, 23 Mar 2022 12:51:04 +0100 Subject: [PATCH] mesh-part: remove dependency on nightly --- tools/src/bin/mesh-part/main.rs | 193 +++++++++++++------------------- 1 file changed, 78 insertions(+), 115 deletions(-) diff --git a/tools/src/bin/mesh-part/main.rs b/tools/src/bin/mesh-part/main.rs index ec26be3b..c8fd4ce6 100644 --- a/tools/src/bin/mesh-part/main.rs +++ b/tools/src/bin/mesh-part/main.rs @@ -1,151 +1,125 @@ -#![feature(min_specialization)] - use anyhow::Context as _; use anyhow::Result; use coupe::Partition as _; use coupe::PointND; use mesh_io::medit::Mesh; use mesh_io::weight; -use mesh_io::weight::Array; use rayon::iter::IntoParallelRefIterator as _; use rayon::iter::ParallelIterator as _; use std::env; use std::fs; use std::io; +use std::mem; -struct Problem { +struct Problem { points: Vec>, - weights: Vec>, + weights: weight::Array, } -trait Algorithm { - fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()>; +trait Algorithm { + fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()>; } -impl Algorithm for coupe::Random +impl Algorithm for coupe::Random where R: rand::Rng, { - fn run(&mut self, partition: &mut [usize], _: &Problem) -> Result<()> { + fn run(&mut self, partition: &mut [usize], _: &Problem) -> Result<()> { self.partition(partition, ())?; Ok(()) } } -impl Algorithm for coupe::Greedy { - default fn run(&mut self, _: &mut [usize], _: &Problem) -> Result<()> { - unreachable!(); - } -} - -impl Algorithm for coupe::Greedy { - fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { - let weights = problem.weights.iter().map(|weight| weight[0]); - self.partition(partition, weights)?; - Ok(()) - } -} - -impl Algorithm for coupe::Greedy { - fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { - let weights = problem - .weights - .iter() - .map(|weight| coupe::Real::from(weight[0])); - self.partition(partition, weights)?; - Ok(()) - } -} - -impl Algorithm for coupe::KarmarkarKarp { - default fn run(&mut self, _: &mut [usize], _: &Problem) -> Result<()> { - unreachable!(); - } -} - -impl Algorithm for coupe::KarmarkarKarp { - fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { - let weights = problem.weights.iter().map(|weight| weight[0]); - self.partition(partition, weights)?; - Ok(()) - } -} - -impl Algorithm for coupe::KarmarkarKarp { - fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { - let weights = problem - .weights - .iter() - .map(|weight| coupe::Real::from(weight[0])); - self.partition(partition, weights)?; - Ok(()) - } -} - -impl Algorithm for coupe::VnBest { - default fn run(&mut self, _: &mut [usize], _: &Problem) -> Result<()> { - unreachable!(); - } -} - -impl Algorithm for coupe::VnBest { - fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { - let weights = problem.weights.iter().map(|weight| weight[0]); - self.partition(partition, weights)?; +impl Algorithm for coupe::Greedy { + fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { + use weight::Array::*; + match &problem.weights { + Integers(is) => { + let weights = is.iter().map(|weight| weight[0]); + self.partition(partition, weights)?; + } + Floats(fs) => { + let weights = fs.iter().map(|weight| coupe::Real::from(weight[0])); + self.partition(partition, weights)?; + } + } Ok(()) } } -impl Algorithm for coupe::VnBest { - fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { - let weights = problem - .weights - .iter() - .map(|weight| coupe::Real::from(weight[0])); - self.partition(partition, weights)?; +impl Algorithm for coupe::KarmarkarKarp { + fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { + use weight::Array::*; + match &problem.weights { + Integers(is) => { + let weights = is.iter().map(|weight| weight[0]); + self.partition(partition, weights)?; + } + Floats(fs) => { + let weights = fs.iter().map(|weight| coupe::Real::from(weight[0])); + self.partition(partition, weights)?; + } + } Ok(()) } } -impl Algorithm for coupe::Rcb { - default fn run(&mut self, _: &mut [usize], _: &Problem) -> Result<()> { - unreachable!(); - } -} - -impl Algorithm for coupe::Rcb { - fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { - let points = problem.points.par_iter().cloned(); - let weights = problem.weights.par_iter().map(|weight| weight[0]); - self.partition(partition, (points, weights))?; +impl Algorithm for coupe::VnBest { + fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { + use weight::Array::*; + match &problem.weights { + Integers(is) => { + let weights = is.iter().map(|weight| weight[0]); + self.partition(partition, weights)?; + } + Floats(fs) => { + let weights = fs.iter().map(|weight| coupe::Real::from(weight[0])); + self.partition(partition, weights)?; + } + } Ok(()) } } -impl Algorithm for coupe::Rcb { - fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { +impl Algorithm for coupe::Rcb { + fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { + use weight::Array::*; let points = problem.points.par_iter().cloned(); - let weights = problem.weights.par_iter().map(|weight| weight[0]); - self.partition(partition, (points, weights))?; + match &problem.weights { + Integers(is) => { + let weights = is.par_iter().map(|weight| weight[0]); + self.partition(partition, (points, weights))?; + } + Floats(fs) => { + let weights = fs.par_iter().map(|weight| weight[0]); + self.partition(partition, (points, weights))?; + } + } Ok(()) } } -impl Algorithm for coupe::HilbertCurve { - default fn run(&mut self, _: &mut [usize], _: &Problem) -> Result<()> { - Err(anyhow::anyhow!("hilbert only supports 2D and floats")) - } -} - -impl Algorithm<2, f64> for coupe::HilbertCurve { - fn run(&mut self, partition: &mut [usize], problem: &Problem<2, f64>) -> Result<()> { - let weights: Vec = problem.weights.iter().map(|weight| weight[0]).collect(); - self.partition(partition, (&problem.points, weights))?; +impl Algorithm for coupe::HilbertCurve { + fn run(&mut self, partition: &mut [usize], problem: &Problem) -> Result<()> { + use weight::Array::*; + if D != 2 { + anyhow::bail!("hilbert is only implemented for 2D meshes"); + } + // SAFETY: is a noop since D == 2 + let points = + unsafe { mem::transmute::<&Vec>, &Vec>>(&problem.points) }; + match &problem.weights { + Integers(_) => anyhow::bail!("hilbert is only implemented for floats"), + Floats(fs) => { + let weights: Vec = fs.iter().map(|weight| weight[0]).collect(); + self.partition(partition, (points, weights))?; + } + } Ok(()) } } -fn parse_algorithm(spec: &str) -> Result>> { +fn parse_algorithm(spec: &str) -> Result>> { let mut args = spec.split(','); let name = args.next().context("it's empty")?; @@ -199,10 +173,10 @@ fn parse_algorithm(spec: &str) -> Result( +fn main_d( matches: getopts::Matches, mesh: Mesh, - weights: Vec>, + weights: weight::Array, ) -> Result> { let points: Vec<_> = mesh .elements() @@ -245,17 +219,6 @@ fn main_d_w( Ok(partition) } -fn main_d( - matches: getopts::Matches, - mesh: Mesh, - weights: weight::Array, -) -> Result> { - match weights { - Array::Integers(is) => main_d_w::(matches, mesh, is), - Array::Floats(fs) => main_d_w::(matches, mesh, fs), - } -} - fn main() -> Result<()> { let mut options = getopts::Options::new(); options.optflag("h", "help", "print this help menu");