metis

MoonBit bindings to METIS

metis
graph
partitioning
mesh
ordering
moon add Milky2018/metis@0.1.1
Download zip
Author
Version
0.1.1
License
Apache-2.0
Last updated
2 months ago
Downloads
129
README

#Milky2018/metis

MoonBit bindings to METIS.

This package vendors the upstream METIS and GKlib C sources into MoonBit native stubs. The ABI uses 32-bit idx_t and 32-bit real_t, matching the standard METIS build.

Graphs and meshes use MoonBit/C-style zero-based numbering. The safe API does not expose METIS' Fortran-numbering option because that mode renumbers input arrays in place inside METIS.

Mesh stores only element connectivity. Mesh partitioning weights are supplied at the call site because part_mesh_nodal expects node weights of length nn, while part_mesh_dual expects element weights of length ne.

#Development

Generate vendored C sources:

python3 scripts/prepare.py

Validate:

moon check --target native moon test --target native python3 scripts/test.py --asan moon fmt moon info --target native

The examples below are tested by MoonBit:

moon test src/README.mbt.md --target native

#Partition A CSR Graph

///|
test "partition a four-cycle graph" {
let graph = CsrGraph::new(4, [0, 2, 4, 6, 8], [1, 3, 0, 2, 1, 3, 0, 2])
let result = part_graph_kway(graph, 2)
inspect(result.part.length(), content="4")
for value in result.part {
guard value >= 0 && value < 2
}
}

#Nested Dissection Ordering

///|
test "compute a node ordering" {
let graph = CsrGraph::new(4, [0, 2, 4, 6, 8], [1, 3, 0, 2, 1, 3, 0, 2])
let result = node_nd(graph)
inspect(result.perm.length(), content="4")
inspect(result.iperm.length(), content="4")
}

#Mesh Conversion And Partitioning

///|
test "convert and partition a mesh" {
let mesh = Mesh::new(2, 4, [0, 3, 6], [0, 1, 2, 1, 2, 3])
let dual = mesh_to_dual(mesh, ncommon=2)
inspect(dual.nvtxs(), content="2")
let nodal = mesh_to_nodal(mesh)
inspect(nodal.nvtxs(), content="4")

let nodal_partition = part_mesh_nodal(
mesh,
2,
node_weights=FixedArray::make(4, 1),
node_sizes=FixedArray::make(4, 1),
)
inspect(nodal_partition.epart.length(), content="2")
inspect(nodal_partition.npart.length(), content="4")

let dual_partition = part_mesh_dual(
mesh,
2,
ncommon=2,
element_weights=FixedArray::make(2, 1),
element_sizes=FixedArray::make(2, 1),
)
inspect(dual_partition.epart.length(), content="2")
inspect(dual_partition.npart.length(), content="4")
}

The public API validates CSR and mesh shapes before entering C. METIS-allocated arrays from mesh conversion are copied into MoonBit-owned arrays and freed inside the binding.

#Milky2018/metis

MoonBit bindings to METIS.

This package vendors the upstream METIS and GKlib C sources into MoonBit native stubs. The ABI uses 32-bit idx_t and 32-bit real_t, matching the standard METIS build.

Graphs and meshes use MoonBit/C-style zero-based numbering. The safe API does not expose METIS' Fortran-numbering option because that mode renumbers input arrays in place inside METIS.

Mesh stores only element connectivity. Mesh partitioning weights are supplied at the call site because part_mesh_nodal expects node weights of length nn, while part_mesh_dual expects element weights of length ne.

#Development

Generate vendored C sources:

python3 scripts/prepare.py

Validate:

moon check --target native moon test --target native python3 scripts/test.py --asan moon fmt moon info --target native

The examples below are tested by MoonBit:

moon test src/README.mbt.md --target native

#Partition A CSR Graph

///|
test "partition a four-cycle graph" {
let graph = CsrGraph::new(4, [0, 2, 4, 6, 8], [1, 3, 0, 2, 1, 3, 0, 2])
let result = part_graph_kway(graph, 2)
inspect(result.part.length(), content="4")
for value in result.part {
guard value >= 0 && value < 2
}
}

#Nested Dissection Ordering

///|
test "compute a node ordering" {
let graph = CsrGraph::new(4, [0, 2, 4, 6, 8], [1, 3, 0, 2, 1, 3, 0, 2])
let result = node_nd(graph)
inspect(result.perm.length(), content="4")
inspect(result.iperm.length(), content="4")
}

#Mesh Conversion And Partitioning

///|
test "convert and partition a mesh" {
let mesh = Mesh::new(2, 4, [0, 3, 6], [0, 1, 2, 1, 2, 3])
let dual = mesh_to_dual(mesh, ncommon=2)
inspect(dual.nvtxs(), content="2")
let nodal = mesh_to_nodal(mesh)
inspect(nodal.nvtxs(), content="4")

let nodal_partition = part_mesh_nodal(
mesh,
2,
node_weights=FixedArray::make(4, 1),
node_sizes=FixedArray::make(4, 1),
)
inspect(nodal_partition.epart.length(), content="2")
inspect(nodal_partition.npart.length(), content="4")

let dual_partition = part_mesh_dual(
mesh,
2,
ncommon=2,
element_weights=FixedArray::make(2, 1),
element_sizes=FixedArray::make(2, 1),
)
inspect(dual_partition.epart.length(), content="2")
inspect(dual_partition.npart.length(), content="4")
}

The public API validates CSR and mesh shapes before entering C. METIS-allocated arrays from mesh conversion are copied into MoonBit-owned arrays and freed inside the binding.

#
MetisError

pub(all) suberror MetisError {
Input
Memory
Error
InvalidGraph
InvalidMesh
InvalidOptions
UnsupportedIndexWidth
} derive(Eq, Hash)

#
CoarseningScheme

pub(all) enum CoarseningScheme {
RandomMatching
SortedHeavyEdgeMatching
}

#
CsrGraph

pub struct CsrGraph {
// private fields
}

#
CsrGraph::adjacency_weights

fn CsrGraph::adjacency_weights(self : CsrGraph) -> FixedArray[Int]?

#
CsrGraph::adjncy

fn CsrGraph::adjncy(self : CsrGraph) -> FixedArray[Int]

#
CsrGraph::ncon

fn CsrGraph::ncon(self : CsrGraph) -> Int

#
CsrGraph::new

fn CsrGraph::new(nvtxs : Int, xadj : FixedArray[Int], adjncy : FixedArray[Int], ncon? : Int, vwgt? : FixedArray[Int], vsize? : FixedArray[Int], adjwgt? : FixedArray[Int]) -> CsrGraph raise MetisError

#
CsrGraph::nvtxs

fn CsrGraph::nvtxs(self : CsrGraph) -> Int

#
CsrGraph::vertex_sizes

fn CsrGraph::vertex_sizes(self : CsrGraph) -> FixedArray[Int]?

#
CsrGraph::vertex_weights

fn CsrGraph::vertex_weights(self : CsrGraph) -> FixedArray[Int]?

#
CsrGraph::xadj

fn CsrGraph::xadj(self : CsrGraph) -> FixedArray[Int]

#
DebugFlag

pub(all) enum DebugFlag {
Info
Time
Coarsen
Refine
InitialPartition
MoveInfo
SeparatorInfo
ConnectivityInfo
ContiguityInfo
Memory
}

#
InitialPartitioningScheme

pub(all) enum InitialPartitioningScheme {
Grow
Random
Edge
Node
MetisRecursiveBisection
}

#
Mesh

pub struct Mesh {
// private fields
}

#
Mesh::eind

fn Mesh::eind(self : Mesh) -> FixedArray[Int]

#
Mesh::eptr

fn Mesh::eptr(self : Mesh) -> FixedArray[Int]

#
Mesh::ne

fn Mesh::ne(self : Mesh) -> Int

#
Mesh::new

fn Mesh::new(ne : Int, nn : Int, eptr : FixedArray[Int], eind : FixedArray[Int]) -> Mesh raise MetisError

#
Mesh::nn

fn Mesh::nn(self : Mesh) -> Int

#
MeshPartitionResult

pub(all) struct MeshPartitionResult {
objval : Int
epart : FixedArray[Int]
npart : FixedArray[Int]
}

#
ObjectiveType

pub(all) enum ObjectiveType {
Cut
Volume
Node
}

#
Options

pub struct Options {
// private fields
}

#
Options::default

fn Options::default() -> Options

#
Options::set_coarsening_scheme

fn Options::set_coarsening_scheme(self : Options, scheme : CoarseningScheme) -> Options

#
Options::set_compress

fn Options::set_compress(self : Options, enabled : Bool) -> Options

#
Options::set_connected_component_ordering

fn Options::set_connected_component_ordering(self : Options, enabled : Bool) -> Options

#
Options::set_contiguous

fn Options::set_contiguous(self : Options, enabled : Bool) -> Options

#
Options::set_debug_flags

fn Options::set_debug_flags(self : Options, flags : FixedArray[DebugFlag]) -> Options

#
Options::set_debug_level

fn Options::set_debug_level(self : Options, level : Int) -> Options

#
Options::set_drop_edges

fn Options::set_drop_edges(self : Options, enabled : Bool) -> Options

#
Options::set_imbalance_factor

fn Options::set_imbalance_factor(self : Options, factor : Int) -> Options

#
Options::set_initial_partitioning_scheme

fn Options::set_initial_partitioning_scheme(self : Options, scheme : InitialPartitioningScheme) -> Options

#
Options::set_minimize_connectivity

fn Options::set_minimize_connectivity(self : Options, enabled : Bool) -> Options

#
Options::set_no_two_hop

fn Options::set_no_two_hop(self : Options, enabled : Bool) -> Options

#
Options::set_number_of_cuts

fn Options::set_number_of_cuts(self : Options, ncuts : Int) -> Options

#
Options::set_number_of_initial_partitions

fn Options::set_number_of_initial_partitions(self : Options, niparts : Int) -> Options

#
Options::set_number_of_iterations

fn Options::set_number_of_iterations(self : Options, niter : Int) -> Options

#
Options::set_number_of_separators

fn Options::set_number_of_separators(self : Options, nseps : Int) -> Options

#
Options::set_objective_type

fn Options::set_objective_type(self : Options, objective : ObjectiveType) -> Options

#
Options::set_on_disk

fn Options::set_on_disk(self : Options, enabled : Bool) -> Options

#
Options::set_partitioning_scheme

fn Options::set_partitioning_scheme(self : Options, scheme : PartitioningScheme) -> Options

#
Options::set_pruning_factor

fn Options::set_pruning_factor(self : Options, factor : Int) -> Options

#
Options::set_refinement_scheme

fn Options::set_refinement_scheme(self : Options, scheme : RefinementScheme) -> Options

#
Options::set_seed

fn Options::set_seed(self : Options, seed : Int) -> Options

#
OrderingResult

pub(all) struct OrderingResult {
perm : FixedArray[Int]
iperm : FixedArray[Int]
}

#
ParallelOrderingResult

pub(all) struct ParallelOrderingResult {
perm : FixedArray[Int]
iperm : FixedArray[Int]
sizes : FixedArray[Int]
}

#
PartitionResult

pub(all) struct PartitionResult {
objval : Int
part : FixedArray[Int]
}

#
PartitioningScheme

pub(all) enum PartitioningScheme {
RecursiveBisection
Kway
}

#
RefinementScheme

pub(all) enum RefinementScheme {
Fm
Greedy
SeparatorTwoSided
SeparatorOneSided
}

#
VertexSeparatorResult

pub(all) struct VertexSeparatorResult {
sepsize : Int
part : FixedArray[Int]
}

#
cache_friendly_reordering

fn cache_friendly_reordering(graph : CsrGraph, part : FixedArray[Int]) -> FixedArray[Int] raise MetisError

#
compute_vertex_separator

fn compute_vertex_separator(graph : CsrGraph, options? : Options) -> VertexSeparatorResult raise MetisError

#
mesh_to_dual

fn mesh_to_dual(mesh : Mesh, ncommon? : Int) -> CsrGraph raise MetisError

#
mesh_to_nodal

fn mesh_to_nodal(mesh : Mesh) -> CsrGraph raise MetisError

#
native_option_count

fn native_option_count() -> Int

#
node_nd

fn node_nd(graph : CsrGraph, options? : Options) -> OrderingResult raise MetisError

#
node_ndp

fn node_ndp(graph : CsrGraph, npes : Int, options? : Options) -> ParallelOrderingResult raise MetisError

#
node_refine

fn node_refine(graph : CsrGraph, vwgt : FixedArray[Int], where_part : FixedArray[Int], hmarker : FixedArray[Int], ubfactor : Float) -> FixedArray[Int] raise MetisError

#
part_graph_kway

fn part_graph_kway(graph : CsrGraph, nparts : Int, options? : Options, target_partition_weights? : FixedArray[Float], imbalance? : FixedArray[Float]) -> PartitionResult raise MetisError

#
part_graph_recursive

fn part_graph_recursive(graph : CsrGraph, nparts : Int, options? : Options, target_partition_weights? : FixedArray[Float], imbalance? : FixedArray[Float]) -> PartitionResult raise MetisError

#
part_mesh_dual

fn part_mesh_dual(mesh : Mesh, nparts : Int, ncommon? : Int, options? : Options, target_partition_weights? : FixedArray[Float], element_weights? : FixedArray[Int], element_sizes? : FixedArray[Int]) -> MeshPartitionResult raise MetisError

#
part_mesh_nodal

fn part_mesh_nodal(mesh : Mesh, nparts : Int, options? : Options, target_partition_weights? : FixedArray[Float], node_weights? : FixedArray[Int], node_sizes? : FixedArray[Int]) -> MeshPartitionResult raise MetisError

#
version

fn version() -> (Int, Int, Int)

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io