1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
//! Fine-tuning parameter types.
//!
//! For options that take an integer value, should this value be negative, the
//! default will be used, if any.
// Idx and Real can be 32 or 64 bits. Make sure to suppress warnings when
// casts turn out to be trivial.
#![allow(trivial_numeric_casts)]
use crate::m;
use crate::Idx;
mod private {
pub trait Sealed {}
}
/// Trait implemented by METIS' options.
///
/// See [`crate::Graph::set_options`] for an example. It is also used in
/// [`crate::Mesh::set_options`].
pub trait Opt: private::Sealed {
/// Index of the option in the array from [`crate::Graph::set_options`] and
/// [`crate::Mesh::set_options`].
const INDEX: usize;
/// Convert the value into metis' format, for use with
/// [`crate::Graph::set_options`] and [`crate::Mesh::set_options`].
fn value(self) -> Idx;
}
/// Specifies the partitioning method.
pub enum PType {
/// Multilevel recursive bisection.
Rb,
/// Multilevel k-way partitioning.
Kway,
}
impl private::Sealed for PType {}
impl Opt for PType {
const INDEX: usize = m::moptions_et_METIS_OPTION_PTYPE as usize;
fn value(self) -> Idx {
match self {
PType::Rb => m::mptype_et_METIS_PTYPE_RB as Idx,
PType::Kway => m::mptype_et_METIS_PTYPE_KWAY as Idx,
}
}
}
/// Specifies the type of objective.
pub enum ObjType {
/// Edge-cut minimization.
Cut,
/// Total communication volume minimization.
Vol,
}
impl private::Sealed for ObjType {}
impl Opt for ObjType {
const INDEX: usize = m::moptions_et_METIS_OPTION_OBJTYPE as usize;
fn value(self) -> Idx {
match self {
ObjType::Cut => m::mobjtype_et_METIS_OBJTYPE_CUT as Idx,
ObjType::Vol => m::mobjtype_et_METIS_OBJTYPE_VOL as Idx,
}
}
}
/// Specifies the matching scheme to be used during coarsening.
pub enum CType {
/// Random matching.
Rm,
/// Sorted heavy-edge matching.
Shem,
}
impl private::Sealed for CType {}
impl Opt for CType {
const INDEX: usize = m::moptions_et_METIS_OPTION_CTYPE as usize;
fn value(self) -> Idx {
match self {
CType::Rm => m::mctype_et_METIS_CTYPE_RM as Idx,
CType::Shem => m::mctype_et_METIS_CTYPE_SHEM as Idx,
}
}
}
/// Determines the algorithm used during initial partitioning.
pub enum IpType {
/// Grows a bisection using a greedy strategy.
Grow,
/// Compute a bisection at random followed by a refinement.
Random,
/// Derives a separator from an edge cut.
Edge,
/// Grow a bisection using a greedy node-based strategy.
Node,
}
impl private::Sealed for IpType {}
impl Opt for IpType {
const INDEX: usize = m::moptions_et_METIS_OPTION_IPTYPE as usize;
fn value(self) -> Idx {
match self {
IpType::Grow => m::miptype_et_METIS_IPTYPE_GROW as Idx,
IpType::Random => m::miptype_et_METIS_IPTYPE_RANDOM as Idx,
IpType::Edge => m::miptype_et_METIS_IPTYPE_EDGE as Idx,
IpType::Node => m::miptype_et_METIS_IPTYPE_NODE as Idx,
}
}
}
/// Determines the algorithm used for refinement.
pub enum RType {
/// FM-based cut refinement.
Fm,
/// Greedy-based cut and volume refinement.
Greedy,
/// Two-sided FM refinement.
Sep2Sided,
/// One-sided FM refinement.
Sep1Sided,
}
impl private::Sealed for RType {}
impl Opt for RType {
const INDEX: usize = m::moptions_et_METIS_OPTION_RTYPE as usize;
fn value(self) -> Idx {
match self {
RType::Fm => m::mrtype_et_METIS_RTYPE_FM as Idx,
RType::Greedy => m::mrtype_et_METIS_RTYPE_GREEDY as Idx,
RType::Sep2Sided => m::mrtype_et_METIS_RTYPE_SEP2SIDED as Idx,
RType::Sep1Sided => m::mrtype_et_METIS_RTYPE_SEP1SIDED as Idx,
}
}
}
/// Specifies the number of different partitions that it will compute. The
/// final partition is the one that achieves the best edge cut or
/// communication volume. Default is 1.
pub struct NCuts(pub Idx);
impl private::Sealed for NCuts {}
impl Opt for NCuts {
const INDEX: usize = m::moptions_et_METIS_OPTION_NCUTS as usize;
fn value(self) -> Idx {
self.0
}
}
/// Specifies the number of different separators that it will compute at each
/// level of nested dissection.
///
/// The final separator that is used is the smallest one. Default is 1.
pub struct NSeps(pub Idx);
impl private::Sealed for NSeps {}
impl Opt for NSeps {
const INDEX: usize = m::moptions_et_METIS_OPTION_NSEPS as usize;
fn value(self) -> Idx {
self.0
}
}
/// Used to indicate which numbering scheme is used for the adjacency structure
/// of a graph or the element-node structure of a mesh.
#[allow(dead_code)]
pub(crate) enum Numbering {
/// C-style numbering which is assumed to start from 0.
C,
/// Fortran-style numbering which is assumed to start from 1.
Fortran,
}
impl private::Sealed for Numbering {}
impl Opt for Numbering {
const INDEX: usize = m::moptions_et_METIS_OPTION_NUMBERING as usize;
fn value(self) -> Idx {
match self {
Numbering::C => 0,
Numbering::Fortran => 1,
}
}
}
/// Specifies the number of iterations for the refinement algorithms at each
/// stage of the uncoarsening process.
///
/// Default is 10.
pub struct NIter(pub Idx);
impl private::Sealed for NIter {}
impl Opt for NIter {
const INDEX: usize = m::moptions_et_METIS_OPTION_NITER as usize;
fn value(self) -> Idx {
self.0
}
}
/// Specifies the seed for the random number generator.
pub struct Seed(pub Idx);
impl private::Sealed for Seed {}
impl Opt for Seed {
const INDEX: usize = m::moptions_et_METIS_OPTION_SEED as usize;
fn value(self) -> Idx {
self.0
}
}
/// Specifies that the partitioning routines should try to minimize the maximum
/// degree of the subdomain graph.
///
/// I.e., the graph in which each partition is a node, and edges connect
/// subdomains with a shared interface.
pub struct MinConn(pub bool);
impl private::Sealed for MinConn {}
impl Opt for MinConn {
const INDEX: usize = m::moptions_et_METIS_OPTION_MINCONN as usize;
fn value(self) -> Idx {
self.0 as Idx
}
}
/// Specifies that the coarsening will not perform any 2-hop matching when the
/// standards matching approach fails to sufficiently coarsen the graph.
///
/// The 2-hop matching is very effective for graphs with power-law degree
/// distributions.
pub struct No2Hop(pub bool);
impl private::Sealed for No2Hop {}
impl Opt for No2Hop {
const INDEX: usize = m::moptions_et_METIS_OPTION_NO2HOP as usize;
fn value(self) -> Idx {
self.0 as Idx
}
}
/// Specifies that the partitioning routines should try to produce partitions
/// that are contiguous.
///
/// Note that if the input graph is not connected this option is ignored.
pub struct Contig(pub bool);
impl private::Sealed for Contig {}
impl Opt for Contig {
const INDEX: usize = m::moptions_et_METIS_OPTION_CONTIG as usize;
fn value(self) -> Idx {
self.0 as Idx
}
}
/// Specifies that the graph should be compressed by combining vertices
/// that have identical adjacency lists.
pub struct Compress(pub bool);
impl private::Sealed for Compress {}
impl Opt for Compress {
const INDEX: usize = m::moptions_et_METIS_OPTION_COMPRESS as usize;
fn value(self) -> Idx {
self.0 as Idx
}
}
/// Specifies if the connected components of the graph should first be
/// identified and ordered separately.
pub struct CCOrder(pub bool);
impl private::Sealed for CCOrder {}
impl Opt for CCOrder {
const INDEX: usize = m::moptions_et_METIS_OPTION_CCORDER as usize;
fn value(self) -> Idx {
self.0 as Idx
}
}
/// Specifies the minimum degree of the vertices that will be ordered last.
///
/// If the specified value is `x > 0`, then any vertices with a degree greater
/// than `0.1*x*(average degree)` are removed from the graph, an ordering of the
/// rest of the vertices is computed, and an overall ordering is computed by
/// ordering the removed vertices at the end of the overall ordering. For
/// example if `x == 40`, and the average degree is 5, then the algorithm will
/// remove all vertices with degree greater than 20. The vertices that are
/// removed are ordered last (i.e., they are automatically placed in the
/// top-level separator). Good values are often in the range of 60 to 200 (i.e.,
/// 6 to 20 times more than the average). Default value is 0, indicating that no
/// vertices are removed.
///
/// Used to control whether the ordering algorithm should remove any
/// vertices with high degree (i.e., dense columns). This is particularly
/// helpful for certain classes of LP matrices, in which there a few vertices
/// that are connected to many other vertices. By removing these vertices prior
/// to ordering, the quality and the amount of time required to do the ordering
/// improves.
pub struct PFactor(pub Idx);
impl private::Sealed for PFactor {}
impl Opt for PFactor {
const INDEX: usize = m::moptions_et_METIS_OPTION_PFACTOR as usize;
fn value(self) -> Idx {
self.0
}
}
/// Specifies the maximum allowed load imbalance among the partitions.
///
/// A value of `x` indicates that the allowed load imbalance is `(1 + x)/1000`.
/// The load imbalance for the `j`th constraint is defined to be
/// `max_i(w[j,i]/t[j,i])`, where `w[j,i]` is the fraction of the overall
/// weight of the `j`th constraint that is assigned to the`i`th partition and
/// `t[j,i]` is the desired target weight of the `j`th constraint for the `i`th
/// partition (i.e., that specified via `-tpwgts`). For `-ptype=rb`, the default
/// value is 1 (i.e., load imbalance of 1.001) and for `-ptype=kway`, the
/// default value is 30 (i.e., load imbalance of 1.03).
pub struct UFactor(pub Idx);
impl private::Sealed for UFactor {}
impl Opt for UFactor {
const INDEX: usize = m::moptions_et_METIS_OPTION_UFACTOR as usize;
fn value(self) -> Idx {
self.0
}
}
/// Specifies the amount of progress/debugging information will be printed
/// during the execution of the algorithms.
///
/// The default value is false for every field (no debugging/progress
/// information).
pub struct DbgLvl {
/// Prints various diagnostic messages.
pub info: bool,
/// Performs timing analysis.
pub time: bool,
/// Displays various statistics during coarsening.
pub coarsen: bool,
/// Displays various statistics during refinement.
pub refine: bool,
/// Displays various statistics during initial partitioning.
pub ipart: bool,
/// Display detailed information about vertex moves during refinement.
pub move_info: bool,
/// Display detailed information about vertex separators.
pub sep_info: bool,
/// Display information related to the minimization of subdomain
/// connectivity.
pub conn_info: bool,
/// Display information related to the elimination of connected components.
pub contig_info: bool,
}
impl private::Sealed for DbgLvl {}
impl Opt for DbgLvl {
const INDEX: usize = m::moptions_et_METIS_OPTION_DBGLVL as usize;
fn value(self) -> Idx {
let mut dbglvl = 0;
if self.info {
dbglvl |= 1;
}
if self.time {
dbglvl |= 2;
}
if self.coarsen {
dbglvl |= 4;
}
if self.refine {
dbglvl |= 8;
}
if self.ipart {
dbglvl |= 16;
}
if self.move_info {
dbglvl |= 32;
}
if self.sep_info {
dbglvl |= 64;
}
if self.conn_info {
dbglvl |= 128;
}
if self.contig_info {
dbglvl |= 256;
}
dbglvl
}
}