Skip to content

Commit 3f64ddc

Browse files
copy of my private repo
1 parent 34ef6ac commit 3f64ddc

29 files changed

+4781
-2
lines changed

CMakeLists.txt

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#IMPORTANT: Use the cmake flag -DCMAKE_CXX_COMPILER=/path/to/your/nvcc_wrapper
2+
cmake_minimum_required(VERSION 3.18)
3+
project(jetpartition CXX)
4+
set(CMAKE_CXX_STANDARD 17)
5+
set(CMAKE_CXX_STANDARD_REQUIRED True)
6+
7+
#ALL DEVICE BUILDS
8+
find_package(KokkosKernels REQUIRED)
9+
add_compile_options(-O3 -Wall -Wextra -Wshadow)
10+
#add_compile_options(-g -DDEBUG)
11+
12+
add_executable(jet partition.cpp)
13+
add_executable(jet4 partition.cpp)
14+
add_executable(jet2 partition.cpp)
15+
add_executable(jet_host partition.cpp)
16+
add_executable(jet_import partition.cpp)
17+
add_executable(jet_export partition.cpp)
18+
add_executable(jet_serial partition.cpp)
19+
add_executable(pstat part_eval.cpp)
20+
21+
target_compile_definitions(jet PUBLIC HASHMAP_P)
22+
target_compile_definitions(jet4 PUBLIC HASHMAP_P FOUR9)
23+
target_compile_definitions(jet2 PUBLIC HASHMAP_P TWO9)
24+
target_compile_definitions(jet_host PUBLIC HASHMAP_P HOST)
25+
target_compile_definitions(jet_import PUBLIC HASHMAP_P HOST IMP)
26+
target_compile_definitions(jet_export PUBLIC HASHMAP_P HOST EXP)
27+
target_compile_definitions(jet_serial PUBLIC HASHMAP_P SERIAL)
28+
target_link_libraries(jet Kokkos::kokkos Kokkos::kokkoskernels metis)
29+
target_link_libraries(jet4 Kokkos::kokkos Kokkos::kokkoskernels metis)
30+
target_link_libraries(jet2 Kokkos::kokkos Kokkos::kokkoskernels metis)
31+
target_link_libraries(jet_host Kokkos::kokkos Kokkos::kokkoskernels metis)
32+
target_link_libraries(jet_import Kokkos::kokkos Kokkos::kokkoskernels)
33+
target_link_libraries(jet_export Kokkos::kokkos Kokkos::kokkoskernels metis)
34+
target_link_libraries(jet_serial Kokkos::kokkos Kokkos::kokkoskernels metis)
35+
target_link_libraries(pstat Kokkos::kokkos Kokkos::kokkoskernels)

ExperimentLoggerUtil.hpp

+239
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
// ***********************************************************************
2+
//
3+
// Jet: Multilevel Graph Partitioning
4+
//
5+
// Copyright 2023 National Technology & Engineering Solutions of Sandia, LLC
6+
// (NTESS).
7+
//
8+
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9+
// the U.S. Government retains certain rights in this software.
10+
//
11+
// Redistribution and use in source and binary forms, with or without
12+
// modification, are permitted provided that the following conditions are
13+
// met:
14+
//
15+
// 1. Redistributions of source code must retain the above copyright
16+
// notice, this list of conditions and the following disclaimer.
17+
//
18+
// 2. Redistributions in binary form must reproduce the above copyright
19+
// notice, this list of conditions and the following disclaimer in the
20+
// documentation and/or other materials provided with the distribution.
21+
//
22+
// 3. Neither the name of the Corporation nor the names of the
23+
// contributors may be used to endorse or promote products derived from
24+
// this software without specific prior written permission.
25+
//
26+
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27+
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30+
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31+
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33+
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34+
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35+
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37+
//
38+
// ************************************************************************
39+
#pragma once
40+
#include <vector>
41+
#include <stdlib.h>
42+
#include <iostream>
43+
#include <fstream>
44+
#include <string>
45+
#include <map>
46+
47+
namespace jet_partitioner {
48+
49+
enum class Measurement : int {
50+
Map,
51+
Build,
52+
Count,
53+
Prefix,
54+
Bucket,
55+
Dedupe,
56+
RadixSort,
57+
RadixDedupe,
58+
WriteGraph,
59+
Permute,
60+
MapConstruct,
61+
Heavy,
62+
InitTransfer,
63+
HashmapAllocate,
64+
HashmapInsert,
65+
InitPartition,
66+
Coarsen,
67+
Refine,
68+
FreeGraph,
69+
Total,
70+
END
71+
};
72+
73+
template <typename scalar_t>
74+
class ExperimentLoggerUtil {
75+
76+
public:
77+
std::vector<std::string> measurementNames{
78+
"coarsen-map",
79+
"coarsen-build",
80+
"coarsen-count",
81+
"coarsen-prefix-sum",
82+
"coarsen-bucket",
83+
"coarsen-dedupe",
84+
"coarsen-radix-sort",
85+
"coarsen-radix-dedupe",
86+
"coarsen-write-graph",
87+
"coarsen-permute",
88+
"coarsen-map-construct",
89+
"heavy",
90+
"initial-transfer-to-device",
91+
"hashmap-allocate",
92+
"hashmap-insert",
93+
"initial-partition",
94+
"coarsen",
95+
"refine",
96+
"free-graph",
97+
"total",
98+
};
99+
std::vector<double> measurements;
100+
101+
class CoarseLevel {
102+
public:
103+
int64_t edge_cut = 0;
104+
double imb = 0;
105+
uint64_t numEdges = 0;
106+
uint64_t numVertices = 0;
107+
double totalRefTime = 0;
108+
double iterationsTime = 0;
109+
int totalIterations = 0;
110+
int lpIterations = 0;
111+
112+
CoarseLevel(int64_t _edge_cut, double _imb, uint64_t _numEdges, uint64_t _numVertices, double _totalRefTime, double _iterationsTime, int _totalIterations, int _lpIterations) :
113+
edge_cut(_edge_cut),
114+
imb(_imb),
115+
numEdges(_numEdges),
116+
numVertices(_numVertices),
117+
totalRefTime(_totalRefTime),
118+
iterationsTime(_iterationsTime),
119+
totalIterations(_totalIterations),
120+
lpIterations(_lpIterations) {}
121+
122+
};
123+
124+
private:
125+
int numCoarseLevels = 0;
126+
std::vector<CoarseLevel> coarseLevels;
127+
double imb_ratio = 0;
128+
scalar_t fine_ec = 0;
129+
scalar_t max_part_cut = 0;
130+
scalar_t largest_part = 0;
131+
scalar_t smallest_part = 0;
132+
int64_t obj = 0;
133+
134+
public:
135+
ExperimentLoggerUtil() :
136+
measurements(static_cast<int>(Measurement::END), 0.0)
137+
{}
138+
139+
void addCoarseLevel(CoarseLevel cl) {
140+
coarseLevels.push_back(cl);
141+
numCoarseLevels++;
142+
}
143+
144+
void setFinestEdgeCut(scalar_t finestEdgeCut) {
145+
this->fine_ec = finestEdgeCut;
146+
}
147+
148+
void setMaxPartCut(scalar_t x){
149+
this->max_part_cut = x;
150+
}
151+
152+
void setFinestImbRatio(double _imb_ratio) {
153+
this->imb_ratio = _imb_ratio;
154+
}
155+
156+
void setObjective(int64_t x){
157+
this->obj = x;
158+
}
159+
160+
void setLargestPartSize(scalar_t x){
161+
this->largest_part = x;
162+
}
163+
164+
void setSmallestPartSize(scalar_t x){
165+
this->smallest_part = x;
166+
}
167+
168+
void addMeasurement(Measurement m, double val) {
169+
measurements[static_cast<int>(m)] += val;
170+
}
171+
172+
double getMeasurement(Measurement m) {
173+
return measurements[static_cast<int>(m)];
174+
}
175+
176+
void log(char* filename, bool first, bool last) {
177+
std::ofstream f;
178+
f.open(filename, std::ios::app);
179+
180+
if (f.is_open()) {
181+
if (first) {
182+
f << "[";
183+
}
184+
f << "{";
185+
f << "\"edge-cut\":" << std::fixed << fine_ec << ",";
186+
f << "\"max-part-cut\":" << max_part_cut << ",";
187+
f << "\"objective\":" << obj << ",";
188+
f << "\"imbalance-ratio\":" << imb_ratio << ',';
189+
for (int i = 0; i < static_cast<int>(Measurement::END); i++) {
190+
f << "\"" << measurementNames[i] << "-duration-seconds\":" << measurements[i] << ",";
191+
}
192+
f << "\"number-coarse-levels\":" << numCoarseLevels << ",";
193+
f << "\"finest-refinement-duration-seconds\":" << coarseLevels.back().totalRefTime;
194+
f << "}";
195+
if (!last) {
196+
f << ",";
197+
}
198+
else {
199+
f << "]";
200+
}
201+
f.close();
202+
}
203+
else {
204+
std::cerr << "Could not open " << filename << std::endl;
205+
}
206+
}
207+
208+
void verboseReport(){
209+
std::cout << "Final cut: " << std::fixed << fine_ec;
210+
std::cout << "; Max part cut: " << std::fixed << max_part_cut;
211+
std::cout << "; imb: " << imb_ratio;
212+
std::cout << "; largest: " << largest_part << "; smallest: " << smallest_part << std::endl;
213+
std::cout << std::setprecision(5);
214+
std::cout << "Coarsening time: " << getMeasurement(Measurement::Coarsen) << std::endl;
215+
std::cout << " - Coarsening aggregation time: " << getMeasurement(Measurement::Map) << std::endl;
216+
std::cout << " - Coarsening contraction time: " << getMeasurement(Measurement::Build) << std::endl;
217+
std::cout << "Initial partitioning time: " << getMeasurement(Measurement::InitPartition) << std::endl;
218+
std::cout << "Uncoarsening time: " << getMeasurement(Measurement::Refine) << std::endl;
219+
std::cout << "Coarse graph free time: " << getMeasurement(Measurement::FreeGraph) << std::endl;
220+
std::cout << "Total Partitioning Time: " << getMeasurement(Measurement::Total) << std::endl;
221+
std::cout << "Comm size: " << obj << std::endl;
222+
}
223+
224+
void refinementReport(){
225+
std::cout << std::setprecision(6);
226+
std::cout << std::left << std::setw(6) << "Level" << std::setw(16) << "Edge Cut" << std::setw(10) << "Imbalance";
227+
std::cout << std::setw(13) << "Vertices" << std::setw(16) << "Edges" << std::setw(22) << "Total Refinement Time";
228+
std::cout << std::setw(17) << "Total Iterations" << std::setw(14) << "LP Iterations" << std::setw(23) << "Average Iteration Time" << std::endl;
229+
for(size_t i = 0; i < coarseLevels.size(); i++){
230+
CoarseLevel cl = coarseLevels[i];
231+
int level = coarseLevels.size() - 1 - i;
232+
std::cout << std::fixed << std::left << std::setw(6) << level << std::setw(16) << cl.edge_cut << std::setw(10) << cl.imb;
233+
std::cout << std::setw(13) << cl.numVertices << std::setw(16) << cl.numEdges << std::setw(22) << cl.totalRefTime;
234+
std::cout << std::setw(17) << cl.totalIterations << std::setw(14) << cl.lpIterations << std::setw(23) << (cl.iterationsTime / cl.totalIterations) << std::endl;
235+
}
236+
}
237+
};
238+
239+
}

LICENSE

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// ***********************************************************************
2+
//
3+
// Jet: Multilevel Graph Partitioning
4+
//
5+
// Copyright 2023 National Technology & Engineering Solutions of Sandia, LLC
6+
// (NTESS).
7+
//
8+
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9+
// the U.S. Government retains certain rights in this software.
10+
//
11+
// Redistribution and use in source and binary forms, with or without
12+
// modification, are permitted provided that the following conditions are
13+
// met:
14+
//
15+
// 1. Redistributions of source code must retain the above copyright
16+
// notice, this list of conditions and the following disclaimer.
17+
//
18+
// 2. Redistributions in binary form must reproduce the above copyright
19+
// notice, this list of conditions and the following disclaimer in the
20+
// documentation and/or other materials provided with the distribution.
21+
//
22+
// 3. Neither the name of the Corporation nor the names of the
23+
// contributors may be used to endorse or promote products derived from
24+
// this software without specific prior written permission.
25+
//
26+
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27+
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30+
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31+
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33+
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34+
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35+
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37+
//
38+
// ************************************************************************

README.md

+36-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
1-
Jet is a parallel graph partitioner that runs on most CPU and GPU systems (via Kokkos, a required dependency).
2-
Jet was developed in a collaboration between Sandia National Labs and Pennsylvania State University.
1+
# A K-Way Graph Partitioner for the GPU
2+
3+
The Jet Partitioner is a parallel graph partitioner that runs on most CPU and GPU systems (via Kokkos, a required dependency).
4+
This partitioner was developed in a collaboration between Sandia National Labs and Pennsylvania State University.
35
For details about the algorithm, please see https://arxiv.org/abs/2304.13194
6+
7+
## Dependencies
8+
9+
Kokkos (https://github.com/kokkos/kokkos): Enables performance portable parallelism.
10+
KokkosKernels (https://github.com/kokkos/kokkos-kernels): Necessary only for KokkosSparse::CrsMatrix class.
11+
Metis (https://github.com/KarypisLab/METIS): Used for initial partitioning of coarsest graph.
12+
13+
## Usage
14+
15+
### Executables
16+
17+
#### Partitioners
18+
Each partitioner executable requires 2 parameters. The first is a graph file in metis format, the second is a config file. Multiple sample config files are provided in the "configs" directory. Optionally, a third parameter can be used to specify an output file for the partition, and a fourth parameter for runtime statistics in JSON format.
19+
Although the partitioner itself supports weighted edges and vertices, the import method currently does not support weighted vertices.
20+
jet: The primary partitioner exe. Coarsening algorithm can be set in config file. Runs on the default device.
21+
jet\_host: jet but runs on the host device.
22+
jet\_serial: jet but runs on the host on a single thread.
23+
24+
#### Helpers
25+
pstat: Given a metis graph file, partition file, and k-value, will print out quality information on the partition.
26+
27+
### Using Jet in Your Code
28+
We can not provide an option to compile a library due to the use of templates. However, you can import "jet.hpp" into your code to use the partitioner via the "jet\_partitioner::partition" method. Note that this requires you to add our source directory to your include path and also to link our dependencies. This method currently always uses the default coarsening algorithm.
29+
30+
### Input Format
31+
We do not yet support vertex weights within metis graph files.
32+
33+
### Config File format:
34+
\<Coarsening algorithm\> (0 for 2-hop matching)/(1 for HEC)/(2 for pure matching)/(default is 2-hop matching)
35+
\<Number of parts\>
36+
\<Partitioning attempts\>
37+
\<Imbalance value\>

configs/base_config.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0
2+
64
3+
21
4+
1.03

configs/config128_1.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0
2+
128
3+
21
4+
1.01

configs/config128_10.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0
2+
128
3+
21
4+
1.1

configs/config128_3.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0
2+
128
3+
21
4+
1.03

configs/config256_1.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0
2+
256
3+
21
4+
1.01

configs/config256_10.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0
2+
256
3+
21
4+
1.1

configs/config256_3.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0
2+
256
3+
21
4+
1.03

configs/config32_1.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0
2+
32
3+
21
4+
1.01

0 commit comments

Comments
 (0)