/** * generate the switch code for 1 data item given the list of destinations we do not want to * duplicate items until neccessary, so we have to keep track of all the routes and then generate * the switch code this way we can route multiple dests per route instruction */ protected void generateSwitchCode(FlatNode fire, List<FlatNode> dests) { assert !(layout.getIdentities().contains(fire)); // should only have one previous HashMap<ComputeNode, ComputeNode> prev = new HashMap<ComputeNode, ComputeNode>(); HashMap<ComputeNode, HashSet> next = new HashMap<ComputeNode, HashSet>(); ListIterator<FlatNode> destsIt = dests.listIterator(); while (destsIt.hasNext()) { FlatNode dest = destsIt.next(); assert dest != null; assert !(layout.getIdentities().contains(dest)); // System.out.println(" Dest: " + dest + " " + layout.getTile(dest)); ComputeNode[] hops = layout .router .getRoute(ssg, layout.getComputeNode(fire), layout.getComputeNode(dest)) .toArray(new ComputeNode[0]); assert hops.length > 1 : "Error: Bad Layout (could not find route from " + fire.toString() + " -> " + dest.toString(); // for (int i = 0; i < hops.length; i++) // System.out.println(" " + hops[i]); // add to fire's next if (!next.containsKey(layout.getComputeNode(fire))) next.put(layout.getComputeNode(fire), new HashSet()); next.get(layout.getComputeNode(fire)).add(hops[1]); // add to all other previous, next for (int i = 1; i < hops.length - 1; i++) { if (prev.containsKey(hops[i])) if (prev.get(hops[i]) != hops[i - 1]) Utils.fail("More than one previous tile for a single data item"); prev.put(hops[i], hops[i - 1]); if (!next.containsKey(hops[i])) next.put(hops[i], new HashSet()); next.get(hops[i]).add(hops[i + 1]); } // add the last step, plus the dest to the dest map if (prev.containsKey(hops[hops.length - 1])) if (prev.get(hops[hops.length - 1]) != hops[hops.length - 2]) Utils.fail("More than one previous tile for a single data item (2)"); prev.put(hops[hops.length - 1], hops[hops.length - 2]); if (!next.containsKey(hops[hops.length - 1])) next.put(hops[hops.length - 1], new HashSet()); next.get(hops[hops.length - 1]).add(hops[hops.length - 1]); } // create the appropriate amount of routing instructions int elements = Util.getTypeSize(CommonUtils.getOutputType(fire)); for (int i = 0; i < elements; i++) asm(layout.getComputeNode(fire), prev, next); }
/** consume the data and return the number of items produced * */ protected int fireMe( FlatNode fire, SimulationCounter counters, HashMap<FlatNode, Integer> executionCounts) { if (fire.contents instanceof SIRFilter) { // decrement the schedule execution counter decrementExecutionCounts(fire, executionCounts, counters); // consume the date from the buffer counters.decrementBufferCount(fire, consumedItems(fire, counters, executionCounts)); // for a steady state execution return the normal push int ret = ((SIRFilter) fire.contents).getPushInt(); // if the filter is a two stage, and it has not fired // return the initPush() unless the initWork does nothing if (initSimulation && !counters.hasFired(fire) && fire.contents instanceof SIRTwoStageFilter) ret = ((SIRTwoStageFilter) fire.contents).getInitPushInt(); else if (!initSimulation && KjcOptions.ratematch) { // we are ratematching so produce all the data on the one firing. ret *= ssg.getMult(fire, false); } // now this node has fired counters.setFired(fire); return ret; } else if (fire.contents instanceof SIRJoiner) { return fireJoiner(fire, counters, executionCounts); } Utils.fail("Trying to fire a non-filter or joiner"); return -1; }
/** Constructs a joiner with given parent, type and n number of inputs. */ public static SIRJoiner create(SIRContainer parent, SIRJoinType type, int n) { if (type == SIRJoinType.COMBINE) { // fill weights with 1 return new SIRJoiner(parent, type, Utils.initLiteralArray(n, 1), true); } else if (type == SIRJoinType.NULL) { // for null type, fill with zero weights return new SIRJoiner(parent, type, Utils.initLiteralArray(n, 0), true); } else if (type == SIRJoinType.WEIGHTED_RR) { // if making a weighted round robin, should use other constructor Utils.fail("Need to specify weights for weighted round robin"); return null; } else if (type == SIRJoinType.ROUND_ROBIN) { // if making a round robin, should use other constructor Utils.fail("Need to specify weight for uniform round robin"); return null; } else { Utils.fail("Unreckognized joiner type."); return null; } }
/** Give that a node has just fired, update the simulation state * */ protected void decrementExecutionCounts( FlatNode fire, HashMap<FlatNode, Integer> executionCounts, SimulationCounter counters) { // decrement one from the execution count int oldVal = executionCounts.get(fire).intValue(); if (oldVal - 1 < 0) Utils.fail("Executed too much"); // if we are ratematching the node only fires once but only do this // for filters if (!initSimulation && KjcOptions.ratematch && fire.contents instanceof SIRFilter) { executionCounts.put(fire, new Integer(0)); } else executionCounts.put(fire, new Integer(oldVal - 1)); }
public static SIRJoiner create(SIRContainer parent, SIRJoinType type, JExpression[] weights) { if (type == SIRJoinType.NULL) { return new SIRJoiner(parent, type, Utils.initLiteralArray(weights.length, 0), true); } else if (type == SIRJoinType.WEIGHTED_RR) { return createWeightedRR(parent, weights); } else if (type == SIRJoinType.ROUND_ROBIN) { JExpression weight = (weights.length > 0 ? weights[0] : new JIntLiteral(1)); return createUniformRR(parent, weight); } else { Utils.fail("Unrecognized joiner type."); return null; } }
protected SIRStream doCut( LinkedList<PartitionRecord> partitions, PartitionRecord curPartition, int x1, int x2, int xPivot, int tileLimit, int tPivot, SIRStream str) { // there's a division at this <yPivot>. We'll // return result of a horizontal cut. int[] arr = {1 + (xPivot - x1), x2 - xPivot}; PartitionGroup pg = PartitionGroup.createFromArray(arr); SIRContainer result; // might have either pipeline or feedback loop at this point... if (str instanceof SIRPipeline) { result = RefactorPipeline.addHierarchicalChildren((SIRPipeline) str, pg); } else if (str instanceof SIRFeedbackLoop) { // if we have a feedbackloop, then factored is // just the original, since it will have only // two children result = (SIRContainer) str; } else { result = null; Utils.fail("Unrecognized stream type: " + str); } // recurse up and down SIRStream top = traceback(partitions, curPartition, x1, xPivot, tPivot, result.get(0)); // mark that we have a partition here curPartition = new PartitionRecord(); partitions.add(curPartition); SIRStream bot = traceback(partitions, curPartition, xPivot + 1, x2, tileLimit - tPivot, result.get(1)); // mutate ourselves if we haven't been mutated yet result.set(0, top); result.set(1, bot); // all done return result; }
/** Throws an exception (NOT SUPPORTED YET) */ public JExpression analyse(CExpressionContext context) throws PositionedError { at.dms.util.Utils.fail("Analysis of SIR nodes not supported yet."); return this; }
/* * Generates JVM bytecode to evaluate this expression. NOT SUPPORTED YET. * * @param code the bytecode sequence * @param discardValue discard the result of the evaluation ? */ public void genCode(CodeSequence code, boolean discardValue) { at.dms.util.Utils.fail("Codegen of SIR nodes not supported yet."); }
/** Generates a sequence of bytescodes - NOT SUPPORTED YET. */ public void genCode(CodeSequence code) { at.dms.util.Utils.fail("Codegen of SIR nodes not supported yet."); }
/** Analyses the statement (semantically) - NOT SUPPORTED YET. */ public void analyse(CBodyContext context) throws PositionedError { at.dms.util.Utils.fail("Analysis of SIR nodes not supported yet."); }