Example #1
0
        static HilbertCurve()
        {
            Rotated     = new bool[256][];
            Flipped     = new bool[256][];
            Transformed = new ushort[256][];

            Inverted = new byte[256 * 256 * 2];

            for (uint i = 0; i < 256; i++)
            {
                Rotated[i]     = new bool[256];
                Flipped[i]     = new bool[256];
                Transformed[i] = new ushort[256];

                for (uint j = 0; j < 256; j++)
                {
                    var transform = (UInt16)HilbertCurve.xy2dAlt(8, i, j, ref Rotated[i][j], ref Flipped[i][j]);

                    Transformed[i][j]           = transform;
                    Inverted[2 * transform + 0] = (byte)i;
                    Inverted[2 * transform + 1] = (byte)j;
                }
            }
        }
Example #2
0
        private static void WriteTransformed(ulong[] edges,
                                             System.IO.BinaryWriter high32Stream,
                                             System.IO.BinaryWriter next16Stream,
                                             System.IO.BinaryWriter next08Stream,
                                             System.IO.BinaryWriter last08Stream)
        {
            Console.WriteLine("Writing {0} edges", edges.Length);

            if (edges.Length == 0)
            {
                return;
            }

            uint x = 0;
            uint y = 0;

            // recover x and y, to interleave their bits
            HilbertCurve.d2xyByte(edges[0], out x, out y);

            // interleave each bit pattern we want to collect together
            var high32Prior = (uint)((x & 0xFFFF0000) + ((y & 0xFFFF0000) >> 16));
            var next16Prior = (ushort)((x & 0x0000FF00) + ((y & 0x0000FF00) >> 8));
            var next08Prior = (byte)((x & 0x000000F0) + ((y & 0x000000F0) >> 4));

            // count distinct subsequent bit patterns
            var high32Count = (uint)1;
            var next16Count = (uint)1;
            var next08Count = (uint)1;

            last08Stream.Write((byte)(((x & 0x0F) << 4) + (y & 0x0F)));

            for (int i = 1; i < edges.Length; i++)
            {
                // recover x and y, to interleave their bits
                HilbertCurve.d2xyByte(edges[i], out x, out y);

                var high32 = (uint)((x & 0xFFFF0000) + ((y & 0xFFFF0000) >> 16));
                var next16 = (ushort)((x & 0x0000FF00) + ((y & 0x0000FF00) >> 8));
                var next08 = (byte)((x & 0x000000F0) + ((y & 0x000000F0) >> 4));

                // changes in bits call for writing out
                var high32Change = high32 != high32Prior;
                var next16Change = high32Change || (next16 != next16Prior);
                var next08Change = next16Change || (next08 != next08Prior);

                // write high 32, reset high32count
                if (high32Change)
                {
                    high32Stream.Write(high32Prior);
                    high32Stream.Write(high32Count);

                    high32Prior = high32;
                    high32Count = 0;
                }

                // write next 16, reset nex16count, bump high32count
                if (next16Change)
                {
                    next16Stream.Write(next16Prior);
                    next16Stream.Write((ushort)next16Count);
                    high32Count++;

                    next16Prior = next16;
                    next16Count = 0;
                }

                // write next 08, reset next08count, bump next16count
                if (next08Change)
                {
                    next08Stream.Write(next08Prior);
                    next08Stream.Write((byte)next08Count);
                    next16Count++;

                    next08Prior = next08;
                    next08Count = 0;
                }


                // always write the last byte, bump next08count
                last08Stream.Write((byte)(((x & 0x0F) << 4) + (y & 0x0F)));
                next08Count++;
            }

            // flush final metadata records
            next08Stream.Write(next08Prior);
            next08Stream.Write(next08Count);

            next16Stream.Write(next16Prior);
            next16Stream.Write(next16Count);

            high32Stream.Write(high32Prior);
            high32Stream.Write(high32Count);
        }
Example #3
0
        public static void ConvertToHilbert(this string prefix)
        {
            var graph = new FileGraphScanner(prefix);

            var High32 = new Dictionary <UInt32, UInt32>();

            graph.ForEach((vertex, degree, offset, neighbors) =>
            {
                //if (vertex < 1000000)
                {
                    for (int i = 0; i < degree; i++)
                    {
                        var neighbor = neighbors[offset + i];
                        var high32   = (uint)(HilbertCurve.xy2dByte((uint)vertex, (uint)neighbor) >> 32);

                        if (!High32.ContainsKey(high32))
                        {
                            High32.Add(high32, 0);
                        }

                        High32[high32] = High32[high32] + 1;
                    }
                }
            });

            Console.WriteLine("Assesed prefix sizes");

            var pairs = High32.OrderBy(x => x.Key).ToArray();

            var edgeCount = 0L;

            var lowIndex = (uint)0;

            var high32Stream = new System.IO.BinaryWriter(System.IO.File.OpenWrite(prefix + "-high32"));
            var next16Stream = new System.IO.BinaryWriter(System.IO.File.OpenWrite(prefix + "-next16"));
            var next08Stream = new System.IO.BinaryWriter(System.IO.File.OpenWrite(prefix + "-next08"));
            var last08Stream = new System.IO.BinaryWriter(System.IO.File.OpenWrite(prefix + "-last08"));

            for (uint i = 0; i < pairs.Length; i++)
            {
                // if we would have too many edges, do work
                if (edgeCount + pairs[i].Value > 1 << 29)
                {
                    var edges  = new ulong[edgeCount];
                    var cursor = 0;

                    graph.ForEach((vertex, degree, offset, neighbors) =>
                    {
                        //if (vertex < 1000000)
                        {
                            for (int j = 0; j < degree; j++)
                            {
                                var transform = HilbertCurve.xy2dByte((uint)vertex, (uint)neighbors[offset + j]);
                                if ((transform >> 32) >= pairs[lowIndex].Key && (transform >> 32) < pairs[i].Key)
                                {
                                    edges[cursor++] = transform;
                                }
                            }
                        }
                    });

                    if (cursor != edges.Length)
                    {
                        Console.WriteLine("Somehow read the wrong number of edges {0} vs {1}", cursor, edges.Length);
                    }

                    Array.Sort(edges);

                    Console.WriteLine("About to process {0} high32 blocks", i - lowIndex);

                    // traverse edges in order and write out when interesting things happen.
                    WriteTransformed(edges, high32Stream, next16Stream, next08Stream, last08Stream);

                    edgeCount = 0;
                    lowIndex  = i;
                }

                edgeCount += pairs[i].Value;
            }

            var edges2  = new ulong[edgeCount];
            var cursor2 = 0;

            graph.ForEach((vertex, degree, offset, neighbors) =>
            {
                //if (vertex < 1000000)
                {
                    for (int j = 0; j < degree; j++)
                    {
                        var transform = HilbertCurve.xy2dByte((uint)vertex, (uint)neighbors[offset + j]);

                        if ((transform >> 32) >= pairs[lowIndex].Key)
                        {
                            edges2[cursor2++] = transform;
                        }
                    }
                }
            });

            Array.Sort(edges2);

            if (cursor2 != edges2.Length)
            {
                Console.WriteLine("Somehow read the wrong number of edges {0} vs {1}", cursor2, edges2.Length);
            }


            // traverse edges in order and write out when interesting things happen.
            WriteTransformed(edges2, high32Stream, next16Stream, next08Stream, last08Stream);

            high32Stream.Close();
            next16Stream.Close();
            next08Stream.Close();
            last08Stream.Close();
        }
Example #4
0
        public static void Test(int tests)
        {
            var random = new Random(0);

            var testxs = new uint[tests];
            var testys = new uint[tests];

            for (int i = 0; i < tests; i++)
            {
                testxs[i] = (uint)random.Next(Int32.MaxValue);
                testys[i] = (uint)random.Next(Int32.MaxValue);
            }

            var results1 = new long[tests];
            var results2 = new ulong[tests];

            for (int i = 0; i < results1.Length; i++)
            {
                results1[i] = i;
            }

            for (uint i = 0; i < results2.Length; i++)
            {
                results2[i] = i;
            }

            var stopwatch = System.Diagnostics.Stopwatch.StartNew();

            stopwatch.Restart();
            for (int i = 0; i < tests; i++)
            {
                results1[i] = HilbertCurve.xy2d(32, (int)testxs[i], (int)testys[i]);
            }

            Console.WriteLine("Slow encode:\t{0:0.00}ns/record", stopwatch.ElapsedMilliseconds / (tests / 1000000.0));

            stopwatch.Restart();
            for (int i = 0; i < tests; i++)
            {
                int x = 0, y = 0;
                HilbertCurve.d2xy(32, results1[i], out x, out y);
            }
            Console.WriteLine("Slow decode:\t{0:0.00}ns/record", stopwatch.ElapsedMilliseconds / (tests / 1000000.0));

            stopwatch.Restart();
            for (int i = 0; i < tests; i++)
            {
                results2[i] = HilbertCurve.xy2dByte(testxs[i], testys[i]);
            }

            Console.WriteLine("Fast encode:\t{0:0.00}ns/record", stopwatch.ElapsedMilliseconds / (tests / 1000000.0));

            stopwatch.Restart();
            for (int i = 0; i < tests; i++)
            {
                uint x = 0, y = 0;
                HilbertCurve.d2xyByte((ulong)results2[i], out x, out y);
            }
            Console.WriteLine("Fast decode:\t{0:0.00}ns/record", stopwatch.ElapsedMilliseconds / (tests / 1000000.0));

            for (int i = 0; i < tests; i++)
            {
                if (results1[i] != (long)results2[i])
                {
                    Console.WriteLine("Error! ({0}, {1}) -> [ {2}, {3} ]", testxs[i], testys[i], results1[i], results2[i]);
                }

                uint x = 0;
                uint y = 0;

                HilbertCurve.d2xyByte((ulong)results1[i], out x, out y);

                if (x != testxs[i] || y != testys[i])
                {
                    Console.WriteLine("Error!!! {4} -> ({0}, {2}) != ({1}, {3})", x, testxs[i], y, testys[i], results1[i]);
                    Console.ReadLine();
                }
            }
        }
Example #5
0
        static void ExecuteSingleThreaded(string[] args, string dataDir)
        {
            string ukFile          = Path.Combine(dataDir, @"uk-2007-05");
            string twitterFile     = Path.Combine(dataDir, @"twitter_rv.bin");
            string livejournalFile = Path.Combine(dataDir, @"livejournal.bin");

            if (args.Length < 3)
            {
                throw new Exception("Three arguments required: system, algorithm, dataset");
            }

            var algorithm = args[1];
            var dataset   = args[2];

            #region file conversions
            if (algorithm == "convert" && dataset == "twitter")
            {
                SingleThreaded.ConvertGraph(twitterFile);
            }

            if (algorithm == "partition" && dataset == "twitter")
            {
                SingleThreaded.PartitionGraph(twitterFile, 4, (s, t) => (s & 1) + 2 * (t & 1), dataDir + @"twitter-part-{0}-of-{1}");
            }

            if (algorithm == "transpose" && dataset == "twitter")
            {
                var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                SingleThreaded.TransposeGraph(dataDir + @"twitterfollowers\twitter_rv.bin", 65000000);
                Console.WriteLine(stopwatch.Elapsed);
            }
            #endregion

            #region hilbert layout
            if (algorithm == "hilbertlayout" && dataset == "twitter")
            {
                var stopwatch = System.Diagnostics.Stopwatch.StartNew();

                uint nodes = 0;
                var  names = new uint[65000000];
                for (int i = 0; i < names.Length; i++)
                {
                    names[i] = uint.MaxValue;
                }

                var idegrees = new int[65000000];
                var odegrees = new int[65000000];

                var edges = 0L;
                SingleThreaded.ScanGraph(twitterFile, (vertex, degree, offset, neighbors) =>
                {
                    if (names[vertex] == uint.MaxValue)
                    {
                        names[vertex] = nodes++;
                    }

                    for (int i = 0; i < degree; i++)
                    {
                        if (names[neighbors[offset + i]] == uint.MaxValue)
                        {
                            names[neighbors[offset + i]] = nodes++;
                        }
                    }

                    edges += degree;
                });

                Console.WriteLine("{2}\tNodes: {0}\tEdges: {1}", nodes, edges, stopwatch.Elapsed);

                // allocate enough space for all the edges.
                var hilbertTransformed = new uint[edges];

                var counts = new uint[1 << 20];
                SingleThreaded.ScanGraph(twitterFile, (vertex, degree, offset, neighbors) =>
                {
                    for (int i = 0; i < degree; i++)
                    {
                        counts[HilbertCurve.xy2dByte(names[vertex], names[neighbors[offset + i]]) >> 32]++;
                    }
                });

                Console.WriteLine("{0}\tHilbert regions sized", stopwatch.Elapsed);
                for (int i = 1; i < counts.Length; i++)
                {
                    counts[i + 1] += counts[i];
                }

                for (int i = counts.Length - 1; i > 0; i--)
                {
                    counts[i] = counts[i] - 1;
                }

                counts[0] = 0;

                var Trie = new BufferTrie <uint>(20, (array, offset, length) =>
                {
                    for (int i = offset; i < offset + length; i++)
                    {
                        hilbertTransformed[counts[array[i].Index]++] = array[i].Value;
                    }
                });

                for (int i = counts.Length - 1; i > 0; i--)
                {
                    counts[i] = counts[i] - 1;
                }

                counts[0] = 0;

                var buffer = new BufferTrie <uint> .Pair[5000000];

                SingleThreaded.ScanGraph(twitterFile, (vertex, degree, offset, neighbors) =>
                {
                    for (int i = 0; i < degree; i++)
                    {
                        var result = HilbertCurve.xy2dByte(names[vertex], names[neighbors[offset + i]]);

                        buffer[i] = new BufferTrie <uint> .Pair((int)(result >> 32), (uint)(result & 0xFFFF));
                    }

                    Trie.Insert(buffer, 0, degree);
                });

                Trie.Flush();

                Console.WriteLine("{0}\tEdges partitioned", stopwatch.Elapsed);

                using (var upper = new System.IO.BinaryWriter(System.IO.File.OpenWrite("twitter-hilbert-upper")))
                {
                    for (uint i = 0; i < counts.Length - 1; i++)
                    {
                        if (counts[i] < counts[i + 1])
                        {
                            uint x = 0, y = 0;
                            HilbertCurve.d2xyByte((i << 32), out x, out y);

                            upper.Write(x);
                            upper.Write(y);
                            upper.Write(counts[i + 1] - counts[i]);
                        }
                    }
                }

                using (var lower = new System.IO.BinaryWriter(System.IO.File.OpenWrite("twitter-hilbert-lower")))
                {
                    for (uint i = 0; i < counts.Length - 1; i++)
                    {
                        Array.Sort(hilbertTransformed, (int)counts[i], (int)(counts[i + 1] - counts[i]));

                        for (uint j = counts[i]; j < counts[i + 1]; j++)
                        {
                            uint x = 0, y = 0;
                            HilbertCurve.d2xyByte((i << 32) + hilbertTransformed[j], out x, out y);

                            lower.Write((UInt16)(x & 0xFFFF));
                            lower.Write((UInt16)(y & 0xFFFF));
                        }
                    }
                }
            }
            #endregion

            #region hilbert pagerank
            if (algorithm == "hilbertpagerank" && dataset == "livejournal")
            {
                unsafe
                {
                    var stopwatch = System.Diagnostics.Stopwatch.StartNew();

                    var nodes = (uint)42000000;

#if UseLargePages
                    var srcRanks = LargePages.AllocateFloats(nodes);
                    var dstRanks = LargePages.AllocateFloats(nodes);
#else
                    var srcRanks = new float[nodes];
                    var dstRanks = new float[nodes];
#endif
                    for (int i = 0; i < nodes; i++)
                    {
                        srcRanks[i] = 1.0f;
                    }

                    SingleThreaded.HilbertPagerank(@"livejournal-hilbert", dstRanks, srcRanks, nodes, 0.85f);

                    Console.WriteLine(stopwatch.Elapsed);
                }
            }

            if (algorithm == "hilbertpagerank" && dataset == "twitter")
            {
                unsafe
                {
                    var stopwatch = System.Diagnostics.Stopwatch.StartNew();

                    var nodes = (uint)42000000;

#if UseLargePages
                    var srcRanks = LargePages.AllocateFloats(nodes);
                    var dstRanks = LargePages.AllocateFloats(nodes);
#else
                    var srcRanks = new float[nodes];
                    var dstRanks = new float[nodes];
#endif
                    for (int i = 0; i < nodes; i++)
                    {
                        srcRanks[i] = 1.0f;
                    }

                    SingleThreaded.HilbertPagerank(@"twitter-hilbert", dstRanks, srcRanks, nodes, 0.85f);

                    Console.WriteLine(stopwatch.Elapsed);
                }
            }

            if (algorithm == "hilbertpagerank" && dataset == "uk-2007-05")
            {
                unsafe
                {
                    var stopwatch = System.Diagnostics.Stopwatch.StartNew();

                    var nodes = (uint)106000000;

                    var srcRanks = LargePages.AllocateFloats(nodes);
                    var dstRanks = LargePages.AllocateFloats(nodes);

                    for (int i = 0; i < nodes; i++)
                    {
                        srcRanks[i] = 1.0f;
                    }

                    SingleThreaded.MultiHilbertPagerank(@"uk-2007-05-hilbert", dstRanks, srcRanks, nodes, 0.85f);

                    Console.WriteLine(stopwatch.Elapsed);
                }
            }
            #endregion

            #region hilbert union find
            if (algorithm == "hilbertunionfind" && dataset == "twitter")
            {
                unsafe
                {
                    var nodes = (uint)42000000;

                    var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                    SingleThreaded.HilbertUnionFind2(@"twitter-hilbert", nodes);
                    Console.WriteLine(stopwatch.Elapsed);
                }
            }

            if (algorithm == "hilbertunionfind" && dataset == "uk-2007-05")
            {
                unsafe
                {
                    var nodes = (uint)106000000;

                    var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                    SingleThreaded.MultiHilbertCC(@"uk-2007-05-hilbert", nodes);
                    Console.WriteLine(stopwatch.Elapsed);
                }
            }

            if (algorithm == "hilbertunionfind" && dataset == "livejournal")
            {
                unsafe
                {
                    var nodes = (uint)42000000;

                    var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                    SingleThreaded.HilbertUnionFind(@"livejournal-hilbert-upper", "livejournal-hilbert-lower", nodes);
                    Console.WriteLine(stopwatch.Elapsed);
                }
            }
            #endregion

            #region page rank
            if (algorithm == "pagerank" && dataset == "uk-2007-05")
            {
                unsafe
                {
                    var stopwatch = System.Diagnostics.Stopwatch.StartNew();

                    var nodes = (uint)106000000;

#if UseLargePages
                    var srcRanks = LargePages.AllocateFloats(nodes);
                    var dstRanks = LargePages.AllocateFloats(nodes);
#else
                    var srcRanks = new float[nodes];
                    var dstRanks = new float[nodes];
#endif
                    SingleThreaded.PageRankFromDisk(ukFile, dstRanks, srcRanks, nodes, 0.85f);

                    Console.WriteLine(stopwatch.Elapsed);
                }
            }

            if (algorithm == "pagerank" && dataset == "twitter")
            {
                unsafe
                {
                    var stopwatch = System.Diagnostics.Stopwatch.StartNew();

                    var nodes = (uint)65000000;

#if UseLargePages
                    var srcRanks = LargePages.AllocateFloats(nodes);
                    var dstRanks = LargePages.AllocateFloats(nodes);
#else
                    var srcRanks = new float[nodes];
                    var dstRanks = new float[nodes];
#endif
                    SingleThreaded.PageRankFromDisk(twitterFile, dstRanks, srcRanks, nodes, 0.85f);

                    Console.WriteLine(stopwatch.Elapsed);
                }
            }

            if (algorithm == "pagerank" && dataset == "livejournal")
            {
                var stopwatch = System.Diagnostics.Stopwatch.StartNew();

                unsafe
                {
                    var nodes = (uint)65000000;

#if UseLargePages
                    var srcRanks = LargePages.AllocateFloats(nodes);
                    var dstRanks = LargePages.AllocateFloats(nodes);
#else
                    var srcRanks = new float[nodes];
                    var dstRanks = new float[nodes];
#endif
                    for (int i = 0; i < 20; i++)
                    {
                        SingleThreaded.PageRankStep(livejournalFile, dstRanks, srcRanks, nodes, 0.85f);
                        Console.WriteLine("{0}\tIteration {1}", stopwatch.Elapsed, i);
                    }
                }

                Console.WriteLine(stopwatch.Elapsed);
            }
            #endregion

            #region connected components
            if (algorithm == "connectedcomponents" && dataset == "twitter")
            {
                var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                SingleThreaded.ConnectedComponents(twitterFile, 65000000);
                Console.WriteLine(stopwatch.Elapsed);
            }

            if (algorithm == "connectedcomponents" && dataset == "uk-2007-05")
            {
                var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                SingleThreaded.ClumsyCC(ukFile, 106000000);
                Console.WriteLine(stopwatch.Elapsed);
            }

            if (algorithm == "connectedcomponents" && dataset == "livejournal")
            {
                var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                SingleThreaded.ConnectedComponents(livejournalFile, 6500000);
                Console.WriteLine(stopwatch.Elapsed);
            }
            #endregion

            #region maximal independent set
            if (algorithm == "maximalindependentset" && dataset == "twitter")
            {
                var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                SingleThreaded.MaximalIndependentSet(twitterFile, 65000000);
                Console.WriteLine(stopwatch.Elapsed);
            }

            if (algorithm == "maximalindependentset" && dataset == "livejournal")
            {
                var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                SingleThreaded.MaximalIndependentSet(livejournalFile, 6500000);
                Console.WriteLine(stopwatch.Elapsed);
            }
            #endregion
        }