public void visitNode(FlatNode node) { System.out.println("Creating SliceNodes: " + node); OutputSliceNode output = new OutputSliceNode(); InputSliceNode input = new InputSliceNode(); FilterContent content; int mult = 1; if (node.isFilter()) { if (node.contents instanceof SIRFileWriter) { content = new FileOutputContent((SIRFileWriter) node.contents); } else if (node.contents instanceof SIRFileReader) { content = new FileInputContent((SIRFileReader) node.contents); } else content = new FilterContent(node.getFilter()); } else if (node.isSplitter()) { CType type = CommonUtils.getOutputType(node); SIRIdentity id = new SIRIdentity(type); RenameAll.renameAllFilters(id); content = new FilterContent(id); if (!node.isDuplicateSplitter()) mult = node.getTotalOutgoingWeights(); } else { // joiner CType type = CommonUtils.getOutputType(node); SIRIdentity id = new SIRIdentity(type); RenameAll.renameAllFilters(id); content = new FilterContent(id); mult = node.getTotalIncomingWeights(); } if (exeCounts[0].containsKey(node.contents)) content.setInitMult(mult * ((int[]) exeCounts[0].get(node.contents))[0]); else content.setInitMult(0); content.setSteadyMult(mult * ((int[]) exeCounts[1].get(node.contents))[0]); FilterSliceNode filterNode = new FilterSliceNode(content); if (node.isSplitter() || node.isJoiner()) generatedIds.add(filterNode); inputNodes.put(node.contents, input); outputNodes.put(node.contents, output); filterNodes.put(node.contents, filterNode); }
/** * 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); }
/* * When generating (no) code for init routine, also generate File* * and close() for file. */ private static void genFileReaderInit( SIRFileReader fr, CType return_type, String function_name, int selfID, List /*String*/ cleanupCode, CodegenPrintWriter p) { int id = NodeEnumerator.getSIROperatorId(fr); String theType = "" + fr.getOutputType(); // dispatch to special routine for bit type if (theType.equals("bit")) { p.print("FILE* " + fpName(fr) + ";"); p.newLine(); p.newLine(); } startParameterlessFunction(CommonUtils.CTypeToStringA(return_type, true), function_name, p); if (theType.equals("bit")) { p.print(fpName(fr) + " = fopen(\"" + fr.getFileName() + "\", \"r\");"); p.newLine(); p.print("assert (" + fpName(fr) + ");"); p.newLine(); } else { p.print("__file_descr__" + id + " = FileReader_open(\"" + fr.getFileName() + "\");"); p.newLine(); p.print("assert (__file_descr__" + id + ");"); p.newLine(); } endFunction(p); String closeName = ClusterUtils.getWorkName(fr, selfID) + "__close"; startParameterlessFunction("void", closeName, p); if (theType.equals("bit")) { p.println("fclose(" + fpName(fr) + ");"); } else { p.println("FileReader_close(__file_descr__" + id + ");"); } endFunction(p); cleanupCode.add(closeName + "();\n"); }
/** * Create code for the init function of built-in filter * * @param filter The filter for which we are creating init function * @param return_type The return type for the init function * @param function_name The name for the init function * @param selfID The unique identifier that FlatIRToCluster has assigned to the function * @param cleanupCode A list of statements run at "clean-up" time to which this code can add * requests to close files, etc. * @param p The printer for outputting code for the function */ static void predefinedFilterInit( SIRPredefinedFilter filter, CType return_type, String function_name, int selfID, List /*String*/ cleanupCode, CodegenPrintWriter p) { // No wrapper code around init since may need to create defns at file // level. We assume that the code generator will continue to // generate code for init before code for work, so scope of // any file-level code will include the work function. // p.println("// predefinedFilterInit " + filter.getName() // + " " + filter.getInputType().toString() + " -> " // + filter.getOutputType().toString()); if (filter instanceof SIRFileReader) { if (!(KjcOptions.mencoder || KjcOptions.blender)) { genFileReaderInit( (SIRFileReader) filter, return_type, function_name, selfID, cleanupCode, p); } } else if (filter instanceof SIRFileWriter) { if (!(KjcOptions.mencoder || KjcOptions.blender)) { genFileWriterInit( (SIRFileWriter) filter, return_type, function_name, selfID, cleanupCode, p); } } else if (filter instanceof SIRIdentity || filter instanceof SIRDummySink || filter instanceof SIRDummySource) { // all of these have filters produce empty init functions. startParameterlessFunction(CommonUtils.CTypeToStringA(return_type, true), function_name, p); endFunction(p); } else if (filter instanceof SIRDummySink) { // TODO: get right exception for unimplemented. throw new Error("Unsupported predefined filter " + filter.getName()); } else if (filter instanceof SIRDummySource) { throw new Error("Unsupported predefined filter " + filter.getName()); } else { // TODO: get right unchecked exception for unextended code... throw new Error("Unknown predefined filter " + filter.getName()); } }
/* * When generating (no) code for init routine, also generate File* * and close() for file. */ private static void genFileWriterInit( SIRFileWriter fw, CType return_type, String function_name, int selfID, List /*String*/ cleanupCode, CodegenPrintWriter p) { int id = NodeEnumerator.getSIROperatorId(fw); String theType = "" + fw.getInputType(); String bits_to_go = bitsToGoName(fw); String the_bits = theBitsName(fw); if (theType.equals("bit")) { p.println("FILE* " + fpName(fw) + ";"); } if (theType.equals("bit")) { // the bit type is special since you can not just read or // write a bit. It requires buffering in some larger // integer type. p.println(bits_type + " " + the_bits + " = 0;"); p.println("int " + bits_to_go + " = 8 * sizeof(" + the_bits + ");"); } p.newLine(); startParameterlessFunction(CommonUtils.CTypeToStringA(return_type, true), function_name, p); if (theType.equals("bit")) { p.println(fpName(fw) + " = fopen(\"" + fw.getFileName() + "\", \"w\");"); p.println("assert (" + fpName(fw) + ");"); } else { p.print("__file_descr__" + id + " = FileWriter_open(\"" + fw.getFileName() + "\");"); p.newLine(); p.print("assert (__file_descr__" + id + ");"); p.newLine(); } endFunction(p); String closeName = ClusterUtils.getWorkName(fw, selfID) + "__close"; startParameterlessFunction("void", closeName, p); if (theType.equals("bit")) { p.println("if (" + bits_to_go + " != 8 * sizeof(" + the_bits + ")) {"); p.indent(); p.println(the_bits + " = " + the_bits + " << " + bits_to_go + ";"); p.println( "fwrite(" + "&" + the_bits + ", " + "sizeof(" + the_bits + "), " + "1, " + fpName(fw) + ");"); p.outdent(); p.println("}"); } if (theType.equals("bit")) { p.println("fclose(" + fpName(fw) + ");"); } else { p.println("FileWriter_flush(__file_descr__" + id + ");"); p.println("FileWriter_close(__file_descr__" + id + ");"); } endFunction(p); cleanupCode.add(closeName + "();\n"); }