Пример #1
0
        public void SimpleCycle()
        {
            var    graph = new MutableDirectedGraph();
            NodeId a     = graph.CreateNode();
            NodeId b     = graph.CreateNode();
            NodeId c     = graph.CreateNode();
            NodeId d     = graph.CreateNode();
            NodeId e     = graph.CreateNode();
            NodeId f     = graph.CreateNode();

            graph.AddEdge(a, b);
            graph.AddEdge(b, c);
            graph.AddEdge(c, b); // Cycle-forming backedge (violates topo order).
            graph.AddEdge(d, e);
            graph.AddEdge(e, f);

            XAssert.IsTrue(graph.IsReachableFrom(a, b), "Shouldn't visit the backedge");
            XAssert.IsTrue(graph.IsReachableFrom(a, c), "Shouldn't visit the backedge");

            try
            {
                // Note that to fail, we need a > e here due to a fast-path for 'unreachable'
                // that doesn't look at any edges.
                graph.IsReachableFrom(a, f); // Fails since it should find the backedge c -> b
            }
            catch (BuildXLException)
            {
                return;
            }

            XAssert.Fail("Expected a failure due to a topological order violation");
        }
Пример #2
0
        /// <summary>
        /// Creates a test graph.
        /// There are light edges between nodes 0 - 1, 1 - 2, and 2 - 0.
        /// There are heavy edges between 0 - 1 and 1 - 3
        /// </summary>
        private static void CreateGraphWithLightEdges(out MutableDirectedGraph graph, out NodeId[] nodes)
        {
            graph = new MutableDirectedGraph();
            XAssert.AreEqual(graph.NodeCount, 0);
            XAssert.AreEqual(graph.EdgeCount, 0);

            // Test creation.
            nodes = new NodeId[4];
            for (int i = 0; i < nodes.Length; ++i)
            {
                nodes[i] = graph.CreateNode();
            }

            XAssert.AreEqual(graph.NodeCount, nodes.Length);
            XAssert.AreEqual(graph.EdgeCount, 0);

            foreach (NodeId t in nodes)
            {
                XAssert.IsTrue(graph.ContainsNode(t));
                XAssert.IsTrue(graph.IsSourceNode(t));
                XAssert.IsTrue(graph.IsSinkNode(t));
            }

            graph.AddEdge(nodes[0], nodes[1], isLight: true);
            graph.AddEdge(nodes[1], nodes[2], isLight: true);
            graph.AddEdge(nodes[2], nodes[0], isLight: true);
            graph.AddEdge(nodes[0], nodes[1], isLight: false);
            graph.AddEdge(nodes[1], nodes[3], isLight: false);
        }
Пример #3
0
        public void TestGraphSerializationWithLightEdges()
        {
            using (var tempStorage = new TempFileStorage(canGetFileNames: true, rootPath: TestOutputDirectory))
            {
                MutableDirectedGraph graph;
                NodeId[]             nodes;

                CreateGraphWithLightEdges(out graph, out nodes);

                string fileName = tempStorage.GetUniqueFileName();
                using (FileStream fileStream = File.Open(fileName, FileMode.Create))
                {
                    var writer = new BuildXLWriter(debug: false, stream: fileStream, leaveOpen: false, logStats: false);
                    graph.Serialize(writer);
                }

                MutableDirectedGraph newGraph;

                using (FileStream fileStream = File.Open(fileName, FileMode.Open))
                {
                    var reader = new BuildXLReader(debug: false, stream: fileStream, leaveOpen: false);
                    newGraph = MutableDirectedGraph.Deserialize(reader);
                }

                XAssert.AreEqual(newGraph.NodeCount, nodes.Length);
                XAssert.AreEqual(newGraph.EdgeCount, 5);

                XAssert.IsTrue(newGraph.ContainsEdge(nodes[0], nodes[1], isLight: true));
                XAssert.IsTrue(newGraph.ContainsEdge(nodes[0], nodes[1], isLight: false));
                XAssert.IsFalse(newGraph.ContainsEdge(nodes[1], nodes[0], isLight: true));
                XAssert.IsFalse(newGraph.ContainsEdge(nodes[1], nodes[0], isLight: false));
                XAssert.IsFalse(newGraph.ContainsEdge(nodes[1], nodes[3], isLight: true));
            }
        }
Пример #4
0
        public async Task TestGraphSerialization()
        {
            using (var stream = new MemoryStream())
            {
                MutableDirectedGraph graph;
                NodeId[]             nodes;

                CreateGraph(out graph, out nodes);

                var writer = new BuildXLWriter(debug: false, stream: stream, leaveOpen: true, logStats: false);
                graph.Serialize(writer);

                MutableDirectedGraph newMutableGraph;
                stream.Position = 0;
                var reader = new BuildXLReader(debug: false, stream: stream, leaveOpen: true);
                newMutableGraph = MutableDirectedGraph.Deserialize(reader);

                DeserializedDirectedGraph newImmutableDirectedGraph;
                stream.Position           = 0;
                newImmutableDirectedGraph = await DeserializedDirectedGraph.DeserializeAsync(reader);

                XAssert.IsTrue(newMutableGraph.ContainsEdge(nodes[11], nodes[8]));
                XAssert.IsFalse(newMutableGraph.ContainsEdge(nodes[11], nodes[2]));

                TestGraphSerializationPerformCommonValidations(newImmutableDirectedGraph, nodes, graph);
                TestGraphSerializationPerformCommonValidations(newMutableGraph, nodes, graph);
            }
        }
Пример #5
0
        public void DisconnectedNodes()
        {
            var    graph = new MutableDirectedGraph();
            NodeId a     = graph.CreateNode();
            NodeId b     = graph.CreateNode();

            XAssert.IsFalse(graph.IsReachableFrom(a, b));
            XAssert.IsFalse(graph.IsReachableFrom(b, a));
        }
Пример #6
0
        public void TriviallyConnectedNodes()
        {
            var    graph = new MutableDirectedGraph();
            NodeId a     = graph.CreateNode();
            NodeId b     = graph.CreateNode();

            graph.AddEdge(a, b);

            XAssert.IsTrue(graph.IsReachableFrom(a, b));
            XAssert.IsFalse(graph.IsReachableFrom(b, a));
        }
Пример #7
0
        public void TopologicalOrderViolationsIgnoredIfRequested()
        {
            var    graph = new MutableDirectedGraph();
            NodeId a     = graph.CreateNode();
            NodeId b     = graph.CreateNode();
            NodeId c     = graph.CreateNode();
            NodeId d     = graph.CreateNode();

            graph.AddEdge(a, b);
            graph.AddEdge(d, c); // This edge breaks the topological labelling.

            XAssert.IsFalse(graph.IsReachableFrom(a, c, skipOutOfOrderNodes: true));
        }
Пример #8
0
        public void ReadJsonGraph(string path, string targetPath = null, bool loadTargetIfApplicable = true)
        {
            if (loadTargetIfApplicable && targetPath != null && File.Exists(targetPath))
            {
                if (Deserialize(targetPath))
                {
                    return;
                }
            }

            MutableDataflowGraph = new MutableDirectedGraph();
            DataflowGraph        = MutableDataflowGraph;
            using (var stream = new ProgressStream(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 64 << 10), "JsonData"))
                using (var textReader = new StreamReader(stream))
                    using (var textWriter = new StreamWriter(Path.ChangeExtension(targetPath, ".filter.json")))
                        using (var reader = new JsonFilter(path, new JsonTextReader(textReader), new JsonTextWriter(textWriter)))
                        {
                            AssertPostRead(reader, JsonToken.StartObject);
                            while (reader.Read() && reader.TokenType == JsonToken.PropertyName)
                            {
                                string propertyName = (string)reader.Value;
                                switch (propertyName)
                                {
                                case "graph":
                                    ReadGraph(reader);
                                    break;

                                case "execution":
                                    ReadExecutions(reader);
                                    break;

                                case "pips":
                                    ReadPips(reader);
                                    break;

                                default:
                                    reader.Skip();
                                    break;
                                }
                            }
                        }

            AddEdges();

            Compute();

            if (targetPath != null)
            {
                Serialize(targetPath);
            }
        }
Пример #9
0
        private static IReadonlyDirectedGraph CreateRandomAcyclicGraph(Random rng, int nodeCount)
        {
            var graph = new MutableDirectedGraph();
            var nodes = new NodeId[nodeCount];

            for (int i = 0; i < nodeCount; i++)
            {
                nodes[i] = graph.CreateNode();
            }

            for (int i = 0; i < nodeCount; i++)
            {
                int toIndex = i;
                while ((toIndex = rng.Next(toIndex + 1, nodeCount)) < nodeCount)
                {
                    graph.AddEdge(nodes[i], nodes[toIndex]);
                }
            }

            return(graph);
        }
Пример #10
0
        public void TrivialViolationOfTopologicalOrder()
        {
            var    graph = new MutableDirectedGraph();
            NodeId a     = graph.CreateNode();
            NodeId b     = graph.CreateNode();
            NodeId c     = graph.CreateNode();
            NodeId d     = graph.CreateNode();

            graph.AddEdge(a, b);
            graph.AddEdge(d, c); // This edge breaks the topological labelling.

            try
            {
                // Note that to fail, we need c > a here due to a fast-path for 'unreachable'
                // that doesn't look at any edges.
                graph.IsReachableFrom(a, c);
            }
            catch (BuildXLException)
            {
                return;
            }

            XAssert.Fail("Expected a failure due to a topological order violation");
        }
Пример #11
0
        public void MultipleLevels()
        {
            var graph = new MutableDirectedGraph();

            NodeId l0 = graph.CreateNode();

            NodeId l1_n1 = graph.CreateNode();
            NodeId l1_n2 = graph.CreateNode();

            graph.AddEdge(l0, l1_n1);
            graph.AddEdge(l0, l1_n2);
            graph.AddEdge(l1_n1, l1_n2);

            NodeId l2_n1 = graph.CreateNode();
            NodeId l2_n2 = graph.CreateNode();

            graph.AddEdge(l1_n1, l2_n1);
            graph.AddEdge(l1_n2, l2_n2);

            NodeId l3_n1 = graph.CreateNode();
            NodeId l3_n2 = graph.CreateNode();

            graph.AddEdge(l2_n1, l3_n1);
            graph.AddEdge(l2_n2, l3_n2);

            NodeId l4 = graph.CreateNode();

            graph.AddEdge(l3_n1, l4);
            graph.AddEdge(l3_n2, l4);

            XAssert.IsTrue(graph.IsReachableFrom(l1_n1, l3_n2));
            XAssert.IsTrue(graph.IsReachableFrom(l0, l4));

            XAssert.IsFalse(graph.IsReachableFrom(l3_n2, l1_n1));
            XAssert.IsFalse(graph.IsReachableFrom(l4, l0));
        }
Пример #12
0
        /// <summary>
        /// Creates a test graph.
        /// </summary>
        private static void CreateGraph(out MutableDirectedGraph graph, out NodeId[] nodes)
        {
            graph = new MutableDirectedGraph();
            XAssert.AreEqual(graph.NodeCount, 0);
            XAssert.AreEqual(graph.EdgeCount, 0);

            // Test creation.
            nodes = new NodeId[12];
            for (int i = 0; i < nodes.Length; ++i)
            {
                nodes[i] = graph.CreateNode();
            }

            XAssert.AreEqual(graph.NodeCount, nodes.Length);
            XAssert.AreEqual(graph.EdgeCount, 0);

            foreach (NodeId t in nodes)
            {
                XAssert.IsTrue(graph.ContainsNode(t));
                XAssert.IsTrue(graph.IsSourceNode(t));
                XAssert.IsTrue(graph.IsSinkNode(t));
            }

            graph.AddEdge(nodes[5], nodes[0]);
            graph.AddEdge(nodes[5], nodes[1]);
            graph.AddEdge(nodes[6], nodes[1]);
            graph.AddEdge(nodes[6], nodes[2]);
            graph.AddEdge(nodes[7], nodes[5]);
            graph.AddEdge(nodes[8], nodes[5]);
            graph.AddEdge(nodes[9], nodes[6]);
            graph.AddEdge(nodes[9], nodes[3]);
            graph.AddEdge(nodes[9], nodes[4]);
            graph.AddEdge(nodes[10], nodes[8]);
            graph.AddEdge(nodes[11], nodes[8]);
            graph.AddEdge(nodes[11], nodes[9]);
        }
Пример #13
0
 public ComputationContext(MutableDirectedGraph graph)
 {
     Dependencies = new VisitationTracker(graph);
     Dependents   = new VisitationTracker(graph);
     Visitor      = new NodeVisitor(graph);
 }