p.print("  for (int n = 0; n < (__max_iteration / __MULT); n++) {\n");
p.print("  for (int n = 0; n < (__max_iteration " + (mult == 1? "" : " / __MULT") +  " ); n++) {\n");
    public static void generateFusionFile(DiscoverSchedule d_sched) {            int threadNumber = NodeEnumerator.getNumberOfNodes();            CodegenPrintWriter p = null;        try {            p = new CodegenPrintWriter(new FileWriter("fusion.cpp"));        } catch (IOException e) {            e.printStackTrace();            System.exit(1);        }            p.print("#include <pthread.h>\n");        p.print("#include <unistd.h>\n");        //p.print("#include <signal.h>\n");        p.print("#include <string.h>\n");        p.print("#include <stdlib.h>\n");        p.print("#include <stdio.h>\n");        p.newLine();        p.print("#include <netsocket.h>\n");        p.print("#include <node_server.h>\n");        p.print("#include <init_instance.h>\n");        p.print("#include <master_server.h>\n");        p.print("#include <save_state.h>\n");        p.print("#include <save_manager.h>\n");        p.print("#include <delete_chkpts.h>\n");        p.print("#include <object_write_buffer.h>\n");        p.print("#include <read_setup.h>\n");        p.print("#include <ccp.h>\n");        //p.print("#include <read_setup.h>\n");        p.print("#include <timer.h>\n");        p.print("#include \"fusion.h\"\n");        p.println("#include \"structs.h\"");        if (KjcOptions.countops) {            p.println("#include \"profiler.h\"");        }        p.newLine();            p.print("int __max_iteration;\n");        p.print("int __timer_enabled = 0;\n");        p.print("int __frequency_of_chkpts;\n");        p.print("volatile int __vol;\n");        p.print("proc_timer tt(\"total runtime\");\n");        p.newLine();        // declare profiling timers        if (KjcOptions.profile) {            String ident = InsertTimers.getIdentifier();            p.println("proc_timer " + ident + "[" + InsertTimers.getNumTimers() + "] = {");            p.indent();            for (int i=0; i<InsertTimers.getNumTimers(); i++) {                 String name = InsertTimers.getTimerName(i);                p.print("proc_timer(\"" + name + "\")");                if (i!=InsertTimers.getNumTimers()-1) {                     p.print(", ");                }                p.println("// " + ident + "[" + i + "]");            }            p.outdent();            p.println("};");        }        p.newLine();        for (int i = 0; i < threadNumber; i++) {            FlatNode node = NodeEnumerator.getFlatNode(i);            SIROperator oper = (SIROperator)node.contents;            Vector out = RegisterStreams.getNodeOutStreams(oper);                    for (int s = 0; s < out.size(); s++) {                NetStream stream = (NetStream)out.elementAt(s);                int src = stream.getSource();                int dst = stream.getDest();                if (FixedBufferTape.isFixedBuffer(src, dst)) {                    String type = ClusterUtils.CTypeToString(stream.getType());                    p.print(type + " BUFFER_" + src + "_" + dst                            + "[__BUF_SIZE_MASK_" + src + "_" + dst                            + " + 1];\n");                    p.print("int HEAD_" + src + "_" + dst + " = 0;\n");                    p.print("int TAIL_" + src + "_" + dst + " = 0;\n");                    p.newLine();                }            }        }        for (SIRJoiner j : ClusterCode.feedbackJoineersNeedingPrep) {            p.println("extern void __feedbackjoiner_"+ NodeEnumerator.getSIROperatorId(j) +"_prep();");        }        for (int i = 0; i < threadNumber; i++) {            FlatNode node = NodeEnumerator.getFlatNode(i);            int id = NodeEnumerator.getSIROperatorId(node.contents);            //if (!ClusterFusion.isEliminated(tmp)) {                   //p.print("extern void __declare_sockets_"+i+"();\n");            //p.print("extern void __init_sockets_"+i+"(void (*)());\n");            if (node.contents instanceof SIRFilter) {                //p.print("extern void __init_pop_buf__"+i+"();\n");                //p.print("extern void __update_pop_buf__"+i+"();\n");                p.print("extern void "+((SIRFilter)node.contents).getInit().getName()+"__"+id+"();\n");            }            if (node.contents instanceof SIRTwoStageFilter) {                String initWork = ((SIRTwoStageFilter)node.contents).getInitWork().getName()+"__"+id;                p.print("extern void "+initWork+"();\n");            }            if (node.contents instanceof SIRStream && SIRPortal.getPortalsWithSender((SIRStream)node.contents).length > 0) {                p.print("extern void __init_sdep_"+id+"();\n");            }                        if (node.contents instanceof SIRStream && SIRPortal.getPortalsWithReceiver((SIRStream)node.contents).length > 0) {                p.print("extern void check_messages__"+id+"();\n");            }            p.print("extern void "+get_work_function(node.contents)+"(int);\n");	    if ((node.contents instanceof SIRFileReader)	            || (node.contents instanceof SIRFileWriter)) {		p.print("extern void "+get_work_function(node.contents)+"__close();\n");	    }	    if ((node.contents instanceof SIRFilter) &&		!(node.contents instanceof SIRFileReader) &&		!(node.contents instanceof SIRFileWriter)) {				CType input_type = ((SIRFilter)node.contents).getInputType();		CType output_type = ((SIRFilter)node.contents).getOutputType();		p.println("extern void "+get_work_function(node.contents)+"__mod(int ____n, "+input_type+" *____in, "+output_type+" *____out);");		p.println("extern void "+get_work_function(node.contents)+"__mod2(int ____n, "+input_type+" *____in, "+output_type+" *____out, int s1, int s2);");	    }            /*              String work_n = get_work_n_function(node.contents);              if (work_n != null) {              p.print("extern void "+work_n+"(int n);\n");              }            */        }        p.newLine();        p.print("int main(int argc, char **argv) {\n");        // tell the profiler how many ID's there are        if (KjcOptions.countops) {            p.println("  profiler::set_num_ids(" + InsertCounters.getNumIds() + ");");        }        p.print("  read_setup::read_setup_file();\n");        p.print("  __max_iteration = read_setup::max_iteration;\n");        p.print("  for (int a = 1; a < argc; a++) {\n");        p.print("    if (argc > a + 1 && strcmp(argv[a], \"-i\") == 0) {\n");        p.print("      int tmp;\n");        p.print("      sscanf(argv[a + 1], \"%d\", &tmp);\n");        p.println("#ifdef VERBOSE");        p.print("      fprintf(stderr,\"Number of Iterations: %d\\n\", tmp);\n");        p.println("#endif");        p.print("      __max_iteration = tmp;\n");        p.print("    }\n");        p.print("    if (strcmp(argv[a], \"-t\") == 0) {\n");         p.println("#ifdef VERBOSE");        p.print("       fprintf(stderr,\"Timer enabled.\\n\");\n");         p.println("#endif");        p.print("       __timer_enabled = 1;");         p.print("    }\n");        p.print("  }\n");// implicit_mult used to be a parameter, but entire peek-scaling// feature has been turned off since much more likely to be a pessimization// than an optimization//        p.print("  if ("+implicit_mult+" > 1) {\n");//        p.println("#ifdef VERBOSE");//        p.print("    fprintf(stderr,\"Implicit multiplicity: "+implicit_mult+"\\n\");\n");//        p.println("#endif");//        p.print("    int tmp;\n");//        p.print("    tmp = __max_iteration / "+implicit_mult+";\n");//        p.print("    if (__max_iteration % "+implicit_mult+" > 0) tmp++;\n");//        p.print("    __max_iteration = tmp;\n");//        p.println("#ifdef VERBOSE");//        p.print("    fprintf(stderr,\"Number of Iterations: %d (%d)\\n\", __max_iteration, __max_iteration * "+implicit_mult+");\n");//        p.println("#endif");//        p.print("  }\n");        /*          for (int i = 0; i < threadNumber; i++) {          //FlatNode tmp = NodeEnumerator.getFlatNode(i);          //if (!ClusterFusion.isEliminated(tmp)) {               p.print("__declare_sockets_"+i+"();");          }          p.println();          p.println();          p.print("  init_instance::initialize_sockets();");          p.println();          p.println();          p.print("  ");          for (int i = 0; i < threadNumber; i++) {          //FlatNode tmp = NodeEnumerator.getFlatNode(i);          //if (!ClusterFusion.isEliminated(tmp)) {               p.print("__init_sockets_"+i+"(NULL);");          }          p.println();          p.println();        */        int n_phases = d_sched.getNumberOfPhases();        p.print("// number of phases: "+n_phases+"\n");        p.newLine();        p.newLine();        p.print("  // ============= Initialization =============\n");        for (SIRJoiner j : ClusterCode.feedbackJoineersNeedingPrep) {            p.println("__feedbackjoiner_"+ NodeEnumerator.getSIROperatorId(j) +"_prep();");        }        p.newLine();                for (int ph = 0; ph < n_phases; ph++) {                //p.print("  // ============= Phase: "+ph+" =============\n");            HashSet phase = d_sched.getAllOperatorsInPhase(ph);            Iterator iter = phase.iterator();            while (iter.hasNext()) {                SIROperator oper = (SIROperator)iter.next();                int id = NodeEnumerator.getSIROperatorId(oper);                FlatNode node = NodeEnumerator.getFlatNode(id);                Integer init = (Integer)ClusterBackend.initExecutionCounts.get(node);                int init_int = 0;                if (init != null) init_int = (init).intValue();                Integer steady = (Integer)ClusterBackend.steadyExecutionCounts.get(node);                int steady_int = 0;                if (steady != null) steady_int = (steady).intValue();                if (steady_int > 0) {                    if (init_int > 0) {                                    if (oper instanceof SIRFilter) {                                            //if (ph > 0) p.print("  __init_pop_buf__"+id+"(); "); else p.print("  ");                            p.print("  ");                            p.print(((SIRFilter)oper).getInit().getName()+"__"+id+"(); ");                            if (SIRPortal.getPortalsWithSender((SIRFilter)oper).length > 0) {                                //p.print(" /* " + SIRPortal.getPortalsWithSender((SIRFilter)oper).length + "*/ ");                                p.print("  __init_sdep_"+id+"();");                            }                                        } else {                            p.print("  ");                        }                                    if (oper instanceof SIRTwoStageFilter) {                            String initWork = ((SIRTwoStageFilter)node.contents).getInitWork().getName()+"__"+id;                            p.print("  "+initWork+"();");                            if (init_int > 1) {                                p.print("  "+get_work_function(oper)+"("+                                        (init_int-1)+");");                            }                                        } else {                            p.print("  "+get_work_function(oper)+"("+init_int+");");                        }                        //p.print(get_loop(init_int, get_work_function(oper)+"();"));                        p.newLine();                                } else {                                    if (oper instanceof SIRFilter) {                                                    //if (ph > 0) p.print("  __init_pop_buf__"+id+"(); ");                            p.print(((SIRFilter)oper).getInit().getName()+"__"+id+"();");                            if (SIRPortal.getPortalsWithSender((SIRFilter)oper).length > 0) {                                p.print("  __init_sdep_"+id+"();");                            }                            p.newLine();                        }                    }                }            }            //p.println();        }        p.newLine();        p.print("  // ============= Steady State =============\n");        p.newLine();        p.println("  if (__timer_enabled) {");        p.println("    tt.start();");        p.println("  }");        p.print("  for (int n = 0; n < (__max_iteration / __MULT); n++) {\n");        for (int ph = 0; ph < n_phases; ph++) {                //p.print("  // ============= Phase: "+ph+" =============\n");            HashSet phase = d_sched.getAllOperatorsInPhase(ph);            Iterator iter = phase.iterator();            while (iter.hasNext()) {                SIROperator oper = (SIROperator)iter.next();                int id = NodeEnumerator.getSIROperatorId(oper);                FlatNode node = NodeEnumerator.getFlatNode(id);                boolean rcv_msg = false;                if (oper instanceof SIRFilter) {                    if (SIRPortal.getPortalsWithReceiver((SIRFilter)oper).length > 0) {                        rcv_msg = true;                    }                }//                Integer init = (Integer)ClusterBackend.initExecutionCounts.get(node);//                int init_int = 0;//                if (init != null) init_int = (init).intValue();                Integer steady = (Integer)ClusterBackend.steadyExecutionCounts.get(node);                int steady_int = 0;                if (steady != null) steady_int = (steady).intValue();                if (steady_int > 0) {                    Vector out = RegisterStreams.getNodeOutStreams(oper);                    for (int i = 0; i < out.size(); i++) {                        NetStream s = (NetStream)out.elementAt(i);                        int _s = s.getSource();                        int _d = s.getDest();                        if (FixedBufferTape.isFixedBuffer(_s,_d)) {                        if (!FixedBufferTape.needsModularBuffer(_s,_d)) {                            // p.print(" #ifdef __NOMOD_"+_s+"_"+_d+"\n");                            if (FixedBufferTape.hasExtraPeeks(_s,_d)) {                                // p.print(" #ifdef __PEEK_BUF_SIZE_"+_s+"_"+_d+"\n");                                p.print("      for (int __y = 0; __y < __PEEK_BUF_SIZE_"                                                + _s                                                + "_"                                                + _d                                                + "; __y++) {\n");                                p.print("        BUFFER_" + _s + "_" + _d                                        + "[__y] = BUFFER_" + _s + "_" + _d                                        + "[__y + TAIL_" + _s + "_" + _d                                        + "];\n");                                p.print("      }\n");                                p.print("      HEAD_" + _s + "_" + _d                                        + " -= TAIL_" + _s + "_" + _d + ";\n");                                p.print("      TAIL_" + _s + "_" + _d                                        + " = 0;\n");                                //p.print("    #else\n");                            } else {                                p.print("      HEAD_" + _s + "_" + _d                                        + " = 0;\n");                                p.print("      TAIL_" + _s + "_" + _d                                        + " = 0;\n");                                //p.print("    #endif\n");                            }                            //p.print("    #endif\n");                        }                                    /*                        p.print("    if (HEAD_"+_s+"_"+_d+" - TAIL_"+_s+"_"+_d+" != __PEEK_BUF_SIZE_"+_s+"_"+_d+") {\n");                        p.print("      fprintf(stderr,\"head: %d\\n\", HEAD_"+_s+"_"+_d+");\n");                        p.print("      fprintf(stderr,\"tail: %d\\n\", TAIL_"+_s+"_"+_d+");\n");                        p.print("      assert(1 == 0);\n");                        p.print("    }\n");                        */                    }                    }                    if (rcv_msg) p.print("    check_messages__"+id+"();\n");                    p.print("    "+get_work_function(oper)+"("+steady_int+"*__MULT);");                }                                p.newLine();            }        }                p.print("  }\n");        //p.print("  for (int n = 0; n < (__max_iteration % __MULT); n++) {\n");        p.print("  int rem = (__max_iteration % __MULT);\n\n");        for (int ph = 0; ph < n_phases; ph++) {                HashSet phase = d_sched.getAllOperatorsInPhase(ph);            Iterator iter = phase.iterator();            while (iter.hasNext()) {                SIROperator oper = (SIROperator)iter.next();                int id = NodeEnumerator.getSIROperatorId(oper);                FlatNode node = NodeEnumerator.getFlatNode(id);                boolean rcv_msg = false;                if (oper instanceof SIRFilter) {                    if (SIRPortal.getPortalsWithReceiver((SIRFilter)oper).length > 0) {                        rcv_msg = true;                    }                }                //                Integer init = (Integer)ClusterBackend.initExecutionCounts.get(node);//                int init_int = 0;//                if (init != null) init_int = (init).intValue();                Integer steady = (Integer)ClusterBackend.steadyExecutionCounts.get(node);                int steady_int = 0;                if (steady != null) steady_int = (steady).intValue();                if (steady_int > 0) {                    Vector out = RegisterStreams.getNodeOutStreams(oper);                    for (int i = 0; i < out.size(); i++) {                        NetStream s = (NetStream)out.elementAt(i);                        int _s = s.getSource();                        int _d = s.getDest();                        if (FixedBufferTape.isFixedBuffer(_s,_d)) {                        if (! FixedBufferTape.needsModularBuffer(_s,_d)) {                        //p.print("    #ifdef __NOMOD_"+_s+"_"+_d+"\n");                        if (FixedBufferTape.getExtraPeeks(_s,_d) > 0) {                        //p.print("    #ifdef __PEEK_BUF_SIZE_"+_s+"_"+_d+"\n");                        // //p.println("// FusionCode_1");                        p.print("      for (int __y = 0; __y < __PEEK_BUF_SIZE_"+_s+"_"+_d+"; __y++) {\n");                        p.print("        BUFFER_"+_s+"_"+_d+"[__y] = BUFFER_"+_s+"_"+_d+"[__y + TAIL_"+_s+"_"+_d+"];\n");                        p.print("      }\n");                        p.print("      HEAD_"+_s+"_"+_d+" -= TAIL_"+_s+"_"+_d+";\n");                        p.print("      TAIL_"+_s+"_"+_d+" = 0;\n");                                    //p.print("    #else\n");                        } else {                         p.print("      HEAD_"+_s+"_"+_d+" = 0;\n");                        p.print("      TAIL_"+_s+"_"+_d+" = 0;\n");                        //p.print("    #endif\n");                        }                        //p.print("    #endif\n");                        }                        /*                        p.print("    if (HEAD_"+_s+"_"+_d+" - TAIL_"+_s+"_"+_d+" != __PEEK_BUF_SIZE_"+_s+"_"+_d+") {\n");                        p.print("      fprintf(stderr,\"head: %d\\n\", HEAD_"+_s+"_"+_d+");\n");                        p.print("      fprintf(stderr,\"tail: %d\\n\", TAIL_"+_s+"_"+_d+");\n");                        p.print("      assert(1 == 0);\n");                        p.print("    }\n");                        */                    }                    }                    if (rcv_msg) p.print("    check_messages__"+id+"();\n");                    p.print("    "+get_work_function(oper)+"("+steady_int+"*rem);");                                        if ((node.contents instanceof SIRFileReader) ||                        (node.contents instanceof SIRFileWriter)) {                        p.print("    "+get_work_function(oper)+"__close();\n");                    }                                    }                /*                if (steady_int > 0) {                Vector out = RegisterStreams.getNodeOutStreams(oper);                for (int i = 0; i < out.size(); i++) {                NetStream s = (NetStream)out.elementAt(i);                int _s = s.getSource();                int _d = s.getDest();                p.print("    #ifdef __NOMOD_"+_s+"_"+_d+"\n");                p.print("    HEAD_"+_s+"_"+_d+" = 0; TAIL_"+_s+"_"+_d+" = 0;\n");                p.print("    #endif\n");                }                            p.print("    "+get_work_function(oper)+"("+steady_int+");");                }                */                p.newLine();            }        }            //p.print("  }\n");        p.indent();        // print -t timer summary.        p.println("if (__timer_enabled) {");        p.println("  tt.stop();");        p.println("  tt.output(stderr);");        p.println("}");                // print profiling timer summary        p.println();        if (KjcOptions.profile) {            String ident = InsertTimers.getIdentifier();            p.println("FILE* timer_output = fopen(\"profile.c.log\", \"w\");");            p.println("for (int i = 0; i<" + InsertTimers.getNumTimers() + "; i++) {");             p.println("  " + ident + "[i].output(timer_output);");            p.println("}");            p.println("fclose(timer_output);");            p.println("printf(\"Profiling information written to profile.c.log.\\n\");");        }        p.println();        // print profiling summary        if (KjcOptions.countops) {            p.println("  profiler::summarize();");        }        p.println("return 0;");        p.outdent();        p.println("}");        try {            p.close();        }        catch (Exception e) {            System.err.println("Unable to write fusion.cpp");        }    }