DiGraph was being being confused with the DigGraph in firrtl. This led to pathological exceptions (#22)
No such method error on accessing a lazy val. InstanceGraph seemed also to be a duplicate of firrtl code --- IOPadSpec fails no two tests but these seem to be at least an ordinary error. And should be debugged separately
This commit is contained in:
committed by
Colin Schmidt
parent
5b5c8c82db
commit
16846b86fd
@@ -1,158 +0,0 @@
|
||||
package firrtl
|
||||
|
||||
import scala.collection.immutable.{HashSet, HashMap}
|
||||
import scala.collection.mutable
|
||||
import scala.collection.mutable.MultiMap
|
||||
|
||||
class MutableDiGraph[T](
|
||||
val edgeData: MultiMap[T,T] = new mutable.HashMap[T, mutable.Set[T]] with MultiMap[T, T]) {
|
||||
def contains(v: T) = edgeData.contains(v)
|
||||
def getVertices = edgeData.keys
|
||||
def getEdges(v: T) = edgeData(v)
|
||||
def addVertex(v: T): T = {
|
||||
edgeData.getOrElseUpdate(v,new mutable.HashSet[T])
|
||||
v
|
||||
}
|
||||
// Add v to keys to maintain invariant
|
||||
def addEdge(u: T, v: T) = {
|
||||
edgeData.getOrElseUpdate(v, new mutable.HashSet[T])
|
||||
edgeData.addBinding(u,v)
|
||||
}
|
||||
}
|
||||
|
||||
object DiGraph {
|
||||
def apply[T](mdg: MutableDiGraph[T]) = new DiGraph((mdg.edgeData mapValues { _.toSet }).toMap[T, Set[T]])
|
||||
def apply[T](edgeData: MultiMap[T,T]) = new DiGraph((edgeData mapValues { _.toSet }).toMap[T, Set[T]])
|
||||
}
|
||||
|
||||
class DiGraph[T] (val edges: Map[T, Set[T]]) {
|
||||
|
||||
def getVertices = edges.keys
|
||||
def getEdges(v: T) = edges.getOrElse(v, new HashSet[T])
|
||||
|
||||
// Graph must be acyclic for valid linearization
|
||||
def linearize(root: T) = {
|
||||
val order = new mutable.ArrayBuffer[T]
|
||||
val visited = new mutable.HashSet[T]
|
||||
def explore(v: T): Unit = {
|
||||
visited += v
|
||||
for (u <- getEdges(v)) {
|
||||
if (!visited.contains(u)) {
|
||||
explore(u)
|
||||
}
|
||||
}
|
||||
order.append(v)
|
||||
}
|
||||
explore(root)
|
||||
order.reverse.toList
|
||||
}
|
||||
|
||||
def doBFS(root: T) = {
|
||||
val prev = new mutable.HashMap[T,T]
|
||||
val queue = new mutable.Queue[T]
|
||||
queue.enqueue(root)
|
||||
while (!queue.isEmpty) {
|
||||
val u = queue.dequeue
|
||||
for (v <- getEdges(u)) {
|
||||
if (!prev.contains(v)) {
|
||||
prev(v) = u
|
||||
queue.enqueue(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
prev
|
||||
}
|
||||
|
||||
def reachabilityBFS(root: T) = doBFS(root).keys.toSet
|
||||
|
||||
def path(start: T, end: T) = {
|
||||
val nodePath = new mutable.ArrayBuffer[T]
|
||||
val prev = doBFS(start)
|
||||
nodePath += end
|
||||
while (nodePath.last != start) {
|
||||
nodePath += prev(nodePath.last)
|
||||
}
|
||||
nodePath.toList.reverse
|
||||
}
|
||||
|
||||
def findSCCs = {
|
||||
var counter: BigInt = 0
|
||||
val stack = new mutable.Stack[T]
|
||||
val onstack = new mutable.HashSet[T]
|
||||
val indices = new mutable.HashMap[T, BigInt]
|
||||
val lowlinks = new mutable.HashMap[T, BigInt]
|
||||
val sccs = new mutable.ArrayBuffer[List[T]]
|
||||
|
||||
def strongConnect(v: T): Unit = {
|
||||
indices(v) = counter
|
||||
lowlinks(v) = counter
|
||||
counter = counter + 1
|
||||
stack.push(v)
|
||||
onstack += v
|
||||
for (w <- getEdges(v)) {
|
||||
if (!indices.contains(w)) {
|
||||
strongConnect(w)
|
||||
lowlinks(v) = lowlinks(v).min(lowlinks(w))
|
||||
} else if (onstack.contains(w)) {
|
||||
lowlinks(v) = lowlinks(v).min(indices(w))
|
||||
}
|
||||
}
|
||||
if (lowlinks(v) == indices(v)) {
|
||||
val scc = new mutable.ArrayBuffer[T]
|
||||
do {
|
||||
val w = stack.pop
|
||||
onstack -= w
|
||||
scc += w
|
||||
}
|
||||
while (scc.last != v);
|
||||
sccs.append(scc.toList)
|
||||
}
|
||||
}
|
||||
|
||||
for (v <- getVertices) {
|
||||
strongConnect(v)
|
||||
}
|
||||
|
||||
sccs.toList
|
||||
}
|
||||
|
||||
def pathsInDAG(start: T): Map[T,List[List[T]]] = {
|
||||
// paths(v) holds the set of paths from start to v
|
||||
val paths = new mutable.HashMap[T,mutable.Set[List[T]]] with mutable.MultiMap[T,List[T]]
|
||||
val queue = new mutable.Queue[T]
|
||||
val visited = new mutable.HashSet[T]
|
||||
paths.addBinding(start,List(start))
|
||||
queue.enqueue(start)
|
||||
visited += start
|
||||
while (!queue.isEmpty) {
|
||||
val current = queue.dequeue
|
||||
for (v <- getEdges(current)) {
|
||||
if (!visited.contains(v)) {
|
||||
queue.enqueue(v)
|
||||
visited += v
|
||||
}
|
||||
for (p <- paths(current)) {
|
||||
paths.addBinding(v, p :+ v)
|
||||
}
|
||||
}
|
||||
}
|
||||
(paths map { case (k,v) => (k,v.toList) }).toMap
|
||||
}
|
||||
|
||||
def reverse = {
|
||||
val mdg = new MutableDiGraph[T]
|
||||
edges foreach { case (u,edges) => edges.foreach({ v => mdg.addEdge(v,u) }) }
|
||||
DiGraph(mdg)
|
||||
}
|
||||
|
||||
def simplify(vprime: Set[T]) = {
|
||||
val eprime = vprime.map( v => (v,reachabilityBFS(v) & vprime) ).toMap
|
||||
new DiGraph(eprime)
|
||||
}
|
||||
|
||||
def transformNodes[Q](f: (T) => Q): DiGraph[Q] = {
|
||||
val eprime = edges.map({ case (k,v) => (f(k),v.map(f(_))) })
|
||||
new DiGraph(eprime)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package firrtl.analyses
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
import firrtl._
|
||||
import firrtl.ir._
|
||||
import firrtl.Utils._
|
||||
import firrtl.Mappers._
|
||||
|
||||
class InstanceGraph(c: Circuit) {
|
||||
|
||||
private def collectInstances(insts: mutable.Set[WDefInstance])(s: Statement): Statement = s match {
|
||||
case i: WDefInstance =>
|
||||
insts += i
|
||||
i
|
||||
case _ =>
|
||||
s map collectInstances(insts)
|
||||
s
|
||||
}
|
||||
|
||||
val moduleMap = c.modules.map({m => (m.name,m) }).toMap
|
||||
val childInstances =
|
||||
new mutable.HashMap[String,mutable.Set[WDefInstance]]
|
||||
for (m <- c.modules) {
|
||||
childInstances(m.name) = new mutable.HashSet[WDefInstance]
|
||||
m map collectInstances(childInstances(m.name))
|
||||
}
|
||||
val instanceGraph = new MutableDiGraph[WDefInstance]
|
||||
val instanceQueue = new mutable.Queue[WDefInstance]
|
||||
val topInstance = WDefInstance(c.main,c.main) // top instance
|
||||
instanceQueue.enqueue(topInstance)
|
||||
while (!instanceQueue.isEmpty) {
|
||||
val current = instanceQueue.dequeue
|
||||
for (child <- childInstances(current.module)) {
|
||||
if (!instanceGraph.contains(child)) {
|
||||
instanceQueue.enqueue(child)
|
||||
}
|
||||
instanceGraph.addEdge(current,child)
|
||||
}
|
||||
}
|
||||
|
||||
val graph = DiGraph(instanceGraph)
|
||||
|
||||
lazy val fullHierarchy = graph.pathsInDAG(topInstance)
|
||||
|
||||
def findInstancesInHierarchy(module: String): List[List[WDefInstance]] = {
|
||||
val instances = graph.getVertices.filter(_.module == module).toList
|
||||
instances flatMap { i => fullHierarchy(i) }
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user