コード例 #1
0
        private int FindClockPeriod(DelayGraphVertex vertex, Dictionary <DelayGraphVertex, int> computedDelays, out bool foundCycle)
        {
            int periodEstimatedFromThisTerminalForward =
                TraverseForwardCalculatingPeriodIterative(vertex, computedDelays, out foundCycle);

            return(periodEstimatedFromThisTerminalForward);
        }
コード例 #2
0
 private static long GetLatencyCost(DelayGraphVertex v, HashSet <DelayGraphVertex> registered)
 {
     if (v.IsRegistered || registered.Contains(v))
     {
         return(v.LatencyCostIfRegistered);
     }
     return(0);
 }
コード例 #3
0
        private int TraverseForwardCalculatingPeriod(
            DelayGraphVertex startingVertex, out bool foundCycle)
        {
            var computedDelays = new Dictionary <DelayGraphVertex, int>();
            var visiting       = new HashSet <DelayGraphVertex>();

            return(TraverseForwardCalculatingPeriodRecursive(startingVertex, out foundCycle, visiting, computedDelays));
        }
コード例 #4
0
        /// <summary>
        /// Iterative version of topological sort, of forward edges only
        /// </summary>
        /// <param name="v">a delay graph vertex</param>
        /// <param name="sorted">linked list of sorted list of vertices</param>
        /// <param name="visited">to keep track of vertices that have been visited previously</param>
        /// <param name="graph">the delay graph</param>
        /// <returns>return true iff v is processed as unvisited</returns>
        private static bool TopoIterative(DelayGraphVertex v, LinkedList <DelayGraphVertex> sorted, Dictionary <DelayGraphVertex, VisitState> visited, DelayGraph graph)
        {
            // add v to visited first, and if it is already visited, then bail
            if (visited.ContainsKey(v))
            {
                return(false);
            }

            var stack = new Stack <DelayGraphVertex>();

            visited[v] = VisitState.Queued;
            stack.Push(v);

            while (stack.Any())
            {
                var curr   = stack.Peek();
                var status = visited[curr];

                if (status == VisitState.Queued)
                {
                    // first ever visit, queue all outgoing vertices
                    visited[curr] = VisitState.Visiting;
                    var outEdges = graph.GetForwardOutEdges(curr);
                    foreach (var e in outEdges.Reverse())
                    {
                        var        next = e.Target;
                        VisitState nextStatus;
                        if (!visited.TryGetValue(next, out nextStatus) ||
                            nextStatus == VisitState.Queued)
                        {
                            // not visited yet, or previously queued, queue next
                            visited[next] = VisitState.Queued;
                            stack.Push(next);
                        }
                        else if (nextStatus == VisitState.Visiting)
                        {
                            // found a cycle - not supposed to happen - there is no good topological sort with cycles
                            return(false);
                        }
                        // othewise: visited, no need to queue it again
                    }
                }
                else if (status == VisitState.Visiting)
                {
                    // second visit - all fanout have been processed already
                    visited[curr] = VisitState.Visited;
                    sorted.AddFirst(curr);
                    stack.Pop();
                }
                else
                {
                    // visited - previously added to sorted already, just pop it
                    stack.Pop();
                }
            }

            return(true);
        }
コード例 #5
0
            /// <summary>
            /// allocate and enter a data into WaveFrontDictionary for vertex v, initialized to refCount
            /// </summary>
            /// <param name="v">a vertex</param>
            /// <param name="refCount">the reference count for number of uses before deleting from dictionary</param>
            /// <param name="data">The data for this definition.</param>
            /// <returns>the allocated data</returns>
            internal void Define(DelayGraphVertex v, int refCount, T data)
            {
                var packet = new Packet <T>(refCount, data);

                if (refCount > 0)
                {
                    this[v] = packet;
                }
            }
コード例 #6
0
        private static IEnumerable <DelayGraphVertex> GetFanouts(DelayGraphVertex v, DelayGraph graph)
        {
            IEnumerable <DelayGraphEdge> edges;

            if (graph.TryGetOutEdges(v, out edges))
            {
                return(edges.Select(e => e.Target));
            }
            return(Enumerable.Empty <DelayGraphVertex>());
        }
コード例 #7
0
 /// <summary>
 /// if myData is null, create it and register it into table using table.Define() for vertex v
 /// </summary>
 /// <param name="table">the wavefront dictionary</param>
 /// <param name="v">a vertex</param>
 /// <param name="myRefCount">reference count </param>
 /// <param name="myData">original data, could be null</param>
 /// <returns></returns>
 private static Dictionary <DelayGraphVertex, long> GetOrMakeMyData(WaveFrontDictionary <Dictionary <DelayGraphVertex, long> > table,
                                                                    DelayGraphVertex v, int myRefCount, Dictionary <DelayGraphVertex, long> myData)
 {
     if (myData == null)
     {
         myData = new Dictionary <DelayGraphVertex, long>();
         table.Define(v, myRefCount, myData);
     }
     return(myData);
 }
コード例 #8
0
 internal PeriodTraverseState(
     DelayGraphVertex vertex,
     int delayReturned,
     Queue <DelayGraphEdge> unfinishedEdges,
     int maxAmongOutgoingEdges)
 {
     Vertex                = vertex;
     DelayReturned         = delayReturned;
     UnfinishedEdges       = unfinishedEdges;
     MaxAmongOutgoingEdges = maxAmongOutgoingEdges;
     StateWaitingOn        = null;
 }
コード例 #9
0
        private int TraverseForwardCalculatingPeriodRecursive(DelayGraphVertex startingVertex, out bool foundCycle,
                                                              HashSet <DelayGraphVertex> visiting,
                                                              Dictionary <DelayGraphVertex, int> computedDelays)
        {
            foundCycle = false;
            int maxAmongOutgoingEdges = 0;

            if (computedDelays.TryGetValue(startingVertex, out maxAmongOutgoingEdges))
            {
                return(maxAmongOutgoingEdges);
            }
            if (visiting.Contains(startingVertex)) // stop recursing if we hit a cycle
            {
                foundCycle = true;
                return(0);
            }

            // set state to visiting for starting vertex
            visiting.Add(startingVertex);
            IEnumerable <DelayGraphEdge> foundOutgoingEdges;

            if (Graph.TryGetOutEdges(startingVertex, out foundOutgoingEdges))
            {
                foreach (var outEdge in foundOutgoingEdges)
                {
                    int delayOnThisPath;
                    if (Registered(outEdge.Target)) // stop recursing when we hit a register
                    {
                        delayOnThisPath = outEdge.Delay;
                    }
                    else
                    {
                        bool anyCycle;
                        delayOnThisPath = outEdge.Delay + TraverseForwardCalculatingPeriodRecursive(
                            startingVertex: outEdge.Target,
                            foundCycle: out anyCycle,
                            visiting: visiting,
                            computedDelays: computedDelays);
                        if (anyCycle)
                        {
                            foundCycle = true;
                        }
                    }
                    maxAmongOutgoingEdges = Math.Max(maxAmongOutgoingEdges, delayOnThisPath);
                }
            }
            // finished visiting startingVertex - enter into ComputeDelays - which means visited is done
            // and remove it from visiting to be technically correct
            computedDelays[startingVertex] = maxAmongOutgoingEdges;
            visiting.Remove(startingVertex);
            return(maxAmongOutgoingEdges);
        }
コード例 #10
0
            /// <summary>
            /// decrement reference count, if 0, remove v from dictinary
            /// </summary>
            /// <param name="v">a vertex</param>
            /// <returns>the data being kept for v in WaveFrontDictionary</returns>
            internal T Use(DelayGraphVertex v)
            {
                Packet <T> packet;

                if (TryGetValue(v, out packet))
                {
                    var data = packet.Data;
                    packet.RefCount--;
                    if (packet.RefCount == 0)
                    {
                        Remove(v);
                    }
                    return(data);
                }
                return(default(T));
            }
コード例 #11
0
 /// <summary>
 /// return a topologically sorted (according to non-feedback edges only) list of vertices
 /// </summary>
 /// <param name="v">a vertex</param>
 /// <param name="sorted">linked list of sorted list of vertices</param>
 /// <param name="visited">to keep track of vertices that have been visited previously</param>
 /// <param name="graph">the delay graph</param>
 /// <returns>return true iff v is processed as unvisited </returns>
 private static bool TopoRecursive(DelayGraphVertex v, LinkedList <DelayGraphVertex> sorted, HashSet <DelayGraphVertex> visited, DelayGraph graph)
 {
     // add v to visited first, and if it is already visited, then bail
     if (visited.Add(v))
     {
         var outEdges = graph.GetForwardOutEdges(v);
         foreach (var e in outEdges)
         {
             TopoRecursive(e.Target, sorted, visited, graph);
         }
         // all fanout have been visited and added to sorted list - add v to start of sorted list
         sorted.AddFirst(v);
         return(true);
     }
     return(false);
 }
コード例 #12
0
 private void RetimeRegister(DelayGraphVertex v)
 {
     if (v.IsInputTerminal)
     {
         // move v's register to incoming edges
         foreach (var e in Graph.GetForwardInEdges(v))
         {
             RegisteredTerminals.Add(e.Source);
         }
     }
     else
     {
         // move v's register to outgoing edges
         foreach (var e in Graph.GetForwardOutEdges(v))
         {
             RegisteredTerminals.Add(e.Source);
         }
     }
     RegisteredTerminals.Remove(v);
 }
コード例 #13
0
        private static Dictionary <String, DelayGraphVertex> RecreateVertices(XElement graph, String nmsp, DelayGraph delayGraph)
        {
            var nodeIdToVertexMap = new Dictionary <String, DelayGraphVertex>();
            var vertexType        = typeof(DelayGraphVertex);

            // todo: update this map if new properties are added...or use "CreatePropertyTypeMap" below
            var propertyToTypeMap = new Dictionary <String, Type>()
            {
                { "VertexId", typeof(int) },
                { "NodeType", typeof(int) },
                { "NodeUniqueId", typeof(int) },
                { "ThroughputCostIfRegistered", typeof(long) },
                { "LatencyCostIfRegistered", typeof(long) },
                { "RegisterCostIfRegistered", typeof(long) },
                { "IsRegistered", typeof(bool) },
                { "IsInputTerminal", typeof(bool) },
                { "IsOutputTerminal", typeof(bool) },
                { "DisallowRegister", typeof(bool) }
            };

            // get the nodes
            foreach (var node in graph.Elements(nmsp + "node"))
            {
                // create new vertex
                var vertex = new DelayGraphVertex();
                var id     = (string)node.Attribute("id");
                nodeIdToVertexMap.Add(id, vertex);

                // populate the fields of the node
                foreach (var data in node.Elements())
                {
                    var     key      = (string)data.Attribute("key");
                    dynamic contents = Convert.ChangeType(data.Value, propertyToTypeMap[key], CultureInfo.InvariantCulture);
                    vertexType.GetProperty(key).SetValue(vertex, contents);
                }

                // add the node to the graph
                delayGraph.AddVertex(vertex);
            }
            return(nodeIdToVertexMap);
        }
コード例 #14
0
 /// <summary>
 /// return true iff there is at least one forward combinational path from v to target (ie, a path consisting of forward edges and no registered vertices along the way)
 /// </summary>
 /// <param name="v">the source vertex</param>
 /// <param name="target">the target vertex</param>
 /// <param name="visited">a cache for visited vertices</param>
 /// <returns>true iff there is a combinational forward path</returns>
 private bool FindForwardPath(DelayGraphVertex v, DelayGraphVertex target, HashSet <DelayGraphVertex> visited)
 {
     if (v == target)
     {
         return(true);
     }
     if (!visited.Add(v))
     {
         // previously visited
         return(false);
     }
     foreach (var e in Graph.GetForwardOutEdges(v))
     {
         if (Registered(e.Target))
         {
             continue;
         }
         if (FindForwardPath(e.Target, target, visited))
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #15
0
        private int TraverseForwardCalculatingPeriodIterative(
            DelayGraphVertex startingVertex,
            Dictionary <DelayGraphVertex, int> computedDelays,
            out bool foundCycle)
        {
            Stack <DelayGraphVertex> stack = new Stack <DelayGraphVertex>();
            var visited = new Dictionary <DelayGraphVertex, VisitState>();

            stack.Push(startingVertex);
            visited[startingVertex] = VisitState.Queued;
            foundCycle = false;

            while (stack.Any())
            {
                DelayGraphVertex currentVertex = stack.Peek();
                var visitStatus = visited[currentVertex];   // it is an error if currentVertex is not found in visited dictionary

                if (visitStatus == VisitState.Queued)
                {
                    // first time processing currentVertex - queue all outgoing edges
                    visited[currentVertex] = VisitState.Visiting;
                    IEnumerable <DelayGraphEdge> foundOutgoingEdges;
                    if (Graph.TryGetOutEdges(currentVertex, out foundOutgoingEdges))
                    {
                        var todo = foundOutgoingEdges.Where(e => !Registered(e.Target)).Select(e => e.Target);
                        todo.Reverse();
                        foreach (var next in todo)
                        {
                            VisitState status;
                            if (!visited.TryGetValue(next, out status))
                            {
                                visited[next] = VisitState.Queued;
                                stack.Push(next);
                            }
                            else if (status == VisitState.Queued)
                            {
                                // next has been previously queued - have to push it again so this is processed before parent's second visit
                                stack.Push(next);
                            }
                            else if (status == VisitState.Visiting)
                            {
                                // found a cycle
                                foundCycle           = true;
                                computedDelays[next] = 0;
                            }
                            // ok if status is Visited - no need to re-schedule next
                        }
                    }
                }
                else if (visitStatus == VisitState.Visiting)
                {
                    // second visit - all fanout have been processed already
                    int maxDelay = 0;
                    IEnumerable <DelayGraphEdge> foundOutgoingEdges;
                    if (Graph.TryGetOutEdges(currentVertex, out foundOutgoingEdges))
                    {
                        foreach (var edge in foundOutgoingEdges)
                        {
                            var next      = edge.Target;
                            int nextDelay = 0;
                            if (!Registered(next))
                            {
                                if (!computedDelays.TryGetValue(next, out nextDelay))
                                {
                                    throw new Exception("Cannot find Key: next should have been processed and found in ComputeDelays");
                                }
                            }
                            maxDelay = Math.Max(maxDelay, edge.Delay + nextDelay);
                        }
                    }
                    computedDelays[currentVertex] = maxDelay;
                    visited[currentVertex]        = VisitState.Visited;
                    stack.Pop();
                }
                else
                {
                    // visited - due to reconvergence - just pop it
                    stack.Pop();
                }
            }
            return(computedDelays[startingVertex]);
        }
コード例 #16
0
        private int TraverseForwardCalculatingPeriodIterative2(
            DelayGraphVertex startingVertex, out bool foundCycle)
        {
            Stack <PeriodTraverseState> stack = new Stack <PeriodTraverseState>();

            stack.Push(new PeriodTraverseState(startingVertex));

            PeriodTraverseState currentState = null;

            foundCycle = false;
            while (stack.Any())
            {
                currentState = stack.Peek();

                int alreadyComputedDelay = 0;
                if (ComputedDelays.TryGetValue(currentState.Vertex, out alreadyComputedDelay)) // put in for reconvergent paths
                {
                    currentState.DelayReturned = alreadyComputedDelay;
                    stack.Pop();
                    continue;
                }
                if (currentState.StateWaitingOn == null)        // this state is used here just to tell if we are coming along here b/c we need to attend to unfinished business where we might have already set 'visited'
                {
                    if (Visiting.Contains(currentState.Vertex)) // stop recursing if we're going along a loop, but still add up the delays of the loop
                    {
                        currentState.DelayReturned = 0;
                        foundCycle = true;
                        stack.Pop();
                        continue;
                    }
                    Visiting.Add(currentState.Vertex);
                }
                if (currentState.UnfinishedEdges == null)
                {
                    IEnumerable <DelayGraphEdge> foundOutgoingEdges;
                    if (Graph.TryGetOutEdges(currentState.Vertex, out foundOutgoingEdges))
                    {
                        currentState.UnfinishedEdges = new Queue <DelayGraphEdge>(foundOutgoingEdges);
                    }
                }
                bool done = true;
                while (currentState.UnfinishedEdges != null && currentState.UnfinishedEdges.Any())
                {
                    var outEdge = currentState.UnfinishedEdges.Peek();
                    int delayOnThisPath;
                    if (Registered(outEdge.Target)) // stop recursing when we hit a register
                    {
                        delayOnThisPath = outEdge.Delay;
                    }
                    else if (Visiting.Contains(outEdge.Target))
                    {
                        // found a cycle
                        foundCycle      = true;
                        delayOnThisPath = outEdge.Delay;
                    }
                    else
                    {
                        if (currentState.StateWaitingOn == null)
                        {
                            currentState.StateWaitingOn = new PeriodTraverseState(outEdge.Target);
                            stack.Push(currentState.StateWaitingOn);
                            done = false; // need to process what we just pushed
                            break;
                        }
                        else
                        {
                            delayOnThisPath             = outEdge.Delay + currentState.StateWaitingOn.DelayReturned;
                            currentState.StateWaitingOn = null;
                        }
                    }
                    currentState.UnfinishedEdges.Dequeue();
                    currentState.MaxAmongOutgoingEdges = Math.Max(currentState.MaxAmongOutgoingEdges, delayOnThisPath);
                }
                if (done)
                {
                    ComputedDelays[currentState.Vertex] = currentState.MaxAmongOutgoingEdges;
                    currentState.DelayReturned          = currentState.MaxAmongOutgoingEdges;
                    Visiting.Remove(currentState.Vertex);
                    stack.Pop();
                }
            }
            return(currentState.DelayReturned);
        }
コード例 #17
0
 internal PeriodTraverseState(
     DelayGraphVertex vertex)
     : this(vertex, 0, null, 0)
 {
 }
コード例 #18
0
 private bool Registered(DelayGraphVertex v)
 {
     return(v.IsRegistered || RegisteredTerminals.Contains(v));
 }