/// <summary>
        /// Returns all nodes in the schedule whose target appears prior to the node.
        /// </summary>
        /// <param name="g"></param>
        /// <param name="schedule"></param>
        /// <returns></returns>
        internal static Set <NodeIndex> CollectUses(IndexedGraph g, IEnumerable <NodeIndex> schedule)
        {
            Set <NodeIndex> uses      = new Set <NodeIndex>();
            Set <NodeIndex> available = new Set <NodeIndex>();

            foreach (NodeIndex node in schedule)
            {
                foreach (NodeIndex source in g.SourcesOf(node))
                {
                    if (!available.Contains(source))
                    {
                        uses.Add(source);
                    }
                }
                available.Add(node);
            }
            return(uses);
        }
Exemple #2
0
        /// <summary>
        /// Returns all nodes in the schedule whose target appears prior to the node.
        /// </summary>
        /// <param name="g"></param>
        /// <param name="schedule"></param>
        /// <param name="isDeleted"></param>
        /// <returns></returns>
        internal static Set <NodeIndex> CollectUses(IndexedGraph g, IEnumerable <NodeIndex> schedule, Func <EdgeIndex, bool> isDeleted = null)
        {
            Set <NodeIndex> uses      = new Set <NodeIndex>();
            Set <NodeIndex> available = new Set <NodeIndex>();

            foreach (NodeIndex node in schedule)
            {
                foreach (EdgeIndex edge in g.EdgesInto(node).Where(e => isDeleted == null || !isDeleted(e)))
                {
                    NodeIndex source = g.SourceOf(edge);
                    if (!available.Contains(source))
                    {
                        uses.Add(source);
                    }
                }
                available.Add(node);
            }
            return(uses);
        }
Exemple #3
0
        int CalculateNodeDepth(IndexedGraph <string, Orbit> orbits)
        {
            foreach (var orbit in orbits.DepthFirstWalk())
            {
                if (orbit.Name != "COM")
                {
                    orbit.Depth = orbits.GetParent(orbit).Depth + 1;
                }
            }

            var total = 0;

            foreach (var orbit in orbits.DepthFirstWalk())
            {
                total += orbit.Depth;
            }

            return(total);
        }
Exemple #4
0
        IndexedGraph <string, Orbit> BuildOrbits(Dictionary <string, string> orbitsDef)
        {
            var orbits = new IndexedGraph <string, Orbit>();

            orbits["COM"] = new Orbit("COM");
            foreach (var orbit in orbitsDef.Keys)
            {
                orbits[orbit] = new Orbit(orbit);
            }

            foreach (var orbit in orbitsDef)
            {
                orbits.AddParentChildLink(orbit.Value, orbit.Key);
            }

            orbits.Root = orbits["COM"];

            return(orbits);
        }
        internal static IEnumerable <NodeIndex> GetOverwrites(BasicTransformContext context, IndexedGraph dependencyGraph, NodeIndex writer,
                                                              List <IStatement> nodes, Dictionary <IStatement, int> indexOfNode)
        {
            IStatement            ist = nodes[writer];
            DependencyInformation di  = context.InputAttributes.Get <DependencyInformation>(ist);

            if (di == null)
            {
                context.Error("Dependency information not found for statement: " + ist);
                di = new DependencyInformation();
            }
            foreach (IStatement previousWriteStmt in di.Overwrites)
            {
                NodeIndex previousWriter = indexOfNode[previousWriteStmt];
                if (previousWriter < writer)
                {
                    yield return(previousWriter);
                }
            }
        }
Exemple #6
0
            public void VisualizeDependencyGraph(IndexedGraph dg, IEnumerable <EdgeStylePredicate> edgeStyles = null, Func <int, string> nodeName = null, Func <int, string> edgeName = null, string visualizationTitle = "Dependency_Graph")
            {
                DependencyGraphView view = new DependencyGraphView(dg, edgeStyles, nodeName, edgeName);

                view.Show(visualizationTitle);
            }
        protected override void DoConvertMethodBody(IList <IStatement> outputs, IList <IStatement> inputs)
        {
            List <int> whileNumberOfNode = new List <int>();
            List <int> fusedCountOfNode  = new List <int>();
            List <List <IStatement> > containersOfNode = new List <List <IStatement> >();
            // the code may have multiple while(true) loops, however these must be disjoint.
            // therefore we treat 'while' as one container, but give each loop a different 'while number'.
            int outerWhileCount         = 0;
            int currentOuterWhileNumber = 0;
            int currentFusedCount       = 0;
            List <Set <IVariableDeclaration> > loopVarsOfWhileNumber = new List <Set <IVariableDeclaration> >();
            // build the dependency graph
            var g = new DependencyGraph2(context, inputs, DependencyGraph2.BackEdgeHandling.Ignore,
                                         delegate(IWhileStatement iws)
            {
                if (iws is IFusedBlockStatement)
                {
                    if (iws.Condition is IVariableReferenceExpression)
                    {
                        currentFusedCount++;
                    }
                }
                else
                {
                    outerWhileCount++;
                    currentOuterWhileNumber = outerWhileCount;
                }
            },
                                         delegate(IWhileStatement iws)
            {
                if (iws is IFusedBlockStatement)
                {
                    if (iws.Condition is IVariableReferenceExpression)
                    {
                        currentFusedCount--;
                    }
                }
                else
                {
                    currentOuterWhileNumber = 0;
                }
            },
                                         delegate(IConditionStatement ics)
            {
            },
                                         delegate(IConditionStatement ics)
            {
            },
                                         delegate(IStatement ist, int targetIndex)
            {
                int whileNumber = currentOuterWhileNumber;
                whileNumberOfNode.Add(whileNumber);
                fusedCountOfNode.Add(currentFusedCount);
                List <IStatement> containers = new List <IStatement>();
                LoopMergingTransform.UnwrapStatement(ist, containers);
                containersOfNode.Add(containers);
                for (int i = 0; i < currentFusedCount; i++)
                {
                    if (containers[i] is IForStatement ifs)
                    {
                        var loopVar = Recognizer.LoopVariable(ifs);
                        if (loopVarsOfWhileNumber.Count <= whileNumber)
                        {
                            while (loopVarsOfWhileNumber.Count <= whileNumber)
                            {
                                loopVarsOfWhileNumber.Add(new Set <IVariableDeclaration>());
                            }
                        }
                        Set <IVariableDeclaration> loopVars = loopVarsOfWhileNumber[whileNumber];
                        loopVars.Add(loopVar);
                    }
                }
            });
            var nodes           = g.nodes;
            var dependencyGraph = g.dependencyGraph;

            for (int whileNumber = 1; whileNumber < loopVarsOfWhileNumber.Count; whileNumber++)
            {
                foreach (var loopVar in loopVarsOfWhileNumber[whileNumber])
                {
                    // Any statement (in the while loop) that has a forward descendant and a backward descendant will be cloned, so we want to minimize the number of such nodes.
                    // The free variables in this problem are the loop directions at the leaf statements, since all other loop directions are forced by these.
                    // We find the optimal labeling of the free variables by solving a min cut problem on a special network.
                    // The network is constructed so that the cost of a cut is equal to the number of statements that will be cloned.
                    // The network has 2 nodes for every statement: an in-node and an out-node.
                    // For a non-leaf statement, there is a capacity 1 edge from the in-node to out-node.  This edge is cut when the statement is cloned.
                    // For a leaf statement, there is an infinite capacity edge in both directions, or equivalently a single node.
                    // If statement A depends on statement B, then there is an infinite capacity edge from in-A to in-B, and from out-B to out-A,
                    // representing the fact that cloning A requires cloning B, but not the reverse.
                    // If a statement must appear with a forward loop, it is connected to the source.
                    // If a statement must appear with a backward loop, it is connected to the sink.

                    // construct a capacitated graph
                    int inNodeStart  = 0;
                    int outNodeStart = inNodeStart + dependencyGraph.Nodes.Count;
                    int sourceNode   = outNodeStart + dependencyGraph.Nodes.Count;
                    int sinkNode     = sourceNode + 1;
                    int cutNodeCount = sinkNode + 1;
                    Func <NodeIndex, int> getInNode       = node => node + inNodeStart;
                    Func <NodeIndex, int> getOutNode      = node => node + outNodeStart;
                    IndexedGraph          network         = new IndexedGraph(cutNodeCount);
                    const float           infinity        = 1000000f;
                    List <float>          capacity        = new List <float>();
                    List <NodeIndex>      nodesOfInterest = new List <NodeIndex>();
                    foreach (var node in dependencyGraph.Nodes)
                    {
                        if (whileNumberOfNode[node] != whileNumber)
                        {
                            continue;
                        }
                        NodeIndex         source             = node;
                        List <IStatement> containersOfSource = containersOfNode[source];
                        bool hasLoopVar = containersOfSource.Any(container => container is IForStatement && Recognizer.LoopVariable((IForStatement)container) == loopVar);
                        if (!hasLoopVar)
                        {
                            continue;
                        }
                        nodesOfInterest.Add(node);
                        IStatement sourceSt            = nodes[source];
                        var        readAfterWriteEdges = dependencyGraph.EdgesOutOf(source).Where(edge => !g.isWriteAfterRead[edge]);
                        bool       isLeaf  = true;
                        int        inNode  = getInNode(node);
                        int        outNode = getOutNode(node);
                        foreach (var target in readAfterWriteEdges.Select(dependencyGraph.TargetOf))
                        {
                            List <IStatement> containersOfTarget = containersOfNode[target];
                            IStatement        targetSt           = nodes[target];
                            ForEachMatchingLoopVariable(containersOfSource, containersOfTarget, (loopVar2, afs, bfs) =>
                            {
                                if (loopVar2 == loopVar)
                                {
                                    int inTarget  = getInNode(target);
                                    int outTarget = getOutNode(target);
                                    network.AddEdge(inTarget, inNode);
                                    capacity.Add(infinity);
                                    network.AddEdge(outNode, outTarget);
                                    capacity.Add(infinity);
                                    isLeaf = false;
                                }
                            });
                        }
                        if (isLeaf)
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} leaf {sourceSt}");
                            }
                            network.AddEdge(inNode, outNode);
                            capacity.Add(infinity);
                            network.AddEdge(outNode, inNode);
                            capacity.Add(infinity);
                        }
                        else
                        {
                            network.AddEdge(inNode, outNode);
                            capacity.Add(1f);
                        }
                        int       fusedCount = fusedCountOfNode[node];
                        Direction desiredDirectionOfSource = GetDesiredDirection(loopVar, containersOfSource, fusedCount);
                        if (desiredDirectionOfSource == Direction.Forward)
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} forward {sourceSt}");
                            }
                            network.AddEdge(sourceNode, inNode);
                            capacity.Add(infinity);
                        }
                        else if (desiredDirectionOfSource == Direction.Backward)
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} backward {sourceSt}");
                            }
                            network.AddEdge(outNode, sinkNode);
                            capacity.Add(infinity);
                        }
                    }
                    network.IsReadOnly = true;

                    // compute the min cut
                    MinCut <NodeIndex, EdgeIndex> mc = new MinCut <EdgeIndex, EdgeIndex>(network, e => capacity[e]);
                    mc.Sources.Add(sourceNode);
                    mc.Sinks.Add(sinkNode);
                    Set <NodeIndex> sourceGroup = mc.GetSourceGroup();
                    foreach (NodeIndex node in nodesOfInterest)
                    {
                        IStatement sourceSt   = nodes[node];
                        bool       forwardIn  = sourceGroup.Contains(getInNode(node));
                        bool       forwardOut = sourceGroup.Contains(getOutNode(node));
                        if (forwardIn != forwardOut)
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} will clone {sourceSt}");
                            }
                        }
                        else if (forwardIn)
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} wants forward {sourceSt}");
                            }
                        }
                        else
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} wants backward {sourceSt}");
                            }
                            var  containers    = containersOfNode[node];
                            bool isForwardLoop = true;
                            foreach (var container in containers)
                            {
                                if (container is IForStatement)
                                {
                                    IForStatement ifs = (IForStatement)container;
                                    if (Recognizer.LoopVariable(ifs) == loopVar)
                                    {
                                        isForwardLoop = Recognizer.IsForwardLoop(ifs);
                                    }
                                }
                            }
                            if (isForwardLoop)
                            {
                                Set <IVariableDeclaration> loopVarsToReverse;
                                if (!loopVarsToReverseInStatement.TryGetValue(sourceSt, out loopVarsToReverse))
                                {
                                    // TODO: re-use equivalent sets
                                    loopVarsToReverse = new Set <IVariableDeclaration>();
                                    loopVarsToReverseInStatement.Add(sourceSt, loopVarsToReverse);
                                }
                                loopVarsToReverse.Add(loopVar);
                            }
                        }
                    }
                }
            }

            base.DoConvertMethodBody(outputs, inputs);
        }
Exemple #8
0
 public IndexedAStarPathFinder(IndexedGraph <N> graph) : this(graph, false)
 {
 }
            public void VisualizeDependencyGraph(IndexedGraph dg, IEnumerable <EdgeStylePredicate> edgeStyles = null, Func <int, string> nodeName = null, Func <int, string> edgeName = null, string visualizationTitle = "Infer.NET Dependency Graph Viewer")
            {
                var view = new DependencyGraphView(dg, edgeStyles, nodeName, edgeName);

                view.RunInForm(visualizationTitle);
            }
Exemple #10
0
 internal DependencyGraphView(IndexedGraph dg, IEnumerable <EdgeStylePredicate> edgeStyles = null,
                              Func <NodeIndex, string> nodeName = null,
                              Func <EdgeIndex, string> edgeName = null)
 {
     this.dg         = dg;
     this.edgeStyles = edgeStyles;
     this.nodeName   = nodeName;
     this.edgeName   = edgeName;
     nodeOf          = dg.CreateNodeData <Node>(null);
     OnGraphChanged();
     panel.Dock   = DockStyle.Fill;
     gviewer.Dock = DockStyle.Fill;
     panel.Controls.Add(gviewer);
     if (edgeStyles != null)
     {
         // draw the legend
         TableLayoutPanel legend = new TableLayoutPanel();
         legend.AutoSize    = true;
         legend.ColumnCount = 2 * edgeStyles.Count();
         foreach (EdgeStylePredicate esp in edgeStyles)
         {
             PictureBox pic = new PictureBox();
             pic.SizeMode = PictureBoxSizeMode.AutoSize;
             legend.Controls.Add(pic);
             int size     = 8;
             var bitmap   = new System.Drawing.Bitmap(size, size);
             var graphics = System.Drawing.Graphics.FromImage(bitmap);
             var color    = System.Drawing.Color.Black;
             if ((esp.Style & EdgeStyle.Dimmed) > 0)
             {
                 color = System.Drawing.Color.LightGray;
             }
             else if ((esp.Style & EdgeStyle.Back) > 0)
             {
                 color = System.Drawing.Color.Red;
             }
             else if ((esp.Style & EdgeStyle.Blue) > 0)
             {
                 color = System.Drawing.Color.Blue;
             }
             int width = 1;
             if ((esp.Style & EdgeStyle.Bold) > 0)
             {
                 width = 2;
             }
             var pen = new System.Drawing.Pen(color, width);
             if ((esp.Style & EdgeStyle.Dashed) > 0)
             {
                 pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
             }
             int y = bitmap.Height / 2;
             graphics.DrawLine(pen, 0, y, bitmap.Width - 1, y);
             pic.Image = bitmap;
             ToolLabel label = new ToolLabel();
             label.Text     = esp.Name;
             label.AutoSize = true;
             legend.Controls.Add(label);
         }
         legend.Anchor = AnchorStyles.None; // centers the legend in its parent
         TableLayoutPanel legendPanel = new TableLayoutPanel();
         legendPanel.AutoSize  = true;
         legendPanel.BackColor = System.Drawing.Color.LightGray;
         legendPanel.Controls.Add(legend);
         legendPanel.Dock = DockStyle.Bottom;
         panel.Controls.Add(legendPanel);
     }
 }
Exemple #11
0
#pragma warning restore 162
#endif

        private void PostProcess()
        {
            // create a dependency graph between MethodInvokes
            Dictionary <IVariableDeclaration, List <int> > mutationsOfVariable = new Dictionary <IVariableDeclaration, List <NodeIndex> >();
            IndexedGraph g = new IndexedGraph(factorExprs.Count);

            foreach (NodeIndex node in g.Nodes)
            {
                IExpression factor = factorExprs[node];
                NodeInfo    info   = GetNodeInfo(factor);
                for (int i = 0; i < info.arguments.Count; i++)
                {
                    if (info.isReturnOrOut[i])
                    {
                        // this is a mutation.  add to mutationsOfVariable.
                        IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(info.arguments[i]);
                        if (ivd != null && CodeRecognizer.IsStochastic(context, ivd))
                        {
                            List <int> nodes;
                            if (!mutationsOfVariable.TryGetValue(ivd, out nodes))
                            {
                                nodes = new List <NodeIndex>();
                                mutationsOfVariable[ivd] = nodes;
                            }
                            nodes.Add(node);
                        }
                    }
                }
            }
            foreach (NodeIndex node in g.Nodes)
            {
                IExpression factor = factorExprs[node];
                NodeInfo    info   = GetNodeInfo(factor);
                for (int i = 0; i < info.arguments.Count; i++)
                {
                    if (!info.isReturnOrOut[i])
                    {
                        // not a mutation.  create a dependency on all mutations.
                        IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(info.arguments[i]);
                        if (ivd != null && CodeRecognizer.IsStochastic(context, ivd))
                        {
                            foreach (NodeIndex source in mutationsOfVariable[ivd])
                            {
                                g.AddEdge(source, node);
                            }
                        }
                    }
                }
            }
            List <NodeIndex>             topo_nodes = new List <NodeIndex>();
            DepthFirstSearch <NodeIndex> dfs        = new DepthFirstSearch <NodeIndex>(g.SourcesOf, g);

            dfs.FinishNode += delegate(NodeIndex node)
            {
                IExpression factor = factorExprs[node];
                ProcessFactor(factor, MessageDirection.Forwards);
                topo_nodes.Add(node);
            };
            // process nodes forward
            dfs.SearchFrom(g.Nodes);
            // process nodes backward
            for (int i = topo_nodes.Count - 1; i >= 0; i--)
            {
                NodeIndex   node   = topo_nodes[i];
                IExpression factor = factorExprs[node];
                ProcessFactor(factor, MessageDirection.Backwards);
            }
        }