Skip to content

Commit f671d8f

Browse files
Merge branch 'master' into SarkarBufferMerges
2 parents ccebf63 + 24698a8 commit f671d8f

File tree

64 files changed

+6674
-1192
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+6674
-1192
lines changed

apps/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ endif()
5050

5151
if (COPT_FOUND)
5252
_add_executable( ilp_bsp_scheduler )
53+
_add_executable( ilp_hypergraph_partitioner )
5354
endif()
5455

5556
endif()
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*
2+
Copyright 2024 Huawei Technologies Co., Ltd.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
@author Toni Boehnlein, Benjamin Lozes, Pal Andras Papp, Raphael S. Steiner
17+
*/
18+
19+
#include <filesystem>
20+
#include <fstream>
21+
#include <iostream>
22+
#include <set>
23+
#include <string>
24+
#include <vector>
25+
26+
#include "osp/auxiliary/misc.hpp"
27+
#include "osp/graph_algorithms/directed_graph_path_util.hpp"
28+
#include "osp/auxiliary/io/general_file_reader.hpp"
29+
#include "osp/partitioning/model/hypergraph_utility.hpp"
30+
#include "osp/partitioning/partitioners/generic_FM.hpp"
31+
#include "osp/partitioning/partitioners/partitioning_ILP.hpp"
32+
#include "osp/partitioning/partitioners/partitioning_ILP_replication.hpp"
33+
#include "osp/graph_implementations/adj_list_impl/computational_dag_vector_impl.hpp"
34+
#include "osp/auxiliary/io/hdag_graph_file_reader.hpp"
35+
#include "osp/auxiliary/io/mtx_hypergraph_file_reader.hpp"
36+
#include "osp/auxiliary/io/partitioning_file_writer.hpp"
37+
38+
39+
using namespace osp;
40+
41+
using graph = computational_dag_vector_impl_def_int_t;
42+
using hypergraph = Hypergraph_def_t;
43+
44+
int main(int argc, char *argv[]) {
45+
if (argc < 4) {
46+
std::cerr << "Usage: " << argv[0] << " <input_file> <nr_parts> <imbalance> <optional:part_repl|full_repl>"
47+
<< std::endl;
48+
return 1;
49+
}
50+
51+
std::string filename_hgraph = argv[1];
52+
std::string name_hgraph = filename_hgraph.substr(0, filename_hgraph.rfind("."));
53+
std::string file_ending = filename_hgraph.substr(filename_hgraph.rfind(".") + 1);
54+
if (!file_reader::isPathSafe(filename_hgraph)) {
55+
std::cerr << "Error: Unsafe file path (possible traversal or invalid type).\n";
56+
return 1;
57+
}
58+
59+
std::cout << name_hgraph << std::endl;
60+
61+
int nr_parts = std::stoi(argv[2]);
62+
if (nr_parts < 2 || nr_parts > 32) {
63+
std::cerr << "Argument nr_parts must be an integer between 2 and 32: " << nr_parts << std::endl;
64+
return 1;
65+
}
66+
67+
float imbalance = std::stof(argv[3]);
68+
if (imbalance < 0.01 || imbalance > .99) {
69+
std::cerr << "Argument imbalance must be a float between 0.01 and 0.99: " << imbalance << std::endl;
70+
return 1;
71+
}
72+
73+
unsigned replicate = 0;
74+
75+
if (argc > 4 && std::string(argv[4]) == "part_repl") {
76+
replicate = 1;
77+
} else if (argc > 4 && std::string(argv[4]) == "full_repl") {
78+
replicate = 2;
79+
} else if (argc > 4) {
80+
std::cerr << "Unknown argument: " << argv[4] << ". Expected 'part_repl' or 'full_repl' for replication." << std::endl;
81+
return 1;
82+
}
83+
84+
PartitioningProblem<hypergraph> instance;
85+
86+
bool file_status = true;
87+
if (file_ending == "hdag") {
88+
graph dag;
89+
file_status = file_reader::readComputationalDagHyperdagFormatDB(filename_hgraph, dag);
90+
if(file_status)
91+
instance.getHypergraph() = convert_from_cdag_as_hyperdag<hypergraph, graph>(dag);
92+
} else if (file_ending == "mtx") {
93+
file_status = file_reader::readHypergraphMartixMarketFormat(filename_hgraph, instance.getHypergraph());
94+
} else {
95+
std::cout << "Unknown file extension." << std::endl;
96+
return 1;
97+
}
98+
if (!file_status) {
99+
100+
std::cout << "Reading input file failed." << std::endl;
101+
return 1;
102+
}
103+
104+
instance.setNumberOfPartitions(static_cast<unsigned>(nr_parts));
105+
instance.setMaxWorkWeightViaImbalanceFactor(imbalance);
106+
107+
Partitioning<hypergraph> initial_partition(instance);
108+
GenericFM<hypergraph> fm;
109+
for(size_t node = 0; node < instance.getHypergraph().num_vertices(); ++node)
110+
initial_partition.setAssignedPartition(node, static_cast<unsigned>(node % static_cast<size_t>(nr_parts)));
111+
if(nr_parts == 2)
112+
fm.ImprovePartitioning(initial_partition);
113+
if(nr_parts == 4 || nr_parts == 8 || nr_parts == 16 || nr_parts == 32)
114+
fm.RecursiveFM(initial_partition);
115+
116+
if (replicate > 0) {
117+
118+
PartitioningWithReplication<hypergraph> partition(instance);
119+
HypergraphPartitioningILPWithReplication<hypergraph> partitioner;
120+
121+
for(size_t node = 0; node < instance.getHypergraph().num_vertices(); ++node)
122+
partition.setAssignedPartitions(node, {initial_partition.assignedPartition(node)});
123+
if(partition.satisfiesBalanceConstraint())
124+
partitioner.setUseInitialSolution(true);
125+
126+
partitioner.setTimeLimitSeconds(600);
127+
if(replicate == 2)
128+
partitioner.setReplicationModel(HypergraphPartitioningILPWithReplication<hypergraph>::REPLICATION_MODEL_IN_ILP::GENERAL);
129+
130+
auto solve_status = partitioner.computePartitioning(partition);
131+
132+
if (solve_status == RETURN_STATUS::OSP_SUCCESS || solve_status == RETURN_STATUS::BEST_FOUND) {
133+
file_writer::write_txt(name_hgraph + "_" + std::to_string(nr_parts) + "_" + std::to_string(imbalance) +
134+
"_ILP_rep" + std::to_string(replicate) + ".txt", partition);
135+
std::cout << "Partitioning (with replicaiton) computed with costs: " << partition.computeConnectivityCost() << std::endl;
136+
} else {
137+
std::cout << "Computing partition failed." << std::endl;
138+
return 1;
139+
}
140+
141+
} else {
142+
143+
Partitioning<hypergraph> partition(instance);
144+
HypergraphPartitioningILP<hypergraph> partitioner;
145+
146+
for(size_t node = 0; node < instance.getHypergraph().num_vertices(); ++node)
147+
partition.setAssignedPartition(node, initial_partition.assignedPartition(node));
148+
if(partition.satisfiesBalanceConstraint())
149+
partitioner.setUseInitialSolution(true);
150+
151+
partitioner.setTimeLimitSeconds(600);
152+
153+
auto solve_status = partitioner.computePartitioning(partition);
154+
155+
if (solve_status == RETURN_STATUS::OSP_SUCCESS || solve_status == RETURN_STATUS::BEST_FOUND) {
156+
file_writer::write_txt(name_hgraph + "_" + std::to_string(nr_parts) + "_" + std::to_string(imbalance) +
157+
"_ILP_rep" + std::to_string(replicate) + ".txt", partition);
158+
std::cout << "Partitioning computed with costs: " << partition.computeConnectivityCost() << std::endl;
159+
} else {
160+
std::cout << "Computing partition failed." << std::endl;
161+
return 1;
162+
}
163+
}
164+
return 0;
165+
}

include/osp/auxiliary/hash_util.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ struct uniform_node_hash_func {
2828
result_type operator()(const VertexType& ) { return defautlVal; }
2929
};
3030

31+
32+
template<typename VertexType>
33+
struct vector_node_hash_func {
34+
const std::vector<std::size_t>& node_hashes_;
35+
vector_node_hash_func(const std::vector<std::size_t>& node_hashes) : node_hashes_(node_hashes) {}
36+
using result_type = std::size_t;
37+
result_type operator()(const VertexType& v) const { return node_hashes_[v]; }
38+
};
39+
3140
template<class T>
3241
void hash_combine(std::size_t &seed, const T &v) {
3342
std::hash<T> hasher;

include/osp/auxiliary/io/hdag_graph_file_reader.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,17 @@ bool readComputationalDagHyperdagFormatDB(std::ifstream& infile, Graph_t& graph)
252252
graph.set_vertex_comm_weight(static_cast<vertex_idx_t<Graph_t>>(node), hyperedge_comm_weights[edgeIdx]);
253253
graph.set_vertex_mem_weight(static_cast<vertex_idx_t<Graph_t>>(node), hyperedge_mem_weights[edgeIdx]);
254254
} else {
255-
auto edge = graph.add_edge(static_cast<vertex_idx_t<Graph_t>>(edgeSource[edgeIdx]),
255+
if constexpr (is_modifiable_cdag_comm_edge_v<Graph_t>) {
256+
257+
auto edge = graph.add_edge(static_cast<vertex_idx_t<Graph_t>>(edgeSource[edgeIdx]),
256258
static_cast<vertex_idx_t<Graph_t>>(nodeIdx));
257259

258-
if constexpr (is_modifiable_cdag_comm_edge_v<Graph_t>) {
259260
graph.set_edge_comm_weight(edge.first,
260261
static_cast<e_commw_t<Graph_t>>(hyperedge_comm_weights[edgeIdx]));
262+
263+
} else {
264+
graph.add_edge(static_cast<vertex_idx_t<Graph_t>>(edgeSource[edgeIdx]),
265+
static_cast<vertex_idx_t<Graph_t>>(nodeIdx));
261266
}
262267
}
263268
}

include/osp/auxiliary/io/mtx_graph_file_reader.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ bool readComputationalDagMartixMarketFormat(std::ifstream& infile, Graph_t& grap
6969
return false;
7070
}
7171

72-
const vertex_t num_nodes = static_cast<vertex_t>(M_row);
73-
if (num_nodes > std::numeric_limits<vertex_t>::max()) {
72+
if (static_cast<unsigned long long>(M_row) > std::numeric_limits<vertex_t>::max()) {
7473
std::cerr << "Error: Matrix dimension too large for vertex type.\n";
7574
return false;
7675
}
7776

77+
const vertex_t num_nodes = static_cast<vertex_t>(M_row);
7878
std::vector<int> node_work_wts(num_nodes, 0);
7979
std::vector<int> node_comm_wts(num_nodes, 1);
8080

0 commit comments

Comments
 (0)