public static unsafe void HilbertUnionFind2(string filename, uint nodes) { var stopwatch = System.Diagnostics.Stopwatch.StartNew(); #if UseLargePages var roots = LargePages.AllocateInts(nodes); var ranks = LargePages.AllocateBytes(nodes); #else var roots = new int[nodes]; var ranks = new byte[nodes]; #endif for (int i = 0; i < nodes; i++) { roots[i] = i; } ScanGraphHilbert(filename, (sourceUpper, targetUpper, offset, count, edges) => { for (int j = 0; j < count; j++) { var source = (int)(sourceUpper + (edges[offset + j] & 0xFFFF)); var target = (int)(targetUpper + (edges[offset + j] >> 16)); if (source != target) { while (source != roots[source]) { source = roots[source]; } while (target != roots[target]) { target = roots[target]; } // union(source, target) if (source != target) { // there may be a tie in ranks if (ranks[source] == ranks[target]) { // break ties towards lower ids if (source < target) { ranks[source]++; roots[target] = source; } else { ranks[target]++; roots[source] = target; } } else { // attatch lower rank to higher if (ranks[source] < ranks[target]) { roots[source] = target; } else { roots[target] = source; } } } } } }); // path compress all vertices to roots. for (int i = 0; i < nodes; i++) { while (roots[i] != roots[roots[i]]) { roots[i] = roots[roots[i]]; } } var counter = 0; for (int i = 0; i < nodes; i++) { if (roots[i] != i) { counter++; } } Console.WriteLine("Edges found: {0}", counter); }
public static unsafe void MultiHilbertCC(string filename, uint nodes) { var stopwatch = System.Diagnostics.Stopwatch.StartNew(); var roots = LargePages.AllocateInts(nodes); var ranks = LargePages.AllocateBytes(nodes); for (int i = 0; i < nodes; i++) { roots[i] = i; } var scanner = new MultiHilbertScanner(filename); scanner.Scan((xUpper, yUpper, count, offset, edges) => { for (int j = 0; j < count; j++) { var source = (int)(xUpper + ((edges[offset + j] & 0xF0) >> 4)); var target = (int)(yUpper + ((edges[offset + j] & 0x0F) >> 0)); if (source != target) { while (source != roots[source]) { source = roots[source]; } while (target != roots[target]) { target = roots[target]; } // union(source, target) if (source != target) { // there may be a tie in ranks if (ranks[source] == ranks[target]) { // break ties towards lower ids if (source < target) { ranks[source]++; roots[target] = source; } else { ranks[target]++; roots[source] = target; } } else { // attatch lower rank to higher if (ranks[source] < ranks[target]) { roots[source] = target; } else { roots[target] = source; } } } } } }); // path compress all vertices to roots. for (int i = 0; i < nodes; i++) { while (roots[i] != roots[roots[i]]) { roots[i] = roots[roots[i]]; } } var counter = 0; for (int i = 0; i < nodes; i++) { if (roots[i] != i) { counter++; } } Console.WriteLine("{1}\tEdges found: {0}", counter, stopwatch.Elapsed); }
public static unsafe void HilbertUnionFind(string filenameUpper, string filenameLower, uint nodes) { var stopwatch = System.Diagnostics.Stopwatch.StartNew(); using (var upper = System.IO.File.OpenRead(filenameUpper)) { using (var lower = System.IO.File.OpenRead(filenameLower)) { var bytes = new byte[upper.Length]; upper.Read(bytes, 0, bytes.Length); var uppers = new int[bytes.Length / 4]; Buffer.BlockCopy(bytes, 0, uppers, 0, bytes.Length); var maxEdges = 0; for (int i = 0; i < uppers.Length; i += 3) { maxEdges = Math.Max(maxEdges, uppers[i + 2]); } Console.WriteLine("{1}\tRead header of {0} blocks", uppers.Length / 3, stopwatch.Elapsed); bytes = new byte[8 * maxEdges]; var lowers = new UInt16[2 * maxEdges]; var edges = new Int32[2 * maxEdges]; #if UseLargePages var roots = LargePages.AllocateInts(nodes); var ranks = LargePages.AllocateBytes(nodes); #else var roots = new int[nodes]; var ranks = new byte[nodes]; #endif for (int i = 0; i < nodes; i++) { roots[i] = i; } for (int i = 0; i < uppers.Length; i += 3) { var read = lower.Read(bytes, 0, 4 * uppers[i + 2]); Buffer.BlockCopy(bytes, 0, lowers, 0, read); var sourceUpper = uppers[i + 0] << 16; var targetUpper = uppers[i + 1] << 16; var count = uppers[i + 2]; for (int j = 0; j < count; j++) { edges[2 * j + 0] = roots[sourceUpper + lowers[2 * j + 0]]; edges[2 * j + 1] = roots[targetUpper + lowers[2 * j + 1]]; } for (int j = 0; j < count; j++) { var source = edges[2 * j + 0]; var target = edges[2 * j + 1]; if (source != target) { while (source != roots[source]) { source = roots[source]; } while (target != roots[target]) { target = roots[target]; } // union(source, target) if (source != target) { // there may be a tie in ranks if (ranks[source] == ranks[target]) { // break ties towards lower ids if (source < target) { ranks[source]++; roots[target] = source; } else { ranks[target]++; roots[source] = target; } } else { // attatch lower rank to higher if (ranks[source] < ranks[target]) { roots[source] = target; } else { roots[target] = source; } } } } } } // path compress all vertices to roots. for (int i = 0; i < nodes; i++) { while (roots[i] != roots[roots[i]]) { roots[i] = roots[roots[i]]; } } var counter = 0; for (int i = 0; i < nodes; i++) { if (roots[i] != i) { counter++; } } Console.WriteLine("Edges found: {0}", counter); } } }
public unsafe static void ConnectedComponents(string filename, uint nodes) { #if UseLargePages var roots = LargePages.AllocateInts(nodes); var ranks = LargePages.AllocateBytes(nodes); #else var roots = new int[nodes]; var ranks = new byte[nodes]; #endif for (int i = 0; i < nodes; i++) { roots[i] = i; } // apply per-vertex union-find logic across the graph ScanGraph(filename, (vertex, degree, offset, neighbors) => { // find(vertex) var source = roots[vertex]; while (source != roots[source]) { source = roots[source]; } for (int i = 0; i < degree; i++) { // find(neighbors[i]) var target = roots[neighbors[offset + i]]; while (target != roots[target]) { target = roots[target]; } // union(source, target) if (source != target) { // there may be a tie in ranks if (ranks[source] == ranks[target]) { // break ties towards lower ids if (source < target) { ranks[source]++; roots[target] = source; } else { ranks[target]++; roots[source] = target; source = target; } } else { // attatch lower rank to higher if (ranks[source] < ranks[target]) { roots[source] = target; source = target; } else { roots[target] = source; } } } } }); var counter = 0; for (int i = 0; i < nodes; i++) { if (roots[i] != i) { counter++; } } Console.WriteLine("Edges found: {0}", counter); }