/* * 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"); }
/* * File reader code currently works by using fread. * * The File* is declared outside any function / method. * * This code follows the model in the library of stalling (not pushing) * at end of file (detected by fread returning 0). * */ private static void genFileReaderWork( SIRFileReader filter, Tape outputTape, int selfID, CodegenPrintWriter p) { if (KjcOptions.asciifileio) { System.err.println("Error: -asciifileio not supported in cluster backend."); System.err.println("Exiting..."); System.exit(1); } String theType = "" + filter.getOutputType(); // dispatch to special routine for bit type if (theType.equals("bit")) { genFileReaderWorkBit(filter, outputTape, selfID, p); return; } // get source and destination ids of outgoing tape Tape out = RegisterStreams.getFilterOutStream(filter); int s = out.getSource(); int d = out.getDest(); // template code to generate, using symbolic free vars above. StringBuilder sb = new StringBuilder(); sb.append("\n int __index;\n"); sb.append(" for (__index=0; __index < ____n; __index++) {\n"); if (KjcOptions.compressed) { sb.append(" unsigned char __temp = 0;\n"); sb.append(" FileReader_read(__file_descr__"); sb.append(selfID); sb.append(", &__temp, 1);\n"); sb.append(" PUSH(__temp);\n"); sb.append(" unsigned int __frame_size = __temp;\n"); sb.append(" FileReader_read(__file_descr__"); sb.append(selfID); sb.append(", &__temp, 1);\n"); sb.append(" PUSH(__temp);\n"); sb.append(" __frame_size <<= 8;\n"); sb.append(" __frame_size += __temp;\n"); sb.append(" FileReader_read(__file_descr__"); sb.append(selfID); sb.append(", &__temp, 1);\n"); sb.append(" PUSH(__temp);\n"); sb.append(" __frame_size <<= 8;\n"); sb.append(" __frame_size += __temp;\n"); sb.append(" FileReader_read(__file_descr__"); sb.append(selfID); sb.append(", &__temp, 1);\n"); sb.append(" PUSH(__temp);\n"); sb.append(" __frame_size <<= 8;\n"); sb.append(" __frame_size += __temp;\n"); // the frame size includes the four bytes used to state the frame size sb.append(" FileReader_read(__file_descr__"); sb.append(selfID); sb.append(", (void *)(BUFFER + HEAD), __frame_size - 4);\n"); sb.append(" HEAD += __frame_size - 4;\n"); } else { sb.append(" PUSH(FileReader_read<"); sb.append(theType); sb.append(">(__file_descr__"); sb.append(selfID); sb.append("));\n"); } sb.append(" }\n"); String template = sb.toString(); /* " #ifdef FUSED" + "\n" + " #ifdef NOMOD" + "\n" + " // read directly into buffer" + "\n" + " if (fread(&(BUFFER[HEAD]), sizeof(BUFFER[HEAD]), ____n, FILEREADER)) {" + "\n" + " HEAD+=____n;" + "\n" + " }" + "\n" + " #else" + "\n" + " // wraparound buffer, might have to read in two pieces (but never" + "\n" + " // more, since we would overwrote what we already wrote on this call)" + "\n" + " if (HEAD+____n <= __BUF_SIZE_MASK) {" + "\n" + " // no overflow" + "\n" + " if (fread(&(BUFFER[HEAD]), sizeof(BUFFER[HEAD]), ____n, FILEREADER)) {" + "\n" + " HEAD+=____n;" + "\n" + " }" + "\n" + " } else {" + "\n" + " // overflow, need two pieces" + "\n" + " int piece1 = __BUF_SIZE_MASK - HEAD;" + "\n" + " int piece2 = ____n - piece1;" + "\n" + " if (fread(&(BUFFER[HEAD]), sizeof(BUFFER[HEAD]), piece1, FILEREADER)) {" + "\n" + " if (fread(&(BUFFER[0]), sizeof(BUFFER[HEAD]), piece2, FILEREADER)) {" + "\n" + " HEAD+=____n;" + "\n" + " HEAD&=__BUF_SIZE_MASK;" + "\n" + " }" + "\n" + " }" + "\n" + " }" + "\n" + " #endif" + "\n" + " #else" + "\n" + " // read as a block" + "\n" + " TYPE __buffer[____n];" + "\n" + " int __index;" + "\n" + " if (fread(__buffer, sizeof(__buffer[0]), ____n, FILEREADER)) {" + "\n" + " for (__index=0; __index < ____n; __index++) {" + "\n" + " // should move push out of loop, but not clear if mult-push implemented yet" + "\n" + " PUSH(__buffer[__index]);" + "\n" + " }" + "\n" + " }" + "\n" + " #endif"; */ // set values of free variables String TYPE = theType; String FILEREADER = fpName(filter); String FUSED = "__FUSED_" + s + "_" + d; String NOMOD = "__NOMOD_" + s + "_" + d; String BUFFER = "BUFFER_" + s + "_" + d; String HEAD = "HEAD_" + s + "_" + d; String BUF_SIZE_MASK = "__BUF_SIZE_MASK_" + s + "_" + d; String PUSH = outputTape.getPushName(); // replace templates with correct values template = Utils.replaceAll(template, "TYPE", TYPE); template = Utils.replaceAll(template, "FILEREADER", FILEREADER); template = Utils.replaceAll(template, "FUSED", FUSED); template = Utils.replaceAll(template, "NOMOD", NOMOD); template = Utils.replaceAll(template, "BUFFER", BUFFER); template = Utils.replaceAll(template, "HEAD", HEAD); template = Utils.replaceAll(template, "BUF_SIZE_MASK", BUF_SIZE_MASK); template = Utils.replaceAll(template, "PUSH", PUSH); // output code p.println(template); }