Skip to content

Commit 380b0a0

Browse files
committed
* get ready for pypi wheel setup
1 parent c3524d4 commit 380b0a0

8 files changed

Lines changed: 590 additions & 1 deletion

File tree

.github/workflows/wheels.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Build Wheels
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
tags: [ 'v*' ]
7+
pull_request:
8+
branches: [ main, master ]
9+
workflow_dispatch:
10+
11+
jobs:
12+
build_wheels:
13+
name: Build wheels on ${{ matrix.os }}
14+
runs-on: ${{ matrix.os }}
15+
strategy:
16+
matrix:
17+
os: [ubuntu-latest, macos-13, macos-14]
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
with:
22+
submodules: recursive
23+
24+
- name: Build wheels
25+
uses: pypa/cibuildwheel@v2.16
26+
env:
27+
CIBW_BUILD: cp38-* cp39-* cp310-* cp311-* cp312-*
28+
CIBW_SKIP: "*-musllinux_* *-win32 *-manylinux_i686"
29+
CIBW_ARCHS_LINUX: x86_64
30+
CIBW_ARCHS_MACOS: x86_64 arm64
31+
CIBW_BEFORE_BUILD: ./build.sh
32+
CIBW_BUILD_VERBOSITY: 1
33+
34+
- uses: actions/upload-artifact@v4
35+
with:
36+
name: wheels-${{ matrix.os }}
37+
path: ./wheelhouse/*.whl
38+
39+
build_sdist:
40+
name: Build source distribution
41+
runs-on: ubuntu-latest
42+
steps:
43+
- uses: actions/checkout@v4
44+
with:
45+
submodules: recursive
46+
47+
- name: Build sdist
48+
run: pipx run build --sdist
49+
50+
- uses: actions/upload-artifact@v4
51+
with:
52+
name: sdist
53+
path: dist/*.tar.gz
54+
55+
upload_pypi:
56+
needs: [build_wheels, build_sdist]
57+
runs-on: ubuntu-latest
58+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
59+
steps:
60+
- uses: actions/download-artifact@v4
61+
with:
62+
pattern: "*"
63+
path: dist
64+
merge-multiple: true
65+
66+
- uses: pypa/gh-action-pypi-publish@release/v1
67+
with:
68+
password: ${{ secrets.PYPI_API_TOKEN }}

CMakeLists.txt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,27 @@ foreach(tgt SharedMap sharedmap)
9494
set_target_properties(${tgt} PROPERTIES
9595
BUILD_RPATH "${KaHIP_ROOT}/lib;${MTK_LIBDIR}"
9696
)
97-
endforeach()
97+
endforeach()
98+
99+
# -------------------- Python Bindings --------------------
100+
if(SKBUILD)
101+
find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
102+
find_package(pybind11 CONFIG REQUIRED)
103+
104+
pybind11_add_module(_sharedmap python/sharedmap_bindings.cpp $<TARGET_OBJECTS:libsharedmap>)
105+
target_link_libraries(_sharedmap PRIVATE
106+
${KAHIP_LIBRARY}
107+
MtKaHyPar::mtkahypar
108+
Threads::Threads
109+
)
110+
target_link_options(_sharedmap PRIVATE
111+
"-Wl,--disable-new-dtags"
112+
"-Wl,-rpath-link,${MTK_LIBDIR}"
113+
)
114+
set_target_properties(_sharedmap PROPERTIES
115+
BUILD_RPATH "${KaHIP_ROOT}/lib;${MTK_LIBDIR}"
116+
INSTALL_RPATH "$ORIGIN"
117+
)
118+
119+
install(TARGETS _sharedmap LIBRARY DESTINATION sharedmap)
120+
endif()

MANIFEST.in

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
include README.md
2+
include LICENSE
3+
include pyproject.toml
4+
include CMakeLists.txt
5+
include build.sh
6+
recursive-include include *.h
7+
recursive-include lib *.cpp
8+
recursive-include src *.h *.cpp
9+
recursive-include python *.py *.cpp
10+
recursive-include extern/KaHIP *
11+
recursive-include extern/MtKaHyPar *
12+
recursive-include cmake *
13+
global-exclude *.pyc __pycache__ .git* build cmake-build-*

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,36 @@ The include files for the library are present in the `include` folder.
9191

9292
Usage
9393
-----------
94+
95+
### Python Interface
96+
97+
Install via pip:
98+
```bash
99+
pip install sharedmap
100+
```
101+
102+
Use in Python:
103+
```python
104+
import sharedmap as sm
105+
106+
# Define graph in CSR format
107+
v_weights = [1, 1, 1, 1, 1, 1, 1, 1]
108+
adj_ptrs = [0, 3, 6, 8, 12, 16, 19, 21, 22]
109+
adj_weights = [1] * 22
110+
adj = [1, 2, 3, 0, 3, 4, 0, 3, 0, 1, 2, 5, 1, 5, 6, 7, 3, 4, 6, 4, 5, 4]
111+
112+
# Partition
113+
comm_cost, partition = sm.partition_graph(
114+
v_weights, adj_ptrs, adj_weights, adj,
115+
hierarchy=[2, 2], distance=[1, 10],
116+
imbalance=0.03, n_threads=1
117+
)
118+
```
119+
120+
See [python/README.md](python/README.md) for detailed Python documentation.
121+
122+
### Command Line Interface
123+
94124
Call `SharedMap` in the `build` folder:
95125

96126
./build/SharedMap -g <inpath-graph> -m <outpath-parition> -h <hierarchy> -d <distance> -e <imbalance (e.g. 0.03)> -c {fast|eco|strong} -t <# threads> -s {naive|layer|queue|nb_layer} --seed <seed>

pyproject.toml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
[build-system]
2+
requires = ["scikit-build-core>=0.8", "pybind11>=2.11"]
3+
build-backend = "scikit_build_core.build"
4+
5+
[project]
6+
name = "sharedmap"
7+
version = "1.0.0"
8+
description = "Parallel shared-memory hierarchical process mapping"
9+
readme = "README.md"
10+
authors = [
11+
{name = "Henning Woydt", email = "henning.woydt@informatik.uni-heidelberg.de"}
12+
]
13+
license = {text = "MIT"}
14+
requires-python = ">=3.8"
15+
dependencies = [
16+
"numpy>=1.20"
17+
]
18+
keywords = ["graph-partitioning", "process-mapping", "parallel-computing", "hpc"]
19+
classifiers = [
20+
"Development Status :: 4 - Beta",
21+
"Intended Audience :: Science/Research",
22+
"License :: OSI Approved :: MIT License",
23+
"Programming Language :: Python :: 3",
24+
"Programming Language :: Python :: 3.8",
25+
"Programming Language :: Python :: 3.9",
26+
"Programming Language :: Python :: 3.10",
27+
"Programming Language :: Python :: 3.11",
28+
"Programming Language :: Python :: 3.12",
29+
"Programming Language :: C++",
30+
"Topic :: Scientific/Engineering",
31+
]
32+
33+
[project.urls]
34+
Homepage = "https://github.com/HenningWoydt/SharedMap"
35+
Repository = "https://github.com/HenningWoydt/SharedMap"
36+
Documentation = "https://github.com/HenningWoydt/SharedMap#readme"
37+
Issues = "https://github.com/HenningWoydt/SharedMap/issues"
38+
39+
[tool.scikit-build]
40+
cmake.build-type = "Release"
41+
cmake.verbose = false
42+
wheel.packages = ["python/sharedmap"]
43+
44+
[tool.scikit-build.cmake.define]
45+
SHAREDMAP_DOWNLOAD_TBB = "ON"
46+
CMAKE_POSITION_INDEPENDENT_CODE = "ON"
47+
48+
[tool.cibuildwheel]
49+
build-verbosity = 1
50+
build = "cp38-* cp39-* cp310-* cp311-* cp312-*"
51+
skip = "*-musllinux_* *-win32 *-manylinux_i686"
52+
before-build = "./build.sh"
53+
test-requires = "numpy"
54+
test-command = "python -c 'import sharedmap; print(sharedmap.__version__)'"
55+
56+
[tool.cibuildwheel.linux]
57+
archs = ["x86_64"]
58+
manylinux-x86_64-image = "manylinux2014"
59+
60+
[tool.cibuildwheel.macos]
61+
archs = ["x86_64", "arm64"]

python/README.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Python Installation
2+
3+
## From PyPI (once published)
4+
5+
```bash
6+
pip install sharedmap
7+
```
8+
9+
## From source
10+
11+
```bash
12+
# Clone the repository
13+
git clone https://github.com/HenningWoydt/SharedMap.git
14+
cd SharedMap
15+
16+
# Build dependencies first
17+
./build.sh
18+
19+
# Install Python package
20+
pip install .
21+
```
22+
23+
## Usage
24+
25+
```python
26+
import sharedmap as sm
27+
28+
# Define your graph in CSR format
29+
v_weights = [1, 1, 1, 1, 1, 1, 1, 1]
30+
adj_ptrs = [0, 3, 6, 8, 12, 16, 19, 21, 22]
31+
adj_weights = [1] * 22
32+
adj = [1, 2, 3, 0, 3, 4, 0, 3, 0, 1, 2, 5, 1, 5, 6, 7, 3, 4, 6, 4, 5, 4]
33+
34+
# Define hardware hierarchy and distances
35+
hierarchy = [2, 2] # 2 nodes, 2 cores per node
36+
distance = [1, 10] # distance within node: 1, between nodes: 10
37+
38+
# Partition the graph
39+
comm_cost, partition = sm.partition_graph(
40+
v_weights, adj_ptrs, adj_weights, adj,
41+
hierarchy, distance,
42+
imbalance=0.03,
43+
n_threads=1,
44+
seed=0
45+
)
46+
47+
print(f"Communication Cost: {comm_cost}")
48+
print(f"Partition: {partition}")
49+
```
50+
51+
## API Reference
52+
53+
### `partition_graph()`
54+
55+
Main function for graph partitioning.
56+
57+
**Parameters:**
58+
- `v_weights`: Vertex weights (array of integers >= 1)
59+
- `adj_ptrs`: CSR adjacency pointers (n+1 integers)
60+
- `adj_weights`: Edge weights (array of integers >= 1)
61+
- `adj`: CSR adjacency list
62+
- `hierarchy`: Hierarchy levels (e.g., [4, 8, 6])
63+
- `distance`: Communication distances (e.g., [1, 10, 100])
64+
- `imbalance`: Maximum allowed imbalance (default: 0.03)
65+
- `n_threads`: Number of threads (default: 1)
66+
- `seed`: Random seed (default: 0)
67+
- `strategy`: Thread distribution strategy (default: `Strategy.NB_LAYER`)
68+
- `parallel_alg`: Parallel algorithm (default: `Algorithm.MTKAHYPAR_QUALITY`)
69+
- `serial_alg`: Serial algorithm (default: `Algorithm.KAFFPA_STRONG`)
70+
- `verbose`: Print statistics (default: False)
71+
72+
**Returns:**
73+
- `comm_cost`: Communication cost J(C, D, PI)
74+
- `partition`: Partition assignment for each vertex (numpy array)
75+
76+
### Enums
77+
78+
**Strategy:**
79+
- `Strategy.NAIVE`
80+
- `Strategy.LAYER`
81+
- `Strategy.QUEUE`
82+
- `Strategy.NB_LAYER`
83+
84+
**Algorithm:**
85+
- `Algorithm.KAFFPA_FAST`
86+
- `Algorithm.KAFFPA_ECO`
87+
- `Algorithm.KAFFPA_STRONG`
88+
- `Algorithm.MTKAHYPAR_DEFAULT`
89+
- `Algorithm.MTKAHYPAR_QUALITY`
90+
- `Algorithm.MTKAHYPAR_HIGHEST_QUALITY`
91+
92+
### `validate_input()`
93+
94+
Validates input parameters before partitioning.
95+
96+
**Returns:** `bool` - True if input is valid, False otherwise.

0 commit comments

Comments
 (0)