@@ -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
11311147template <typename Graph_t_in, typename Graph_t_out>
11321148vertex_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