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"); }
/// <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); }
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)); } }
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); } }
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)); }
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)); }
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)); }
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); } }
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); }
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"); }
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)); }
/// <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]); }
public ComputationContext(MutableDirectedGraph graph) { Dependencies = new VisitationTracker(graph); Dependents = new VisitationTracker(graph); Visitor = new NodeVisitor(graph); }