public unsafe static void ClumsyCC(string filename, uint nodes) { var labels = LargePages.AllocateInts(nodes); for (int i = 0; i < nodes; i++) { labels[i] = i; } var oldSum = Int64.MaxValue; var newSum = 0L; for (int i = 0; i < nodes; i++) { newSum += labels[i]; } var stopwatch = System.Diagnostics.Stopwatch.StartNew(); while (newSum < oldSum) { var startTime = stopwatch.Elapsed; // apply per-vertex pagerank logic across the graph ScanGraph(filename, (vertex, degree, offset, neighbors) => { var label = labels[vertex]; for (int i = 0; i < degree; i++) { label = Math.Min(label, labels[neighbors[offset + i]]); } labels[vertex] = label; for (int i = 0; i < degree; i++) { labels[neighbors[offset + i]] = label; } }); oldSum = newSum; newSum = 0L; for (int i = 0; i < nodes; i++) { newSum += labels[i]; } Console.WriteLine("{0}", stopwatch.Elapsed - startTime); } }
public static unsafe void HilbertPagerank(string filename, float *a, float *b, uint nodes, float reset) { var stopwatch = System.Diagnostics.Stopwatch.StartNew(); var degrees = LargePages.AllocateInts(nodes); //var degrees = new int[nodes]; var metadata = UnbufferedIO.ReadFile <uint>(filename + "-upper"); var edges = UnbufferedIO.ReadFile <uint>(filename + "-lower"); Console.WriteLine("{2}\tRead header of {0} blocks, for {1} edges", metadata.Length / 3, edges.Length, stopwatch.Elapsed); ScanGraphHilbert(metadata, edges, (srcUpper, tgtUpper, offset, count, edgeArray) => { for (var j = offset; j < offset + count; j++) { degrees[srcUpper + (edges[j] & 0xFFFF)]++; } }); Console.WriteLine("{0}\tDegrees calculated", stopwatch.Elapsed); for (int iteration = 0; iteration < 20; iteration++) { var startTime = stopwatch.Elapsed; for (int i = 0; i < nodes; i++) { b[i] = (1.0f - reset) * a[i] / degrees[i]; a[i] = reset; } ScanGraphHilbert(metadata, edges, (sourceUpper, targetUpper, offset, count, edgeArray) => { for (var j = offset; j < offset + count; j++) { a[targetUpper + (edges[j] >> 16)] += b[sourceUpper + (edges[j] & 0xFFFF)]; } }); Console.WriteLine("{0}\tIteration {1} in {2}", stopwatch.Elapsed, iteration, stopwatch.Elapsed - startTime); } }
public static unsafe void HilbertPagerankFromDisk(string filename, float[] a, float[] b, uint nodes, float reset) { var stopwatch = System.Diagnostics.Stopwatch.StartNew(); #if UseLargePages var degrees = LargePages.AllocateInts(nodes); #else var degrees = new int[nodes]; #endif ScanGraphHilbert(filename, (srcUpper, tgtUpper, offset, count, edges) => { for (int i = 0; i < count; i++) { degrees[srcUpper + (edges[offset + i] >> 16)]++; } }); Console.WriteLine("{0}\tDegrees calculated", stopwatch.Elapsed); for (int iteration = 0; iteration < 20; iteration++) { var startTime = stopwatch.Elapsed; ScanGraphHilbert(filename, (srcUpper, tgtUpper, offset, count, edges) => { for (int i = 0; i < count; i++) { a[tgtUpper + (edges[offset + i] >> 16)] += b[srcUpper + (edges[offset + i] & 0xFFFF)]; } }); for (int i = 0; i < nodes; i++) { a[i] = a[i] / degrees[i]; } Console.WriteLine("{0}\tIteration {1} in {2}", stopwatch.Elapsed, iteration, stopwatch.Elapsed - startTime); } }
public static unsafe void MultiHilbertPagerank(string filename, float *a, float *b, uint nodes, float reset) { var stopwatch = System.Diagnostics.Stopwatch.StartNew(); var degrees = LargePages.AllocateInts(nodes); var scanner = new MultiHilbertScanner(filename); scanner.Scan((xUpper, yUpper, count, offset, edges) => { for (var j = offset; j < offset + count; j++) { degrees[xUpper + ((edges[j] & 0xF0) >> 4)]++; } }); Console.WriteLine("{0}\tDegrees calculated", stopwatch.Elapsed); for (int iteration = 0; iteration < 20; iteration++) { var startTime = stopwatch.Elapsed; for (int i = 0; i < nodes; i++) { b[i] = (1.0f - reset) * a[i] / degrees[i]; a[i] = reset; } scanner.Scan((xUpper, yUpper, count, offset, edges) => { for (var j = offset; j < offset + count; j++) { a[yUpper + (edges[j] & 0x0F)] += b[xUpper + ((edges[j] & 0xF0) >> 4)]; } }); Console.WriteLine("{0}\tIteration {1} in {2}", stopwatch.Elapsed, iteration, stopwatch.Elapsed - startTime); } }
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 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 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 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); }