Example #1
0
        private List <IStatement> Schedule(DependencyGraph g, IList <IStatement> stmts, bool createFirstIterPostBlocks)
        {
            List <IStatement>     output       = new List <IStatement>();
            List <StatementBlock> blocks       = new List <StatementBlock>();
            List <NodeIndex>      currentBlock = null;
            DirectedGraphFilter <NodeIndex, EdgeIndex> graph2 = new DirectedGraphFilter <NodeIndex, EdgeIndex>(g.dependencyGraph, edge => !g.isDeleted[edge]);
            StrongComponents2 <NodeIndex> scc = new StrongComponents2 <NodeIndex>(graph2.SourcesOf, graph2);

            scc.AddNode        += delegate(NodeIndex node) { currentBlock.Add(node); };
            scc.BeginComponent += delegate() { currentBlock = new List <int>(); };
            scc.EndComponent   += delegate() {
                bool isCyclic = false;
                if (currentBlock.Count == 1)
                {
                    NodeIndex node = currentBlock[0];
                    foreach (NodeIndex source in graph2.SourcesOf(node))
                    {
                        if (source == node)
                        {
                            isCyclic = true;
                            break;
                        }
                    }
                }
                else
                {
                    isCyclic = true;
                }
                if (isCyclic)
                {
                    blocks.Add(new Loop()
                    {
                        indices = currentBlock
                    });
                }
                else
                {
                    blocks.Add(new StraightLine()
                    {
                        indices = currentBlock
                    });
                }
            };
            scc.SearchFrom(graph2.Nodes);
            //scc.SearchFrom(g.outputNodes);

            bool check = false;

            if (check)
            {
                // check that there are no edges from a later component to an earlier component
                Set <NodeIndex> earlierNodes = new Set <int>();
                foreach (StatementBlock block in blocks)
                {
                    earlierNodes.AddRange(block.indices);
                    foreach (NodeIndex node in block.indices)
                    {
                        foreach (NodeIndex source in graph2.SourcesOf(node))
                        {
                            if (!earlierNodes.Contains(source))
                            {
                                Console.WriteLine(g.NodeToString(node) + Environment.NewLine + "   depends on later node " + g.NodeToString(source));
                                Error("Internal error: Strong components are not ordered properly");
                            }
                        }
                    }
                }
            }

            Set <NodeIndex> nodesToMove = new Set <NodeIndex>();
            Dictionary <Loop, IBlockStatement> firstIterPostprocessing = null;

            if (createFirstIterPostBlocks)
            {
                firstIterPostprocessing = GetFirstIterPostprocessing(blocks, graph2, stmts, nodesToMove);
            }
            IVariableDeclaration iteration = Builder.VarDecl("iteration", typeof(int));

            IndexedProperty <NodeIndex, bool> isUniform = graph2.CreateNodeData <bool>(true);

            foreach (StatementBlock block in blocks)
            {
                if (block is Loop)
                {
                    foreach (NodeIndex i in block.indices)
                    {
                        isUniform[i] = false;
                    }
                    IWhileStatement    ws        = Builder.WhileStmt(Builder.LiteralExpr(true));
                    IList <IStatement> whileBody = ws.Body.Statements;

                    if (ContainsIterationStatement(stmts, block.indices))
                    {
                        List <IStatement> nodes = new List <IStatement>();
                        foreach (NodeIndex i in block.indices)
                        {
                            IStatement ist = stmts[i];
                            if (!context.InputAttributes.Has <IterationStatement>(ist))
                            {
                                nodes.Add(ist);
                            }
                        }
                        // build a new dependency graph with the dummy iteration statement removed
                        DependencyGraph   g2  = new DependencyGraph(context, nodes, ignoreMissingNodes: true, ignoreRequirements: true);
                        List <IStatement> sc3 = Schedule(g2, nodes, false);
                        if (sc3.Count == 1 && sc3[0] is IWhileStatement)
                        {
                            ws = (IWhileStatement)sc3[0];
                        }
                        else
                        {
                            // The statements in the outer loop are not strongly connected.
                            // Since we want the next transform to only process strong components,
                            // we mark the outer while loop as DoNotSchedule, leaving only the
                            // inner while loops to be scheduled.
                            // add all statements in sc3 to whileBody, but remove while loops around a single statement.
                            foreach (IStatement ist in sc3)
                            {
                                if (ist is IWhileStatement)
                                {
                                    IWhileStatement iws2 = (IWhileStatement)ist;
                                    if (iws2.Body.Statements.Count == 1)
                                    {
                                        whileBody.AddRange(iws2.Body.Statements);
                                        continue;
                                    }
                                }
                                whileBody.Add(ist);
                            }
                            context.OutputAttributes.Set(ws, new DoNotSchedule());
                        }
                    }
                    else // !ContainsIterationStatement
                    {
                        foreach (NodeIndex i in block.indices)
                        {
                            IStatement st = stmts[i];
                            whileBody.Add(st);
                            DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(st);
                            di.AddClones(clonesOfStatement);
                        }
                        RegisterUnchangedStatements(whileBody);
                    }
                    Loop loop = (Loop)block;
                    if (firstIterPostprocessing != null && firstIterPostprocessing.ContainsKey(loop))
                    {
                        var thenBlock         = firstIterPostprocessing[loop];
                        var iterIsZero        = Builder.BinaryExpr(BinaryOperator.ValueEquality, Builder.VarRefExpr(iteration), Builder.LiteralExpr(0));
                        var firstIterPostStmt = Builder.CondStmt(iterIsZero, thenBlock);
                        context.OutputAttributes.Set(firstIterPostStmt, new FirstIterationPostProcessingBlock());
                        whileBody.Add(firstIterPostStmt);
                    }
                    output.Add(ws);
                }
                else
                {
                    // not cyclic
                    foreach (NodeIndex i in block.indices)
                    {
                        IStatement st = stmts[i];
                        if (!nodesToMove.Contains(i))
                        {
                            output.Add(st);
                            DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(st);
                            di.AddClones(clonesOfStatement);
                        }
                        isUniform[i] = g.IsUniform(i, source => !isUniform[source]);
                        if (isUniform[i] != g.isUniform[i])
                        {
                            Assert.IsTrue(isUniform[i]);
                            g.isUniform[i] = isUniform[i];
                            DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(st);
                            di.IsUniform = isUniform[i];
                        }
                        // mark sources of output statements (for SchedulingTransform)
                        if (g.outputNodes.Contains(i))
                        {
                            foreach (NodeIndex source in graph2.SourcesOf(i))
                            {
                                IStatement sourceSt = stmts[source];
                                if (!context.InputAttributes.Has <OutputSource>(sourceSt))
                                {
                                    context.OutputAttributes.Set(sourceSt, new OutputSource());
                                }
                            }
                        }
                    }
                }
            }
            return(output);
        }
Example #2
0
        public void GraphSearchTest()
        {
            // this is the example graph at http://www.codeproject.com/cs/miscctrl/quickgraph.asp
            Graph <BasicNode> g = new Graph <BasicNode>();
            BasicNode         u = new BasicNode("u");
            BasicNode         v = new BasicNode("v");
            BasicNode         w = new BasicNode("w");
            BasicNode         x = new BasicNode("x");
            BasicNode         y = new BasicNode("y");
            BasicNode         z = new BasicNode("z");

            g.Nodes.Add(u);
            g.Nodes.Add(v);
            g.Nodes.Add(w);
            g.Nodes.Add(x);
            g.Nodes.Add(y);
            g.Nodes.Add(z);
            g.AddEdge(u, v);
            g.AddEdge(u, x);
            g.AddEdge(v, y);
            g.AddEdge(y, x);
            g.AddEdge(x, v);
            g.AddEdge(w, u);
            g.AddEdge(w, y);
            g.AddEdge(w, z);

            DepthFirstSearch <BasicNode> dfs = new DepthFirstSearch <BasicNode>(g);

            dfs.DiscoverNode   += delegate(BasicNode node) { Console.WriteLine("discover " + node); };
            dfs.FinishNode     += delegate(BasicNode node) { Console.WriteLine("finish " + node); };
            dfs.DiscoverEdge   += delegate(Edge <BasicNode> edge) { Console.WriteLine("discover " + edge); };
            dfs.TreeEdge       += delegate(Edge <BasicNode> edge) { Console.WriteLine("tree edge " + edge); };
            dfs.FinishTreeEdge += delegate(Edge <BasicNode> edge) { Console.WriteLine("finish tree edge " + edge); };
            dfs.CrossEdge      += delegate(Edge <BasicNode> edge) { Console.WriteLine("cross edge " + edge); };
            dfs.BackEdge       += delegate(Edge <BasicNode> edge) { Console.WriteLine("back edge " + edge); };
            Console.WriteLine("dfs from u:");
            dfs.SearchFrom(u);
            Console.WriteLine();
            Console.WriteLine("dfs from w:");
            dfs.SearchFrom(w);
            Console.WriteLine();
            dfs.Clear();
            Console.WriteLine("cleared dfs from w:");
            dfs.SearchFrom(w);
            Console.WriteLine();

            Console.WriteLine("bfs:");
            BreadthFirstSearch <BasicNode>      bfs      = new BreadthFirstSearch <BasicNode>(g);
            IndexedProperty <BasicNode, double> distance = g.CreateNodeData <double>(Double.PositiveInfinity);

            bfs.DiscoverNode += delegate(BasicNode node) { Console.WriteLine("discover " + node); };
            bfs.FinishNode   += delegate(BasicNode node) { Console.WriteLine("finish " + node); };
            bfs.TreeEdge     += delegate(Edge <BasicNode> edge)
            {
                Console.WriteLine("tree edge " + edge);
                distance[edge.Target] = distance[edge.Source] + 1;
            };
            // compute distances from w
            distance[w] = 0;
            bfs.SearchFrom(w);
            Console.WriteLine("distances from w:");
            foreach (BasicNode node in g.Nodes)
            {
                Console.WriteLine("[" + node + "] " + distance[node]);
            }
            Assert.Equal(2.0, distance[x]);
            Console.WriteLine();

            Console.WriteLine("distances from w:");
            DistanceSearch <BasicNode> dists = new DistanceSearch <BasicNode>(g);

            dists.SetDistance += delegate(BasicNode node, int dist) { Console.WriteLine("[" + node + "] " + dist); };
            dists.SearchFrom(w);
            Console.WriteLine();

            BasicNode start = z, end;

            (new PseudoPeripheralSearch <BasicNode>(g)).SearchFrom(ref start, out end);
            Console.WriteLine("pseudo-peripheral nodes: " + start + "," + end);

            StrongComponents <BasicNode> scc = new StrongComponents <BasicNode>(g);
            int count = 0;

            scc.AddNode        += delegate(BasicNode node) { Console.Write(" " + node); };
            scc.BeginComponent += delegate()
            {
                Console.Write("[");
                count++;
            };
            scc.EndComponent += delegate() { Console.Write("]"); };
            Console.Write("strong components reachable from w (topological order): ");
            scc.SearchFrom(w);
            Assert.Equal(4, count);
            Console.WriteLine();

            count = 0;
            StrongComponents2 <BasicNode> scc2 = new StrongComponents2 <BasicNode>(g);

            scc2.AddNode        += delegate(BasicNode node) { Console.Write(" " + node); };
            scc2.BeginComponent += delegate()
            {
                Console.Write("[");
                count++;
            };
            scc2.EndComponent += delegate() { Console.Write("]"); };
            Console.Write("strong components reachable from w (rev topological order): ");
            scc2.SearchFrom(w);
            Assert.Equal(4, count);
            Console.WriteLine();

#if false
            Console.WriteLine("CyclicDependencySort:");
            List <BasicNode> schedule = CyclicDependencySort <BasicNode> .Schedule(g,
                                                                                   delegate(BasicNode node, ICollection <BasicNode> available) {
                if (node == x)
                {
                    return(available.Contains(u));
                }
                else
                {
                    return(false);
                }
            },
                                                                                   g.Nodes);

            foreach (BasicNode node in schedule)
            {
                Console.Write(node + " ");
            }
            Console.WriteLine();
            Assert.Equal <int>(6, schedule.Count);
            // order should be: w u x v y z (z can be re-ordered)
            Assert.Equal <BasicNode>(w, schedule[0]);
            Assert.Equal <BasicNode>(u, schedule[1]);
            //Assert.Equal<BasicNode>(z,schedule[5]);
#endif
        }