Skip to content

Commit e26251f

Browse files
progress
1 parent a79e581 commit e26251f

File tree

1 file changed

+169
-84
lines changed

1 file changed

+169
-84
lines changed

include/osp/coarser/Sarkar/Sarkar.hpp

Lines changed: 169 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ limitations under the License.
2020

2121
#include <algorithm>
2222
#include <limits>
23+
#include <map>
2324
#include <set>
2425
#include <tuple>
2526
#include <utility>
@@ -68,9 +69,7 @@ class Sarkar : public CoarserGenExpansionMap<Graph_t_in, Graph_t_out> {
6869
vertex_idx_t<Graph_t_in> out_buffer_merge(v_workw_t<Graph_t_in> commCost, const Graph_t_in &graph, std::vector<std::vector<vertex_idx_t<Graph_t_in>>> &expansionMapOutput) const;
6970
vertex_idx_t<Graph_t_in> in_buffer_merge(v_workw_t<Graph_t_in> commCost, const Graph_t_in &graph, std::vector<std::vector<vertex_idx_t<Graph_t_in>>> &expansionMapOutput) const;
7071

71-
std::vector<std::size_t> nodeHashes;
72-
void computeNodeHashes(const Graph_t_in &graph);
73-
std::unordered_map<std::size_t, std::set< vertex_idx_t<Graph_t_in> >> computeHashOrbits() const;
72+
std::vector<std::size_t> computeNodeHashes(const Graph_t_in &graph, const std::vector< vertex_idx_t<Graph_t_in> > &vertexPoset, const std::vector< v_workw_t<Graph_t_in> > &dist) const;
7473

7574
public:
7675
virtual std::vector<std::vector<vertex_idx_t<Graph_t_in>>> generate_vertex_expansion_map(const Graph_t_in &dag_in) override;
@@ -1127,6 +1126,23 @@ vertex_idx_t<Graph_t_in> Sarkar<Graph_t_in, Graph_t_out>::levelContraction(v_wor
11271126
return counter;
11281127
};
11291128

1129+
template<typename Graph_t_in, typename Graph_t_out>
1130+
std::vector<std::size_t> Sarkar<Graph_t_in, Graph_t_out>::computeNodeHashes(const Graph_t_in &graph, const std::vector< vertex_idx_t<Graph_t_in> > &vertexPoset, const std::vector< v_workw_t<Graph_t_in> > &dist) const {
1131+
using VertexType = vertex_idx_t<Graph_t_in>;
1132+
1133+
std::vector<std::size_t> hashes(graph.num_vertices());
1134+
for (const VertexType &vert : graph.vertices()) {
1135+
std::size_t &hash = hashes[vert];
1136+
hash = std::hash<v_workw_t<Graph_t_in>>{}(graph.vertex_work_weight(vert));
1137+
hash_combine(hash, vertexPoset[vert]);
1138+
hash_combine(hash, dist[vert]);
1139+
if constexpr (has_typed_vertices_v<Graph_t_in>) {
1140+
hash_combine(hash, graph.vertex_type(vert));
1141+
}
1142+
}
1143+
1144+
return hashes;
1145+
}
11301146

11311147
template<typename Graph_t_in, typename Graph_t_out>
11321148
vertex_idx_t<Graph_t_in> Sarkar<Graph_t_in, Graph_t_out>::out_buffer_merge(v_workw_t<Graph_t_in> commCost, const Graph_t_in &graph, std::vector<std::vector<vertex_idx_t<Graph_t_in>>> &expansionMapOutput) const {
@@ -1137,114 +1153,183 @@ vertex_idx_t<Graph_t_in> Sarkar<Graph_t_in, Graph_t_out>::out_buffer_merge(v_wor
11371153
const std::vector< v_workw_t<Graph_t_in> > topDist = getTopDistance(commCost, graph);
11381154
const std::vector< v_workw_t<Graph_t_in> > botDist = getBotDistance(commCost, graph);
11391155

1140-
auto cmp = [](const std::pair<long, VertexType> &lhs, const std::pair<long, VertexType> &rhs) {
1156+
auto cmp = [](const std::pair<long, std::vector<VertexType>> &lhs, const std::pair<long, std::vector<VertexType>> &rhs) {
11411157
return (lhs.first > rhs.first)
11421158
|| ((lhs.first == rhs.first) && (lhs.second < rhs.second));
11431159
};
1144-
std::set<std::pair<long, VertexType>, decltype(cmp)> vertPriority(cmp);
1160+
std::set<std::pair<long, std::vector<VertexType>>, decltype(cmp)> vertPriority(cmp);
11451161

1146-
for (const VertexType &groupHead : graph.vertices()) {
1147-
if (graph.out_degree(groupHead) <= 1) continue;
1162+
std::vector<std::size_t> hashValues = computeNodeHashes(graph, vertexPoset, topDist);
1163+
std::vector<std::size_t> hashValuesWithParents = hashValues;
1164+
for (const VertexType &par : graph.vertices()) {
1165+
for (const VertexType &chld : graph.children(par)) {
1166+
hash_combine(hashValuesWithParents[chld], hashValues[par]);
1167+
}
1168+
}
11481169

1149-
bool shouldSkip = false;
1150-
if constexpr (has_typed_vertices_v<Graph_t_in>) {
1151-
v_type_t<Graph_t_in> children_type = std::numeric_limits< v_type_t<Graph_t_in> >::max();
1152-
1153-
for (const VertexType &groupFoot : graph.children(groupHead)) {
1154-
if (children_type == std::numeric_limits< v_type_t<Graph_t_in> >::max()) {
1155-
children_type = graph.vertex_type(groupFoot);
1156-
}
1157-
if (graph.vertex_type(groupFoot) != children_type) {
1158-
shouldSkip = true;
1159-
break;
1160-
}
1161-
}
1162-
}
1163-
if (shouldSkip) continue;
1164-
for (const VertexType &groupFoot : graph.children(groupHead)) {
1165-
if (vertexPoset[groupFoot] != vertexPoset[groupHead] + 1) {
1166-
shouldSkip = true;
1167-
break;
1168-
}
1169-
}
1170-
if (shouldSkip) continue;
1171-
v_workw_t<Graph_t_in> combined_weight = 0;
1172-
for (const VertexType &groupFoot : graph.children(groupHead)) {
1173-
combined_weight += graph.vertex_work_weight(groupFoot);
1170+
std::unordered_map<std::size_t, std::set<VertexType>> orbits;
1171+
for (const VertexType &vert : graph.vertices()) {
1172+
if (graph.vertex_work_weight(vert) > params.smallWeightThreshold) continue;
1173+
1174+
const std::size_t hash = hashValuesWithParents[vert];
1175+
auto found_iter = orbits.find(hash);
1176+
if (found_iter == orbits.end()) {
1177+
orbits.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(std::initializer_list< vertex_idx_t<Graph_t_in> >{vert}));
1178+
} else {
1179+
found_iter->second.emplace(vert);
11741180
}
1175-
if (combined_weight > params.maxWeight) continue;
1181+
}
11761182

1177-
v_workw_t<Graph_t_in> maxPath = topDist[groupHead] + botDist[groupHead] - graph.vertex_work_weight(groupHead);
1178-
v_workw_t<Graph_t_in> maxParentDist = 0;
1179-
v_workw_t<Graph_t_in> maxChildDist = 0;
1183+
1184+
std::vector<bool> consideredVertices(graph.num_vertices(), false);
1185+
for (const VertexType &vert : graph.vertices()) {
1186+
if (graph.vertex_work_weight(vert) > params.smallWeightThreshold) continue;
1187+
if (consideredVertices[vert]) continue;
11801188

1181-
for (const VertexType &par : graph.parents(groupHead)) {
1182-
maxParentDist = std::max(maxParentDist, topDist[par] + commCost);
1189+
const std::set<VertexType> &orb = orbits.at(hashValuesWithParents[vert]);
1190+
if (orb.size() <= 1U) continue;
1191+
1192+
std::set<VertexType> parents;
1193+
for (const VertexType &par : graph.parents(vert)) {
1194+
parents.emplace(par);
11831195
}
1184-
for (const VertexType &groupFoot : graph.children(groupHead)) {
1185-
for (const VertexType &par : graph.parents(groupFoot)) {
1186-
if (par == groupHead) continue;
1187-
maxParentDist = std::max(maxParentDist, topDist[par] + commCost);
1196+
1197+
std::set<VertexType> secureOrb;
1198+
for (const VertexType &vertCandidate : orb) {
1199+
if (vertexPoset[vertCandidate] != vertexPoset[vert]) continue;
1200+
if (graph.vertex_work_weight(vertCandidate) != graph.vertex_work_weight(vert)) continue;
1201+
if (topDist[vertCandidate] != topDist[vert]) continue;
1202+
if constexpr (has_typed_vertices_v<Graph_t_in>) {
1203+
if (graph.vertex_type(vertCandidate) != graph.vertex_type(vert)) continue;
11881204
}
1205+
1206+
std::set<VertexType> candidateParents;
1207+
for (const VertexType &par : graph.parents(vertCandidate)) {
1208+
candidateParents.emplace(par);
1209+
}
1210+
if (candidateParents != parents) continue;
1211+
1212+
secureOrb.emplace(vertCandidate);
11891213
}
1214+
if (secureOrb.size() <= 1U) continue;
11901215

1191-
for (const VertexType &groupFoot : graph.children(groupHead)) {
1192-
for (const VertexType &chld : graph.children(groupFoot)) {
1193-
maxChildDist = std::max(maxChildDist, botDist[chld] + commCost);
1216+
1217+
auto descendantsCmp = [&vertexPoset](const VertexType &lhs, const VertexType &rhs) {
1218+
return (vertexPoset[lhs] < vertexPoset[rhs])
1219+
|| ((vertexPoset[lhs] == vertexPoset[rhs]) && (lhs < rhs));
1220+
};
1221+
1222+
std::map<VertexType, std::set<VertexType>, decltype(descendantsCmp)> descendantQueue(descendantsCmp);
1223+
for (const VertexType orbVert : secureOrb) {
1224+
for (const VertexType chld : graph.children(orbVert)) {
1225+
auto it = descendantQueue.find(chld);
1226+
if (it == descendantQueue.end()) {
1227+
descendantQueue.emplace(chld, std::initializer_list< vertex_idx_t<Graph_t_in> >{orbVert});
1228+
} else {
1229+
it->second.emplace(orbVert);
1230+
}
11941231
}
11951232
}
1233+
1234+
Union_Find_Universe<VertexType, VertexType, v_workw_t<Graph_t_in>, unsigned> similarityGroupings;
1235+
for (const VertexType orbVert : secureOrb) {
1236+
similarityGroupings.add_object(orbVert);
1237+
}
1238+
1239+
// todo make me a parameter
1240+
constexpr vertex_idx_t<Graph_t_in> groupingSearchDepth = static_cast< vertex_idx_t<Graph_t_in> >(5);
1241+
for (vertex_idx_t<Graph_t_in> i = 0; i < groupingSearchDepth; ++i) {
1242+
if (descendantQueue.empty()) continue;
1243+
const vertex_idx_t<Graph_t_in> level = vertexPoset[ descendantQueue.cbegin()->first ];
1244+
while ((!descendantQueue.empty()) && vertexPoset[ descendantQueue.cbegin()->first ] == level) {
1245+
const VertexType &descendant = descendantQueue.cbegin()->first;
1246+
const std::set<VertexType> &orbSubset = descendantQueue.cbegin()->second;
1247+
1248+
const VertexType firstVert = *orbSubset.begin();
1249+
for (const VertexType otherVert : orbSubset) {
1250+
similarityGroupings.join_by_name(firstVert, otherVert);
1251+
}
11961252

1197-
v_workw_t<Graph_t_in> newMaxPath = maxParentDist + maxChildDist + graph.vertex_work_weight(groupHead);
1198-
for (const VertexType &groupFoot : graph.children(groupHead)) {
1199-
newMaxPath += graph.vertex_work_weight(groupFoot);
1253+
for (const VertexType chld : graph.children(descendant)) {
1254+
auto it = descendantQueue.find(chld);
1255+
if (it == descendantQueue.end()) {
1256+
descendantQueue.emplace(chld, std::initializer_list< vertex_idx_t<Graph_t_in> >{*orbSubset.cbegin()});
1257+
} else {
1258+
it->second.insert(*orbSubset.cbegin());
1259+
}
1260+
}
1261+
1262+
descendantQueue.erase(descendantQueue.begin());
1263+
}
1264+
1265+
// TODO stuff
12001266
}
12011267

1202-
long savings = static_cast<long>(maxPath) - static_cast<long>(newMaxPath);
1203-
if (savings + static_cast<long>(params.leniency * static_cast<double>(maxPath)) >= 0) {
1204-
vertPriority.emplace(savings, groupHead);
1268+
// Union_Find_Universe<VertexType, VertexType, v_workw_t<Graph_t_in>, unsigned> bestSimilarGrouping = similarityGroupings;
1269+
// todo
1270+
1271+
1272+
1273+
1274+
1275+
1276+
1277+
for (const VertexType &touchedVertex : secureOrb) {
1278+
consideredVertices[touchedVertex] = true;
12051279
}
12061280
}
12071281

1208-
std::vector<bool> partitionedFlag(graph.num_vertices(), false);
12091282

1210-
vertex_idx_t<Graph_t_in> maxCorseningNum = graph.num_vertices() - static_cast<vertex_idx_t<Graph_t_in>>(static_cast<double>(graph.num_vertices()) * params.geomDecay);
12111283

1212-
vertex_idx_t<Graph_t_in> counter = 0;
1213-
long minSave = std::numeric_limits<long>::lowest();
1214-
for (auto prioIter = vertPriority.begin(); prioIter != vertPriority.end(); prioIter++) {
1215-
const long &vertSave = prioIter->first;
1216-
const VertexType &groupHead = prioIter->second;
12171284

1218-
// Iterations halt
1219-
if (vertSave < minSave) break;
12201285

1221-
// Check whether we can glue
1222-
bool shouldSkip = false;
1223-
for (const VertexType &groupFoot : graph.children(groupHead)) {
1224-
if (partitionedFlag[groupFoot]) {
1225-
shouldSkip = true;
1226-
break;
1227-
}
1228-
}
1229-
if (shouldSkip) continue;
12301286

1231-
// Adding to partition
1232-
std::vector<VertexType> part;
1233-
part.reserve(graph.out_degree(groupHead));
1234-
for (const VertexType &groupFoot : graph.children(groupHead)) {
1235-
part.emplace_back(groupFoot);
1236-
}
12371287

1238-
expansionMapOutput.emplace_back( std::move(part) );
1239-
counter += graph.out_degree(groupHead) - 1;
1240-
if (counter > maxCorseningNum) {
1241-
minSave = vertSave;
1242-
}
1288+
1289+
1290+
1291+
// todo
1292+
1293+
std::vector<bool> partitionedFlag(graph.num_vertices(), false);
1294+
1295+
// vertex_idx_t<Graph_t_in> maxCorseningNum = graph.num_vertices() - static_cast<vertex_idx_t<Graph_t_in>>(static_cast<double>(graph.num_vertices()) * params.geomDecay);
1296+
1297+
vertex_idx_t<Graph_t_in> counter = 0;
1298+
// long minSave = std::numeric_limits<long>::lowest();
1299+
// for (auto prioIter = vertPriority.begin(); prioIter != vertPriority.end(); prioIter++) {
1300+
// const long &vertSave = prioIter->first;
1301+
// const VertexType &groupHead = prioIter->second;
1302+
1303+
// // Iterations halt
1304+
// if (vertSave < minSave) break;
1305+
1306+
// // Check whether we can glue
1307+
// bool shouldSkip = false;
1308+
// for (const VertexType &groupFoot : graph.children(groupHead)) {
1309+
// if (partitionedFlag[groupFoot]) {
1310+
// shouldSkip = true;
1311+
// break;
1312+
// }
1313+
// }
1314+
// if (shouldSkip) continue;
1315+
1316+
// // Adding to partition
1317+
// std::vector<VertexType> part;
1318+
// part.reserve(graph.out_degree(groupHead));
1319+
// for (const VertexType &groupFoot : graph.children(groupHead)) {
1320+
// part.emplace_back(groupFoot);
1321+
// }
1322+
1323+
// expansionMapOutput.emplace_back( std::move(part) );
1324+
// counter += graph.out_degree(groupHead) - 1;
1325+
// if (counter > maxCorseningNum) {
1326+
// minSave = vertSave;
1327+
// }
12431328

1244-
for (const VertexType &groupFoot : graph.children(groupHead)) {
1245-
partitionedFlag[groupFoot] = true;
1246-
}
1247-
}
1329+
// for (const VertexType &groupFoot : graph.children(groupHead)) {
1330+
// partitionedFlag[groupFoot] = true;
1331+
// }
1332+
// }
12481333

12491334
for (const VertexType &vert : graph.vertices()) {
12501335
if (partitionedFlag[vert]) continue;

0 commit comments

Comments
 (0)