Skip to content

Commit

Permalink
mesh-part: remove dependency on nightly
Browse files Browse the repository at this point in the history
  • Loading branch information
hhirtz committed Mar 23, 2022
1 parent b46a6db commit e31c07f
Showing 1 changed file with 78 additions and 115 deletions.
193 changes: 78 additions & 115 deletions tools/src/bin/mesh-part/main.rs
Original file line number Diff line number Diff line change
@@ -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<const D: usize, W> {
struct Problem<const D: usize> {
points: Vec<PointND<D>>,
weights: Vec<Vec<W>>,
weights: weight::Array,
}

trait Algorithm<const D: usize, W> {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D, W>) -> Result<()>;
trait Algorithm<const D: usize> {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D>) -> Result<()>;
}

impl<const D: usize, W, R> Algorithm<D, W> for coupe::Random<R>
impl<const D: usize, R> Algorithm<D> for coupe::Random<R>
where
R: rand::Rng,
{
fn run(&mut self, partition: &mut [usize], _: &Problem<D, W>) -> Result<()> {
fn run(&mut self, partition: &mut [usize], _: &Problem<D>) -> Result<()> {
self.partition(partition, ())?;
Ok(())
}
}

impl<const D: usize, W> Algorithm<D, W> for coupe::Greedy {
default fn run(&mut self, _: &mut [usize], _: &Problem<D, W>) -> Result<()> {
unreachable!();
}
}

impl<const D: usize> Algorithm<D, i64> for coupe::Greedy {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D, i64>) -> Result<()> {
let weights = problem.weights.iter().map(|weight| weight[0]);
self.partition(partition, weights)?;
Ok(())
}
}

impl<const D: usize> Algorithm<D, f64> for coupe::Greedy {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D, f64>) -> Result<()> {
let weights = problem
.weights
.iter()
.map(|weight| coupe::Real::from(weight[0]));
self.partition(partition, weights)?;
Ok(())
}
}

impl<const D: usize, W> Algorithm<D, W> for coupe::KarmarkarKarp {
default fn run(&mut self, _: &mut [usize], _: &Problem<D, W>) -> Result<()> {
unreachable!();
}
}

impl<const D: usize> Algorithm<D, i64> for coupe::KarmarkarKarp {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D, i64>) -> Result<()> {
let weights = problem.weights.iter().map(|weight| weight[0]);
self.partition(partition, weights)?;
Ok(())
}
}

impl<const D: usize> Algorithm<D, f64> for coupe::KarmarkarKarp {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D, f64>) -> Result<()> {
let weights = problem
.weights
.iter()
.map(|weight| coupe::Real::from(weight[0]));
self.partition(partition, weights)?;
Ok(())
}
}

impl<const D: usize, W> Algorithm<D, W> for coupe::VnBest {
default fn run(&mut self, _: &mut [usize], _: &Problem<D, W>) -> Result<()> {
unreachable!();
}
}

impl<const D: usize> Algorithm<D, i64> for coupe::VnBest {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D, i64>) -> Result<()> {
let weights = problem.weights.iter().map(|weight| weight[0]);
self.partition(partition, weights)?;
impl<const D: usize> Algorithm<D> for coupe::Greedy {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D>) -> 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<const D: usize> Algorithm<D, f64> for coupe::VnBest {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D, f64>) -> Result<()> {
let weights = problem
.weights
.iter()
.map(|weight| coupe::Real::from(weight[0]));
self.partition(partition, weights)?;
impl<const D: usize> Algorithm<D> for coupe::KarmarkarKarp {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D>) -> 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<const D: usize, W> Algorithm<D, W> for coupe::Rcb {
default fn run(&mut self, _: &mut [usize], _: &Problem<D, W>) -> Result<()> {
unreachable!();
}
}

impl<const D: usize> Algorithm<D, i64> for coupe::Rcb {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D, i64>) -> Result<()> {
let points = problem.points.par_iter().cloned();
let weights = problem.weights.par_iter().map(|weight| weight[0]);
self.partition(partition, (points, weights))?;
impl<const D: usize> Algorithm<D> for coupe::VnBest {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D>) -> 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<const D: usize> Algorithm<D, f64> for coupe::Rcb {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D, f64>) -> Result<()> {
impl<const D: usize> Algorithm<D> for coupe::Rcb {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D>) -> 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<const D: usize, W> Algorithm<D, W> for coupe::HilbertCurve {
default fn run(&mut self, _: &mut [usize], _: &Problem<D, W>) -> 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<f64> = problem.weights.iter().map(|weight| weight[0]).collect();
self.partition(partition, (&problem.points, weights))?;
impl<const D: usize> Algorithm<D> for coupe::HilbertCurve {
fn run(&mut self, partition: &mut [usize], problem: &Problem<D>) -> 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<PointND<D>>, &Vec<PointND<2>>>(&problem.points) };
match &problem.weights {
Integers(_) => anyhow::bail!("hilbert is only implemented for floats"),
Floats(fs) => {
let weights: Vec<f64> = fs.iter().map(|weight| weight[0]).collect();
self.partition(partition, (points, weights))?;
}
}
Ok(())
}
}

fn parse_algorithm<const D: usize, W>(spec: &str) -> Result<Box<dyn Algorithm<D, W>>> {
fn parse_algorithm<const D: usize>(spec: &str) -> Result<Box<dyn Algorithm<D>>> {
let mut args = spec.split(',');
let name = args.next().context("it's empty")?;

Expand Down Expand Up @@ -199,10 +173,10 @@ fn parse_algorithm<const D: usize, W>(spec: &str) -> Result<Box<dyn Algorithm<D,
})
}

fn main_d_w<const D: usize, W>(
fn main_d<const D: usize>(
matches: getopts::Matches,
mesh: Mesh,
weights: Vec<Vec<W>>,
weights: weight::Array,
) -> Result<Vec<usize>> {
let points: Vec<_> = mesh
.elements()
Expand Down Expand Up @@ -245,17 +219,6 @@ fn main_d_w<const D: usize, W>(
Ok(partition)
}

fn main_d<const D: usize>(
matches: getopts::Matches,
mesh: Mesh,
weights: weight::Array,
) -> Result<Vec<usize>> {
match weights {
Array::Integers(is) => main_d_w::<D, _>(matches, mesh, is),
Array::Floats(fs) => main_d_w::<D, _>(matches, mesh, fs),
}
}

fn main() -> Result<()> {
let mut options = getopts::Options::new();
options.optflag("h", "help", "print this help menu");
Expand Down

0 comments on commit e31c07f

Please sign in to comment.