Git Product home page Git Product logo

kahypar / mt-kahypar Goto Github PK

View Code? Open in Web Editor NEW
102.0 7.0 20.0 34.52 MB

Mt-KaHyPar (Multi-Threaded Karlsruhe Hypergraph Partitioner) is a shared-memory multilevel graph and hypergraph partitioner equipped with parallel implementations of techniques used in the best sequential partitioning algorithms. Mt-KaHyPar can partition extremely large hypergraphs very fast and with high quality.

License: MIT License

CMake 3.03% HTML 0.09% C++ 94.31% C 0.55% Perl 0.23% Python 1.70% Shell 0.09%
hypergraph-partitioning partitioning graph-partitioning hypergraphs graphs graph-algorithms hypergraph algorithm-engineering partitioning-algorithms shared-memory

mt-kahypar's Introduction

Mt-KaHyPar - Multi-Threaded Karlsruhe Graph and Hypergraph Partitioner

License Linux, MacOS & Windows Build Code Coverage Zenodo
License: MIT Build Status codecov DOI

Table of Contents

About Mt-KaHyPar

Mt-KaHyPar is a shared-memory algorithm for partitioning graphs and hypergraphs. The balanced (hyper)graph partitioning problem asks for a partition of the node set of a (hyper)graph into k disjoint blocks of roughly the same size (usually a small imbalance is allowed by at most 1 + ε times the average block weight), while simultaneously minimizing an objective function defined on the (hyper)edges. Mt-KaHyPar can optimize the cut-net, connectivity, sum-of-external-degrees, and Steiner tree metric (see Supported Objective Functions).

alt textalt text

The highest-quality configuration of Mt-KaHyPar computes partitions that are on par with those produced by the best sequential partitioning algorithms, while being almost an order of magnitude faster with only ten threads (e.g., when compared to KaFFPa or KaHyPar). Besides our high-quality configuration, we provide several other faster configurations that are already able to outperform most of the existing partitioning algorithms with regard to solution quality and running time. The figure below summarizes the time-quality trade-off of different hypergraph (left, connectivity metric) and graph partitioning algorithms (right, cut-net metric). The plot is based on an experiment with over 800 graphs and hypergraphs and relates the average solution quality and running time of each algorithm to the best achievable results. Points on the lower-left are considered better. Partially transparent markers indicate solvers producing more than 15% infeasible partitions (either imbalanced or timeout). For more details, we refer the reader to our publications.

time_quality_trade_off

Features

Besides its fast and high-quality partitioning algorithm, Mt-KaHyPar provides many other useful features:

  • Scalability: Mt-KaHyPar has excellent scaling behaviour (up to 25 with 64 threads), while increasing the number of threads does not adversely affect the solution quality.
  • Deterministic Partitioning: Mt-KaHyPar offers a deterministic partitioning algorithm, ensuring consistent solutions for the same input and random seed.
  • Large K Partitioning: We provide a partitioning configuration for partitioning (hyper)graphs into a large number of blocks (e.g., k > 1024).
  • Graph Partitioning: Mt-KaHyPar includes optimized data structures for graph partitioning, achieving a speedup by a factor of two for plain graphs.
  • Objective Functions: Mt-KaHyPar can optimize the cut-net, connectivity, and sum-of-external-degrees metric (for more details, see Supported Objective Functions)
  • Mapping (Hyper)Graphs Onto Graphs: In many applications of (hyper)graph partitioning, the blocks of a partition need to be assigned to architectures that can be represented as graphs. For instance, in parallel computations, the blocks may be assigned to processors on a computing cluster interconnected via communication links. It becomes advantageous to position nodes close to each other on the target graph if they are adjacent in the original (hyper)graph. However, conventional objective functions do not consider the topology of the target graph during partitioning. We therefore provide a mode that maps the nodes of a (hyper)graph onto the nodes of a target graph. During this process, the partitioning algorithm optimizes the Steiner tree metric. The objective here is to minimize the total weight of all minimal Steiner trees induced by the (hyper)edges of the hypergraph on the target graph. For more information about this metric, we refer the reader to the Supported Objective Functions section.
  • Fixed Vertices: Fixed vertices are nodes that are preassigned to a particular block and are not allowed to change their block during partitioning.

Requirements

The Multi-Threaded Karlsruhe Graph and Hypergraph Partitioning Framework requires:

  • A 64-bit Linux, MacOS, or Windows operating system.
  • A modern, C++17-ready compiler such as g++ version 7 or higher, clang version 11.0.3 or higher, or MinGW compiler on Windows (tested with version 12.1).
  • The cmake build system (>= 3.16).
  • The Boost - Program Options library and the boost header files (>= 1.48). If you don't want to install boost by yourself, you can add the -DKAHYPAR_DOWNLOAD_BOOST=On flag to the cmake command to download, extract, and build the necessary dependencies automatically.
  • The Intel Thread Building Blocks library (TBB, minimum required version is OneTBB 2021.5.0). If you don't want to install TBB by yourself, you can add the -DKAHYPAR_DOWNLOAD_TBB=On flag (only available on Linux) to the cmake command to download oneTBB 2021.7.0 and extract the necessary dependencies automatically. Mt-KaHyPar also compiles with older version of TBB. However, we observed unexpected behaviour of a TBB function on which we rely on which causes on our side a segmentation fault in really rare cases. If you want to ignore these warnings, you can add -DKAHYPAR_ENFORCE_MINIMUM_TBB_VERSION=OFF to the cmake build command.
  • The Portable Hardware Locality library (hwloc)

Linux

The following command will install most of the required dependencies on a Ubuntu machine:

sudo apt-get install libtbb-dev libhwloc-dev libboost-program-options-dev

MacOS

The following command will install most of the required dependencies on a MacOS machine:

brew install tbb boost hwloc

Windows

The following instructions set up the environment used to build Mt-KaHyPar on Windows machines:

  1. Download and install MSYS2 from the official website (https://www.msys2.org/).
  2. Launch the MSYS2 MinGW x64 terminal.
  3. Update the package manager database by running the following command:
pacman -Syu
  1. The following command will then install all required dependencies:
pacman -S make mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc mingw-w64-x86_64-python3 mingw-w64-x86_64-tbb
  1. Rename libtbb12.dll.a to libtbb.dll.a which is located in C:\msys64\mingw64\lib (or /mingw64/lib within the MSYS2 MinGW x64 terminal)

Please note that Mt-KaHyPar was primarily tested and evaluated on Linux machines. While a Windows build has been provided and tested on MSYS2 using pacman to install the required dependencies, we cannot provide any performance guarantees or ensure that the Windows version is free of bugs. At this stage, Windows support is experimental. We are happy to accept contributions to improve Windows support.

Building Mt-KaHyPar

To build Mt-KaHyPar, you can run the build.sh script (creates a build folder) or use the following commands:

  1. Clone the repository including submodules:

    git clone --depth=2 --recursive https://github.com/kahypar/mt-kahypar.git

  2. Create a build directory: mkdir build && cd build

  3. Only on Windows machines: export CMAKE_GENERATOR="MSYS Makefiles"

  4. Run cmake: cmake .. -DCMAKE_BUILD_TYPE=RELEASE (on Windows machines add -DKAHYPAR_DOWNLOAD_BOOST=On)

  5. Run make: make MtKaHyPar -j

The build produces the executable MtKaHyPar, which can be found in build/mt-kahypar/application/.

Running Mt-KaHyPar

To partition a hypergraph with our default configuration, you can use the following command:

./mt-kahypar/application/MtKaHyPar -h <path-to-hgr> --preset-type=default -t <# threads> -k <# blocks> -e <imbalance (e.g. 0.03)> -o km1

Partitioning Configurations

Mt-KaHyPar provides several partitioning configurations with different time-quality trade-offs. The configurations are stored in ini files located in the config folder. However, we recommend using the --preset-type command line parameter to run Mt-KaHyPar with a specific partitioning configuration:

--preset-type=<large_k/deterministic/default/quality/highest_quality>
  • large_k: configuration for partitioning (hyper)graphs into a large number of blocks (e.g. >= 1024 blocks, config/large_k_preset.ini)
  • deterministic: configuration for deterministic partitioning (config/deterministic_preset.ini, corresponds to Mt-KaHyPar-SDet in our publications)
  • default: computes good partitions very fast (config/default_preset.ini, corresponds to Mt-KaHyPar-D in our publications)
  • quality: computes high-quality partitions (config/quality_preset.ini, corresponds to Mt-KaHyPar-D-F in our publications)
  • highest_quality: highest-quality configuration (config/quality_flow_preset.ini, corresponds to Mt-KaHyPar-Q-F in our publications)

The presets can be ranked from lowest to the highest-quality as follows: large_k, deterministic, default, quality, and highest_quality. We recommend using the default configuration to compute good partitions very fast and the quality configuration to compute high-quality solutions. The highest_quality configuration computes better partitions than our quality configuration by 0.5% on average at the cost of a two times longer running time for medium-sized instances (up to 100 million pins). When you have to partition a (hyper)graph into a large number of blocks (e.g., >= 1024 blocks), you can use our large_k configuration. However, we only recommend using this if you experience high running times with one of our other configurations as this can significantly worsen the partitioning quality.

Objective Functions

Mt-KaHyPar can optimize the cut-net, connectivity, and sum-of-external-degrees metric (see Supported Objective Functions).

-o <cut/km1/soed>

Mapping (Hyper)Graphs onto Graphs

To map a (hyper)graph onto a target graph with Mt-KaHyPar, you can add the following command line parameters to the partitioning call:

-g <path-to-target-graph> -o steiner_tree

The target graph is expected to be in Metis format. The nodes of the (hyper)graph are then mapped onto the nodes of the target graph, while optimizing the Steiner tree metric (see Supported Objective Functions).

Graph Partitioning

To partition a graph with Mt-KaHyPar, you can add the following command line parameters to the partitioning call:

-h <path-to-graph> --instance-type=graph --input-file-format=<metis/hmetis> -o cut

Mt-KaHyPar then uses optimized data structures for graph partitioning, which speedups the partitioning time by a factor of two compared to our hypergraph partitioning code. Per default, we expect the input in hMetis format, but you can read graph files in Metis format via --input-file-format=metis.

Fixed Vertices

Fixed vertices are nodes that are preassigned to particular block and are not allowed to change their block during partitioning. Mt-KaHyPar reads fixed vertices from a file in the hMetis fix file format, which can be provided via the following command line parameter:

-f <path-to-fixed-vertex-file>

Note that fixed vertices are only supported in our default, quality, and highest_quality configurations.

Individual Target Block Weights

Per default, Mt-KaHyPar enforces that the weight of each block must be smaller than the average block weight (weight of the hypergraph divided by the number of blocks) times (1 + ε). However, you can provide individual target block weights for each block via

--part-weights=weight_of_block_0 weight_of_block_1 ... weight_of_block_k

Note that the sum of all individual target block weights must be larger than the total weight of all nodes.

Write Partition to Output File

To enable writing the partition to a file after partitioning, you can add the following command line parameters to the partitioning call:

--write-partition-file=true --partition-output-folder=<path/to/folder>

The partition file name is generated automatically based on parameters such as k, imbalance, seed and the input file name and will be located in the folder specified by --partition-output-folder. If you do not provide a partition output folder, the partition file will be placed in the same folder as the input hypergraph file.

Other Useful Program Options

There are several useful options that can provide you with additional insights during and after the partitioning process:

  • --verbose=true: Displays detailed information on the partitioning process
  • --show-detailed-timings=true: Shows detailed sub-timings of each phase of the algorithm at the end of partitioning
  • --enable-progress-bar=true: Shows a progress bar during the coarsening and refinement phase

If you want to change other configuration parameters manually, please run --help for a detailed description of the different program options.

The C Library Interface

We provide a simple C-style interface to use Mt-KaHyPar as a library. The library can be built and installed via

make install.mtkahypar # use sudo (Linux & MacOS) or run shell as an administrator (Windows) to install system-wide

Note: When installing locally, the build will exit with an error due to missing permissions. However, the library is still built successfully and is available in the build folder.

The library interface can be found in include/libmtkahypar.h with a detailed documentation. We also provide several examples in the folder lib/examples that show how to use the library.

Here is a short example of how you can partition a hypergraph using our library interface:

#include <memory>
#include <vector>
#include <iostream>
#include <thread>

#include <libmtkahypar.h>

int main(int argc, char* argv[]) {

  // Initialize thread pool
  mt_kahypar_initialize_thread_pool(
    std::thread::hardware_concurrency() /* use all available cores */,
    true /* activate interleaved NUMA allocation policy */ );

  // Setup partitioning context
  mt_kahypar_context_t* context = mt_kahypar_context_new();
  mt_kahypar_load_preset(context, DEFAULT /* corresponds to MT-KaHyPar-D */);
  // In the following, we partition a hypergraph into two blocks
  // with an allowed imbalance of 3% and optimize the connective metric (KM1)
  mt_kahypar_set_partitioning_parameters(context,
    2 /* number of blocks */, 0.03 /* imbalance parameter */,
    KM1 /* objective function */);
  mt_kahypar_set_seed(42 /* seed */);
  // Enable logging
  mt_kahypar_set_context_parameter(context, VERBOSE, "1");

  // Load Hypergraph for DEFAULT preset
  mt_kahypar_hypergraph_t hypergraph =
    mt_kahypar_read_hypergraph_from_file(
      "path/to/hypergraph/file", DEFAULT, HMETIS /* file format */);

  // Partition Hypergraph
  mt_kahypar_partitioned_hypergraph_t partitioned_hg =
    mt_kahypar_partition(hypergraph, context);

  // Extract Partition
  std::unique_ptr<mt_kahypar_partition_id_t[]> partition =
    std::make_unique<mt_kahypar_partition_id_t[]>(mt_kahypar_num_hypernodes(hypergraph));
  mt_kahypar_get_partition(partitioned_hg, partition.get());

  // Extract Block Weights
  std::unique_ptr<mt_kahypar_hypernode_weight_t[]> block_weights =
    std::make_unique<mt_kahypar_hypernode_weight_t[]>(2);
  mt_kahypar_get_block_weights(partitioned_hg, block_weights.get());

  // Compute Metrics
  const double imbalance = mt_kahypar_imbalance(partitioned_hg, context);
  const double km1 = mt_kahypar_km1(partitioned_hg);

  // Output Results
  std::cout << "Partitioning Results:" << std::endl;
  std::cout << "Imbalance         = " << imbalance << std::endl;
  std::cout << "Km1               = " << km1 << std::endl;
  std::cout << "Weight of Block 0 = " << block_weights[0] << std::endl;
  std::cout << "Weight of Block 1 = " << block_weights[1] << std::endl;

  mt_kahypar_free_context(context);
  mt_kahypar_free_hypergraph(hypergraph);
  mt_kahypar_free_partitioned_hypergraph(partitioned_hg);
}

To compile the program using g++ run:

g++ -std=c++17 -DNDEBUG -O3 your_program.cc -o your_program -lmtkahypar

To execute the binary, you need to ensure that the installation directory (probably /usr/local/lib (Linux) and C:\Program Files (x86)\MtKaHyPar\bin (Windows) for system-wide installation) is included in the dynamic library path. The path can be updated on Linux with:

LD_LIBRARY_PATH="$LD_LIBRARY_PATH;/usr/local/lib"
export LD_LIBRARY_PATH

On Windows, add C:\Program Files (x86)\KaHyPar\bin to PATH in the environment variables settings.

To remove the library from your system use the provided uninstall target:

make uninstall-mtkahypar

Note that we internally use different data structures to represent a (hyper)graph based on the corresponding configuration (mt_kahypar_preset_type_t). The mt_kahypar_hypergraph_t structure stores a pointer to this data structure and also a type description. Therefore, you can not partition a (hyper)graph with all available configurations once it is loaded or constructed. However, you can check the compatibility of a hypergraph with a configuration with the following code:

mt_kahypar_context_t context = mt_kahypar_context_new();
mt_kahypar_load_preset(context, QUALITY);
// Check if the hypergraph is compatible with the QUALITY preset
if ( mt_kahypar_check_compatibility(hypergraph, QUALITY) ) {
  mt_kahypar_partitioned_hypergraph_t partitioned_hg =
    mt_kahypar_partition(hypergraph, context);
}

The Python Library Interface

You can install the Python library interface via

make mtkahypar_python

This will create a shared library in the build/python folder (mtkahypar.so on Linux and mtkahypar.pyd on Windows). Copy the libary to your Python project directory to import Mt-KaHyPar as a Python module.

A documentation of the Python module can be found in python/module.cpp, or by importing the module (import mtkahypar) and calling help(mtkahypar) in Python. We also provide several examples that show how to use the Python interface in the folder python/examples.

Here is a short example of how you can partition a hypergraph using our Python interface:

import multiprocessing
import mtkahypar

# Initialize thread pool
mtkahypar.initializeThreadPool(multiprocessing.cpu_count()) # use all available cores

# Setup partitioning context
context = mtkahypar.Context()
context.loadPreset(mtkahypar.PresetType.DEFAULT) # corresponds to Mt-KaHyPar-D
# In the following, we partition a hypergraph into two blocks
# with an allowed imbalance of 3% and optimize the connectivity metric
context.setPartitioningParameters(
  2,                       # number of blocks
  0.03,                    # imbalance parameter
  mtkahypar.Objective.KM1) # objective function
mtkahypar.setSeed(42)      # seed
context.logging = True     # enables partitioning output

# Load hypergraph from file
hypergraph = mtkahypar.Hypergraph(
  "path/to/hypergraph/file", # hypergraph file
  mtkahypar.FileFormat.HMETIS) # hypergraph is stored in hMetis file format

# Partition hypergraph
partitioned_hg = hypergraph.partition(context)

# Output metrics
print("Partition Stats:")
print("Imbalance = " + str(partitioned_hg.imbalance()))
print("km1       = " + str(partitioned_hg.km1()))
print("Block Weights:")
print("Weight of Block 0 = " + str(partitioned_hg.blockWeight(0)))
print("Weight of Block 1 = " + str(partitioned_hg.blockWeight(1)))

We also provide an optimized graph data structure for partitioning plain graphs. The following example loads and partitions a graph:

# Load graph from file
graph = mtkahypar.Graph(
  "path/to/graph/file", # graph file
  mtkahypar.FileFormat.METIS) # graph is stored in Metis file format

# Partition graph
partitioned_graph = graph.partition(context)

Note that for partitioning hypergraphs into a large number of blocks (e.g., k > 1024), we recommend using the LARGE_K configuration and the partitionIntoLargeK(...) function. Using a different configuration for large k partitioning may cause excessive memory usage and high running times, depending on the size of the hypergraph and the memory capacity of your target machine. For partitioning plain graphs, you can load the LARGE_K configuration, but you can still use the partition(...) function of the graph object. Here is an example that partitions a hypergraph into 1024 blocks:

# Setup partitioning context
context = mtkahypar.Context()
context.loadPreset(mtkahypar.PresetType.LARGE_K)
# In the following, we partition a hypergraph into 1024 blocks
# with an allowed imbalance of 3% and optimize the connectivity metric
context.setPartitioningParameters(1024, 0.03, mtkahypar.Objective.KM1, 42)

# Load and partition hypergraph
hypergraph = mtkahypar.Hypergraph("path/to/hypergraph/file", mtkahypar.FileFormat.HMETIS)
partitioned_hg = hypergraph.partitionIntoLargeK(context)

Supported Objective Functions

Mt-KaHyPar can optimize several objective functions which we explain in the following in more detail.

Cut-Net Metric

cut_net

The cut-net metric is defined as total weight of all nets spanning more than one block of the partition Π (also called cut nets).

Connectivity Metric

connectivity

The connectivity metric additionally multiplies the weight of each cut net with the number of blocks λ(e) spanned by that net minus one. Thus, the connectivity metric tries to minimize the number of blocks connected by each net.

Sum-of-external-Degrees Metric

soed

The sum-of-external-degrees metric is similar to the connectivity metric, but does not subtract one from the number of blocks λ(e) spanned by a net. A peculiarity of this objective function is that removing a net from the cut reduces the metric by 2ω(e), while reducing the connectivity by one reduces the metric only by ω(e). Thus, the objective function prefers removing nets from the cut, while as a secondary criterion, it tries to reduce the connectivity of the nets.

Steiner Tree Metric

steiner_tree

The Steiner tree metric is the most versatile metric that we provide at the moment. A Steiner tree is a tree with minimal weight that connects a subset of the nodes on a graph (a more detailed definition can be found here). For a subset with exactly two nodes, finding a Steiner tree reverts to computing the shortest path between the two nodes. When optimizing the Steiner tree metric, we map the node set of a hypergraph H onto the nodes of a target graph G. The objective is to minimize the total weight of all Steiner trees induced by the nets of H on G. For a net e, dist(Λ(e)) is the weight of the minimal Steiner tree connecting the blocks Λ(e) spanned by net e on G. The Steiner tree metric can be used to accurately model wire-lengths in VLSI design or communication costs in distributed systems when some processors do not communicate with each other directly or with different speeds.

Note that finding a Steiner tree is an NP-hard problem. We therefore enforce a strict upper bound on the number of nodes of the target graph G which are 64 nodes at the moment. If you want to map a hypergraph onto larger target graphs, you can use recursive multisectioning. For example, if you want to map a hypergraph onto a graph with 4096 nodes, you can first partition the hypergraph into 64 blocks, and then map each block of the partition onto a subgraph of the target graph with 64 nodes. We plan to integrate this technique into Mt-KaHyPar in the future.

Custom Objective Functions

We have implemented a common interface for all gain computation techniques that we use in our refinement algorithms. This enables us to extend Mt-KaHyPar with new objective functions without having to modify the internal implementation of the refinement algorithms. A step-by-step guide on how you can implement your own objective function can be found here.

Improving Compile Times

Mt-KaHyPar implements several graph and hypergraph data structures, and supports different objective functions. Each combination of (hyper)graph data structure and objective function is passed to our partitioning algorithms as template parameters. This increases the compile time of Mt-KaHyPar. We therefore provide cmake command line options to disable some of the features of Mt-KaHyPar for faster compilation. The following list summarizes the available parameters:

-DKAHYPAR_ENABLE_GRAPH_PARTITIONING_FEATURES=On/Off # enables/disables graph partitioning features
-DKAHYPAR_ENABLE_HIGHEST_QUALITY_FEATURES=On/Off # enables/disables our highest-quality configuration
-DKAHYPAR_ENABLE_LARGE_K_PARTITIONING_FEATURES=On/Off # enables/distables large k partitioning features
-DKAHYPAR_ENABLE_SOED_METRIC=On/Off # enables/disables sum-of-external-degrees metric
-DKAHYPAR_ENABLE_STEINER_TREE_METRIC=On/Off # enables/disables Steiner tree metric

If you turn off all features, only the deterministic, default, and quality configurations are available for optimizing the cut-net or connectivity metric. Using a disabled feature will throw an error. Note that you can only disable the features in our binary, not in the C and Python interface.

Bug Reports

We encourage you to report any problems with Mt-KaHyPar via the github issue tracking system of the project.

Licensing

Mt-KaHyPar is a free software provided under the MIT License. For more information see the LICENSE file. We distribute this framework freely to foster the use and development of hypergraph partitioning tools. If you use Mt-KaHyPar in an academic setting please cite the appropriate papers.

// Mt-KaHyPar-D
@inproceedings{MT-KAHYPAR-D,
  title     = {Scalable Shared-Memory Hypergraph Partitioning},
  author    = {Gottesbüren, Lars and
               Heuer, Tobias and
               Sanders, Peter and
               Schlag, Sebastian},
  booktitle = {23rd Workshop on Algorithm Engineering and Experiments (ALENEX 2021)},
  pages     = {16--30},
  year      = {2021},
  publisher = {SIAM},
  doi       = {10.1137/1.9781611976472.2},
}

// Mt-KaHyPar-Q
@inproceedings{MT-KAHYPAR-Q,
  title     = {Shared-Memory $n$-level Hypergraph Partitioning},
  author    = {Lars Gottesb{\"{u}}ren and
               Tobias Heuer and
               Peter Sanders and
               Sebastian Schlag},
  booktitle = {24th Workshop on Algorithm Engineering and Experiments (ALENEX 2022)},
  year      = {2022},
  publisher = {SIAM},
  month     = {01},
  doi       = {10.1137/1.9781611977042.11}
}

// Mt-KaHyPar-Q-F
@inproceedings{MT-KaHyPar-Q-F,
  title       =	{Parallel Flow-Based Hypergraph Partitioning},
  author      =	{Lars Gottesb\"{u}ren and
                 Tobias Heuer and
                 Peter Sanders},
  booktitle   =	{20th International Symposium on Experimental Algorithms (SEA 2022)},
  pages       =	{5:1--5:21},
  year        =	{2022},
  volume      =	{233},
  publisher   =	{Schloss Dagstuhl -- Leibniz-Zentrum f{\"u}r Informatik},
  doi         =	{10.4230/LIPIcs.SEA.2022.5}
}

// Deterministic Partitioning
@inproceedings{MT-KAHYPAR-SDET,
  author    = {Lars Gottesb{\"{u}}ren and
               Michael Hamann},
  title     = {Deterministic Parallel Hypergraph Partitioning},
  booktitle = {European Conference on Parallel Processing (Euro-Par)},
  volume    = {13440},
  pages     = {301--316},
  publisher = {Springer},
  year      = {2022},
  doi       = {10.1007/978-3-031-12597-3\_19},
}

// Unconstrained Refinement (Under Review)
@article{MT-KAHYPAR-UNCONSTRAINED,
  title       = {Parallel Unconstrained Local Search for Partitioning Irregular Graphs},
  author      = {Nikolai Maas and
                 Lars Gottesb{\"{u}}ren and
                 Daniel Seemaier},
  institution = {Karlsruhe Institute of Technology},
  year        = {2023},
  url         = {https://arxiv.org/abs/2308.15494}
}

// Dissertation of Lars Gottesbüren
@phdthesis{MT-KAHYPAR-DIS-GOTTESBUEREN,
  author         = {Lars Gottesb\"{u}ren},
  year           = {2023},
  title          = {Parallel and Flow-Based High-Quality Hypergraph Partitioning},
  doi            = {10.5445/IR/1000157894},
  pagetotal      = {256},
  school         = {Karlsruhe Institute of Technology}
}

// Dissertation of Tobias Heuer
@phdthesis{MT-KAHYPAR-DIS-HEUER,
    author       = {Heuer, Tobias},
    year         = {2022},
    title        = {Scalable High-Quality Graph and Hypergraph Partitioning},
    doi          = {10.5445/IR/1000152872},
    pagetotal    = {242},
    school       = {Karlsruhe Institute of Technology}
}

// Mt-KaHyPar Journal Paper (Under Review)
@article{MT-KAHYPAR-JOURNAL,
  title       = {Scalable High-Quality Hypergraph Partitioning},
  author      = {Lars Gottesb{\"u}ren and
                 Tobias Heuer and
                 Nikolai Maas and
                 Peter Sanders and
                 Sebastian Schlag},
  institution = {Karlsruhe Institute of Technology},
  year        = {2023},
  url         = {https://arxiv.org/abs/2303.17679}
}

Contributing

If you are interested in contributing to the Mt-KaHyPar framework feel free to contact us or create an issue on the issue tracking system.

mt-kahypar's People

Contributors

danielseemaier avatar hydai avatar kittobi1992 avatar larsgottesbueren avatar n-maas avatar noahares avatar patricksteil avatar picsel2 avatar uulm-janbaudisch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

mt-kahypar's Issues

Upper bound of cut between two blocks

Hi,
Is there a data structure that records the total cuts between two blocks?
I want to avoid a very large cut between the two blocks after the partition. So I want to get the total cut value between each two blocks dynamically, and modify the gain function according to this cut.

In other words, I hope to optimize the cut objective while keeping the total cut between blocks within the upper bound. Is there any way to deal with this situation?

thanks!

Finalize README

Missing sections:

  1. What is Mt-KaHyPar: Description of Mt-KaHyPar with experimental results
  2. System Requirements
  3. Describe Library Interface

print node partitioning information

Hi, I am wondering if mt-kahypar can print out information of each node belongs to which partition into a file?
If yes, where should I add codes or use which execution command parameters. Actually I try to use --verbose=true --enable-progress-bar=true --partition-output-folder=. All of them did not give me an output result file.

Best effort partitions?

Hey,
I am trying to use this as part of a larger application that is somewhat time constraint.
The partitioning is usually fast enough but sometimes stalls for hours. Is there a
way to set a timeout and just use the best partition found so far?
This can even happen on different runs when the input graph is the same,
is that normal behavior or am I doing anything wrong?
Thanks!

make mtkahypar fatal error "utils/debug.hpp: no such file or directory"

Dear developers,

Under Ubuntu 23.04 and GCC 13.2 I am getting the following fatal error after running make mtkahypar:


In file included from /home/X/Documents/mt-kahypar/external_tools/growt/data-structures/table_config.hpp:6,

                 from /home/X/Documents/mt-kahypar/mt-kahypar/partition/mapping/target_graph.h:40,

                 from /home/X/Documents/mt-kahypar/lib/libmtkahypar.cpp:39:

`/home/X/Documents/mt-kahypar/external_tools/growt/data-structures/element_types/complex_slot.hpp:8:10: fatal error: utils/debug.hpp: No such file or directory

    8 | #include "utils/debug.hpp"
      |          ^~~~~~~~~~~~~~~~~


Any hint of what could have been happening?

Thank you in advance.

Tests are not running in Travis CI

Problem Description:
Travis sets up a VM with 2 cores on an Cloud Infrastructure. The Cloud Infrastructure Provider deploy that VM on a machine with a restricted cpuset. Our application does not consider that cpuset and tries to pin threads on cpus that are disabled.

Steps to reproduce:
sudo cset shield -c 1-3 # Restricts cpuset to cpu 1 - 3

make concurrent_hypergraph_test
Running main() from /home/heuer/mt-kahypar/external_tools/googletest/googletest/src/gtest_main.cc
[==========] Running 25 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 25 tests from AConcurrentHypergraph
[ERROR] Failed to set thread affinity

sudo cset shield --reset # reset cpuset restriction

Force coarsening to reach contraction limit

Aborting coarsening before reaching the contraction limit can have a significant impact on the performance and scalability of the initial partitioning. There are 3 main reasons why contraction limit is not reach during coarsening:

1.) Maximum allowed hypernode weight prevents valid contractions
Currently, the maximum allowed contraction limit is set to total weight of the hypergraph divided by the contraction limit. The rational behind this is, that if the contraction limit is reached than each node should have the same weight. However, in case of social instances a majority of the hypernodes are matched to their high degree center nodes. The current maximum allowed node weight is in that case to restrictive and needs to be relaxed. One idea could be to incorporate the sum of the weight of the neighborhood of the node with the highest degree, which somehow guarantees that each hypernode can be matched with its corresponding center node. This should be inline with the maximum allowed block weight.

2.) Zero-degree vertices introduce size-one communities (see wb-edu.mtx.hgr)
We should remove all zero-degree vertices before partitioning and add them afterwards with a bin-packing heuristic to the partition. Moreover, after single-pin hyperedges are removed, we should perform an additional check for zero-degree vertices.

3.) Many small communities (see DAC2012 instances)
In case, we have many small isolated communities, it can be hard for coarsening to reach contraction limit. One idea could be to merge small communities into a big one and if during coarsening no further contraction is possible (because all vertices have degree zero), than we should randomly contract the hypernodes.

Maintenance of border vertices is buggy

Example:
State before move:
he = 1 pin_count_in_from_part = 2 pin_count_in_to_part = 2 edge_size = 4
u = 3 from = 1 to = 0
v = 4 from = 1 to = 0
he = 1 pin_count_in_from_part_after = 0 pin_count_in_to_part_after = 3 edge_size = 4
he = 1 pin_count_in_from_part_after = 1 pin_count_in_to_part_after = 4 edge_size = 4

In this example, vertices 3 and 4 move from block 1 to block 0 in parallel. Hyperedge 1 has 4 pins. After moving both vertices to block 0 he 1 is a non-cut hyperedge. However, a hyperedge becomes a non-cut hyperedge if
1.) pin_count_in_from_part_after == 0
2.) pin_count_in_to_part_after == edge_size
In the example above this condition is not triggered.

Building from release tarball fails

Mt-KaHyPar can not be built from the release tarball because the directories of git submodules are not populated:

3 errors found in build log:
     13    -- Detecting C compile features
     14    -- Detecting C compile features - done
     15    -- Performing Test CMAKE_HAVE_LIBC_PTHREAD
     16    -- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
     17    -- Found Threads: TRUE
     18    -- Found Threads:
  >> 19    CMake Error at CMakeLists.txt:17 (add_subdirectory):
     20      The source directory
     21    
     22        /tmp/sebastian/spack-stage/spack-stage-mt-kahypar-1.0.0-edfz2bj2yxmuclvzq2lufvyy3eskovxd/spack-src/external_tools/googletest
     23    
     24      does not contain a CMakeLists.txt file.
     25    

     ...

     38    -- Default linker
     39    -- Performing Test KAHYPAR_HAS_CRC32
     40    -- Performing Test KAHYPAR_HAS_CRC32 - Success
     41    -- CMAKE_CXX_FLAGS:  -W -Wall -Wextra  -Wunused  -Wuninitialized -Wfatal-errors -Wcast-qual -Woverloaded-virtual -Wredundant-decls -Winit-self -pedantic -DPARANOID  -Wno-unused-function -pthread -
           std=c++17 -ltbb -ltbbmalloc_proxy -msse4.2 -mcrc32
     42    -- CMAKE_CXX_FLAGS_RELEASE: -O3 -DNDEBUG -O3 -mtune=native -march=native
     43    -- CMAKE_CXX_FLAGS_DEBUG: -g -g3 -fsanitize=undefined -fno-omit-frame-pointer -fsanitize=address
  >> 44    CMake Error at python/CMakeLists.txt:9 (add_subdirectory):
     45      The source directory
     46    
     47        /tmp/sebastian/spack-stage/spack-stage-mt-kahypar-1.0.0-edfz2bj2yxmuclvzq2lufvyy3eskovxd/spack-src/python/pybind11
     48    
     49      does not contain a CMakeLists.txt file.
     50    
     51    
  >> 52    CMake Error at python/CMakeLists.txt:11 (pybind11_add_module):
     53      Unknown CMake command "pybind11_add_module".
     54    
     55    
     56    -- Configuring incomplete, errors occurred!
     57    See also "/tmp/sebastian/spack-stage/spack-stage-mt-kahypar-1.0.0-edfz2bj2yxmuclvzq2lufvyy3eskovxd/spack-build-edfz2bj/CMakeFiles/CMakeOutput.log".

glibc++.so.6 version

image
Hi,

When I build and compile, I run mt-kahypar executable, I got this runtime error. I have no root access, how could I change its system link to my user path which I prepare a 30 higher version library.

Problems with TBB 2021 Versions

The releases of TBB from 2021 no longer contain some headers we use:

For now the Ubuntu Repos all provide the 2020 Versions of TBB, but rolling release distros already use the 2021 version, which Ubuntu will eventually use, too.

Make EPS and MAX_ITERATION in PLM configurable

We should make epsilon and max iteration in PLM configurable in context.h

See line 114 in plm.h:
for (int currentRound = 0; nodesMovedThisRound >= 0.01 * G.numNodes() && currentRound < 16; currentRound++)

Compile a static executable program

Hi,
I am trying to compile a static executable program that can run in different Linux environments,
However, I found it difficult to compile static programs because of the TBB library.
Is there a method for compiling static programs? Or is there any suggestion to run the program in different environments.

thanks!

Test execution

When a test fails, its binary gets deleted, so I cannot run it, in for example a debugger.
Additionally we can't use --gtest_filter= to run some tests by themselves.

Refactor Hypergraph

Since we are now able to perform n-Level as well as multilevel hypergraph partitioning, we should have one dynamic hypergraph and one static hypergraph.

Implement better Work Stealing for Initial Partitioning

When doing recursion during initial partitioning we split the TBB Numa Arena with half the number of threads of the original arena and pass them into the recursion. However, this introduces somehow bad load balancing, in case one recursion terminates earlier than the other, because threads are not able to join the other recursion (number of threads are limited).

IHypergraphSparsifier is missing a public virtual destructor

Hello!

We are writing a student project that uses the C interface and noticed that our application randomly freezes at global destruction. Throwing AddressSanitizer at the problem we got this report:

==11666==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x619000006980 in thread T1:
  object passed to delete has wrong type:
  size of the allocated type:   1032 bytes;
  size of the deallocated type: 16 bytes.
    #0 0x7fa7770bc0a8 in operator delete(void*, unsigned long) (/lib64/libasan.so.8+0xbc0a8)
    #1 0x7fa7769f5f71 in tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerTraits>::process_bypass_loop(tbb::internal::context_guard_helper<false>&, tbb::task*, long) ../../src/tbb/custom_scheduler.h:495
    #2 0x7fa7769f63b1 in tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerTraits>::local_wait_for_all(tbb::task&, tbb::task*) ../../src/tbb/custom_scheduler.h:636
    #3 0x7fa7769efbf6 in tbb::internal::arena::process(tbb::internal::generic_scheduler&) ../../src/tbb/arena.cpp:196
    #4 0x7fa7769ee31f in tbb::internal::market::process(rml::job&) ../../src/tbb/market.cpp:667
    #5 0x7fa7769ea26d in tbb::internal::rml::private_worker::run() ../../src/tbb/private_server.cpp:266
    #6 0x7fa7769ea4c8 in tbb::internal::rml::private_worker::thread_routine(void*) ../../src/tbb/private_server.cpp:219
    #7 0x7fa776a8e14c in start_thread (/lib64/libc.so.6+0x8b14c)
    #8 0x7fa776b0f9ff in clone3 (/lib64/libc.so.6+0x10c9ff)

0x619000006980 is located 0 bytes inside of 1032-byte region [0x619000006980,0x619000006d88)
allocated by thread T0 here:
    #0 0x7fa7770bb1a8 in operator new(unsigned long) (/lib64/libasan.so.8+0xbb1a8)
    #1 0x7fa7765e0ca0 in mt_kahypar::register_HypergraphUndefinedSparsifier::{lambda(mt_kahypar::Context const&)#1}::_FUN(mt_kahypar::Context const) (/home/sebastian/.local/opt/spack/opt/spack/linux-fedora37-haswell/gcc-12.2.1/mt-kahypar-master-bzm4vfxnyju3gqam4v3dqokbksb3ufav/lib64/libmtkahyparhgp.so+0x1e0ca0)

Thread T1 created by T0 here:
    #0 0x7fa77704b3e6 in __interceptor_pthread_create (/lib64/libasan.so.8+0x4b3e6)
    #1 0x7fa7769ea155 in rml::internal::thread_monitor::launch(void* (*)(void*), void*, unsigned long) ../../src/tbb/../rml/server/thread_monitor.h:218
    #2 0x7fa7769ea155 in tbb::internal::rml::private_worker::wake_or_launch() ../../src/tbb/private_server.cpp:297
    #3 0x7fa7769ea155 in tbb::internal::rml::private_server::wake_some(int) ../../src/tbb/private_server.cpp:395
    #4 0x60c000001e3f  (<unknown module>)

SUMMARY: AddressSanitizer: new-delete-type-mismatch (/lib64/libasan.so.8+0xbc0a8) in operator delete(void*, unsigned long)
==11666==HINT: if you don't care about these errors you may set ASAN_OPTIONS=new_delete_type_mismatch=0
==11666==ABORTING

I think that this stems from mt_kahypar::IHypergraphSparsifier not having a public virtual destructor.

TBB Internal NUMA Support

As of recently, TBB provides NUMA support in its task arenas -- i.e. one arena per socket, pinning threads that joined the arena to the corresponding socket and such nice things.
We should consider using their integrated support instead of Tobi's custom code for two reasons: 1) less code for us to maintain, 2) might be faster.
Open question: can we still mock hardware topology? This is desirable for testing purposes.

Edit: Apparently TBB uses hwloc to parse hardware topology info. Hence, mocking topology sounds quite possible.

Localized Label Propagation

Currently label propagation is executed not on each level of the n-level hierarchy. Whether LP is executed or not on the current level is determined by an execution policy. An other approach is to execute label propagation on each level by performing a strongly localized version of LP only on the uncontracted hypernodes. Since, this would not scale in case we only uncontract only one pair of hypernodes, this should be an feature of the batch uncontraction mode.

Visualization for Memory Consumption

Would be nice, if we would have some visual representation of the memory consumption of our hypergraphs. The SDSL has there some nice concept by serializing the data structure in a tree structure enhanced with size information and writing out some visual representation in form of a pie chart using java script library "D3".

Eliminate singletons

We use singletons way too much and they're not particularly "parallel-friendly". In many cases they can simply be replaced by a member. This makes it easier to use certain things in parallel, e.g., Randomize, which currently sometimes requires requesting a processor ID.

Heavy Assertions

Instead of enabling certain assertions for phases via CMake, we could use a single HEAVY_ASSERTION macro that looks up a variable similar to the way the KaHyPar logger does.
What do you think @kittobi1992 ?

hmod.precompute_attributes removes or does not remove singletons based off of the OS (inconsistent behaviour)

Depending on which OS is being used the following will print different results:

import hypernetx as hnx
import hypernetx.algorithms.hypergraph_modularity as hmod
formulaDict,stringTree = readFile("./CDL-FMINCE/toybox.dimacs") # code by me
H=formulaToHypergraph(formulaDict)
HDual = H.dual()
H=hmod.precompute_attributes(H)
HDual = hmod.precompute_attributes(HDual)

#this should diverge based off of OS

print(len(list(H.nodes())))
print(len(list(HDual.nodes())))

On the linux systems the results are 544 and 590, while on Windows I get 175 and 221.

I was using ANTLR4 with python integration to parse a dimacs (SAT) file and interpret it as a hypergraph. The resulting graph has 544 nodes and 590 edges before the attributes are computed.

Compared Systems

Ubuntu system:

  • Ubuntu 20.04.6 LTS
  • wsl 2
  • Python 3.8.10
  • pip installation manager

Debian

  • SMP Debian 5.10.127-1
  • Python 3.9.2
  • pip installation manager

Windows

  • Windows 10 Home
  • Python 3.11.3
  • Anaconda virtual environment (+VSCode)

How to build this if my TBB is installed in my user customized path?

I build TBB from source and install it under my user home directory, let's say /home/xxx/tbb/include and /home/xxx/tbb/lib64. And I also add this two path into my ~/.bashrc file append after variable PATH and LD_LIBRARY_PATH. Then I source this file also.

But when I build mt-kahypar with cmake .., it still shows cannot find TBB package. How should I solve it?

Btw, my gcc version is 12.0

Union by Weight broken for multilevel coarsening

As discussed today: Using union by weight to identify representatives in multilevel coarsening only works as expected for the first level. As soon as the weights change, things might break.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.