/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package datapath.graph; import datapath.graph.display.Display; import datapath.graph.display.DisplayEdge.Color; import datapath.graph.display.DisplayEdge.Type; import datapath.graph.display.DisplayFactory; import datapath.graph.operations.Operation; import datapath.graph.operations.ParentInput; import datapath.graph.operations.ParentOutput; import datapath.graph.operations.Predicate; import datapath.graph.operations.UnaryOperation; import java.util.HashSet; import java.util.Set; /** * * @author jh */ public class Graph { private Set<Operation> operations; private Set<Graph> innerLoops; private static int lastId; private int id; private int level; public Graph() { this(-1); } public Graph(int level) { operations = new HashSet<Operation>(); innerLoops = new HashSet<Graph>(); id = lastId++; this.level = level; } public void addOperation(Operation op) { operations.add(op); } public Set<Operation> getOperations() { return operations; } public int getId() { return id; } public Set<ParentInput> getInput() { HashSet<ParentInput> input = new HashSet<ParentInput>(); for (Operation op : operations) { if (op instanceof ParentInput) { input.add((ParentInput) op); } } return input; } public Set<ParentOutput> getOutput() { HashSet<ParentOutput> output = new HashSet<ParentOutput>(); for (Operation op : operations) { if (op instanceof ParentOutput) { output.add((ParentOutput) op); } } return output; } public static boolean isBackEdge(Operation source, Operation target) { return source.getExecutionOrdinal() > target.getExecutionOrdinal(); } public static int getDistance(Operation source, Operation target) { return Math.abs(target.getSchedule() - source.getSchedule() - source.getDelay()); } public void displayAll(DisplayFactory factory, String stage) { for (Graph graph : innerLoops) { graph.displayAll(factory); } display(factory); } public void displayAll(DisplayFactory factory) { displayAll(factory, ""); } public void display(DisplayFactory factory, String stage) { Display disp = factory.display("Datapath Graph " + this.toString()); // display.newGraph(context, false); for (Operation op : operations) { disp.addNode(factory.displayNode(op)); } for (Operation op : operations) { if(op.getUse().size() == 0) { System.out.println("warning: op has no use "+op); } for (Operation target : op.getUse()) { if (isBackEdge(op, target)) { disp.addEdge(factory.displayEdge(op, target, Type.Solid, Color.RED)); } else { disp.addEdge(factory.displayEdge(op, target, Type.Solid, Color.BLACK)); } } for (Predicate pred : op.getPredicates()) { disp.addEdge(factory.displayEdge(pred, op, Type.Dashed, pred.getEdgeColor())); } } disp.display(stage); } public void display(DisplayFactory factory, ParentOutput output) { Display disp = factory.display("Datapath Output " + output.getDisplayLabel()); HashSet<Operation> ops = new HashSet<Operation>(); String name = output.getName(); ops.add(output); ops.addAll(output.dependsOnOperations(true)); boolean changed; do { changed = false; for (Operation op : ops.toArray(new Operation[0])) { if(!op.getDebugMessage().equals("") && !op.getDebugMessage().equals(name)) continue; changed |= ops.addAll(op.dependsOnOperations(true)); } } while (changed); for(Operation op : ops) { disp.addNode(factory.displayNode(op)); } for (Operation op : ops) { for (Operation target : op.getUse()) { if(!ops.contains(target)) continue; if (isBackEdge(op, target)) { disp.addEdge(factory.displayEdge(op, target, Type.Solid, Color.RED)); } else { disp.addEdge(factory.displayEdge(op, target, Type.Solid, Color.BLACK)); } } // for (Predicate pred : op.getPredicates()) { // disp.addEdge(factory.displayEdge(pred, op, Type.Dashed, // pred.getEdgeColor())); // } } disp.display(output.getName()); } public void display(DisplayFactory factory) { display(factory, ""); } public void remove(Operation op) { assert operations.contains(op); operations.remove(op); } public void addInnerLoop(Graph g) { innerLoops.add(g); } public Set<Graph> getInnerLoops() { return innerLoops; } public int numOfOperation(boolean includeInnerLoops, Class<? extends Operation> type) { int numOperation = 0; if (includeInnerLoops) { for (Graph innerLoop : innerLoops) { numOperation += innerLoop.numOfOperation(includeInnerLoops, type); } } for (Operation op : operations) { if (op.getClass() == type) { numOperation++; } } return numOperation; } @Override public String toString() { return String.format("Graph%d level:%d", id, level); } public boolean isTopLevel() { return level == 0; } public int getLatestSchedule() { int lastOp = 0; for (Operation op : operations) { lastOp = Math.max(lastOp, op.getSchedule()); } return lastOp; } /** * Inserts an operation (node) between two other. * @param toInsert Operation to insert. Must be a UnaryOperation (one input, one output). * @param pred After which node toInsert should be placed. * @param succ Before which node toInsert should be place. */ public void insertNode(UnaryOperation toInsert, Operation pred, Operation succ) { //toInsert.addUse(succ); toInsert.setData(pred); addOperation(toInsert); succ.replace(pred, toInsert); //pred.removeUse(succ); //pred.addUse(toInsert); } }