Vector in = (Vector)RegisterStreams.getNodeInStreams(node.contents); Vector out_v = (Vector)RegisterStreams.getNodeOutStreams(node.contents); NetStream out = (NetStream)out_v.elementAt(0);
List<NetStream> in = RegisterStreams.getNodeInStreams(node.contents); List<NetStream> out_v = RegisterStreams.getNodeOutStreams(node.contents); NetStream out = out_v.get(0);
    public static void generateJoiner(FlatNode node) {                SIRJoiner joiner = (SIRJoiner)node.contents;        if (joiner.getSumOfWeights() == 0) {            // The joiner is not doing any work                    return;        }        int init_counts, steady_counts;        Integer init_int = (Integer)ClusterBackend.initExecutionCounts.get(node);        if (init_int==null) {            init_counts = 0;        } else {            init_counts = init_int.intValue();        }        steady_counts = ((Integer)ClusterBackend.steadyExecutionCounts.get(node)).intValue();        CType baseType = CommonUtils.getBaseType(CommonUtils.getJoinerType(node));        int thread_id = NodeEnumerator.getSIROperatorId(node.contents);        Vector in = (Vector)RegisterStreams.getNodeInStreams(node.contents);        Vector out_v = (Vector)RegisterStreams.getNodeOutStreams(node.contents);        NetStream out = (NetStream)out_v.elementAt(0);        CodegenPrintWriter p = null;        try {            p = new CodegenPrintWriter(new FileWriter("thread"+thread_id+".cpp"));        } catch (IOException e) {            e.printStackTrace();            System.exit(1);        }                ClusterCodeGenerator gen = new ClusterCodeGenerator(joiner, new JFieldDeclaration[0]);        p.print("// init counts: "+init_counts+" steady counts: "+steady_counts+"\n");         p.newLine();        //  +=============================+        //  | Preamble                    |        //  +=============================+             FlatIRToCluster f2c = new FlatIRToCluster(p);        gen.generatePreamble(f2c,p);        p.print("void save_peek_buffer__"+thread_id+"(object_write_buffer *buf) {}\n");        p.print("void load_peek_buffer__"+thread_id+"(object_write_buffer *buf) {}\n");        p.newLine();        p.println("void save_file_pointer__"+thread_id+"(object_write_buffer *buf) {}");        p.println("void load_file_pointer__"+thread_id+"(object_write_buffer *buf) {}");        p.newLine();        int _s = out.getSource();        int _d = out.getDest();        if (FixedBufferTape.isFixedBuffer(_s, _d)) {            p.print("extern " + baseType.toString() + " BUFFER_" + _s + "_"                    + _d + "[];\n");            p.print("extern int HEAD_" + _s + "_" + _d + ";\n");            p.print("extern int TAIL_" + _s + "_" + _d + ";\n");        }           for (int o = 0; o < in.size(); o++) {            _s = ((NetStream)in.elementAt(o)).getSource();            _d = ((NetStream)in.elementAt(o)).getDest();            if (FixedBufferTape.isFixedBuffer(_s, _d)) {                p.print("extern " + baseType.toString() + " BUFFER_" + _s + "_"                        + _d + "[];\n");                p.print("extern int HEAD_" + _s + "_" + _d + ";\n");                p.print("extern int TAIL_" + _s + "_" + _d + ";\n");            }        }        //  +=============================+        //  | Joiner Pop                  |        //  +=============================+        if (! FixedBufferTape.isFixedBuffer(out.getSource(),out.getDest())) {        int sum_of_weights = joiner.getSumOfWeights();        p.print(baseType.toString()+" "+out.pop_buffer()+"["+sum_of_weights+"];\n");        p.print("int "+out.pop_index()+" = "+sum_of_weights+";\n");        p.newLine();        p.print(baseType.toString()+" "+out.pop_name()+"() {\n");        p.print("  if ("+out.pop_index()+" == "+sum_of_weights+") {\n");        int _offs = 0;                //int ways = joiner.getWays();        for (int i = 0; i < in.size(); i++) {            int num = joiner.getWeight(i);                        NetStream s = (NetStream)in.elementAt(i);            FlatNode source = NodeEnumerator.getFlatNode(s.getSource());            if (ClusterFusion.fusedWith(node).contains(source)) {                for (int y = 0; y < num; y++) {                    p.print("    "+out.pop_buffer()+"["+(_offs + y)+"] = "+s.pop_name()+"();\n");                }            } else {                p.print("    "+s.consumer_name()+".pop_items(&"+out.pop_buffer()+"["+_offs+"], "+num+");\n");            }            _offs += num;        }        p.print("    "+out.pop_index()+" = 0;\n");        p.print("  }\n");            p.print("  return "+out.pop_buffer()+"["+out.pop_index()+"++];\n");        p.print("}\n");        p.newLine();        }                //  +=============================+        //  | Init Path                   |        //  +=============================+        if (joiner.getParent() instanceof SIRFeedbackLoop) {                    SIRFeedbackLoop floop = (SIRFeedbackLoop)joiner.getParent();            p.print("//delay = "+((JIntLiteral)floop.getDelay()).intValue());            p.newLine();            JMethodDeclaration ipath = floop.getInitPath();            ipath.setName("__Init_Path_"+thread_id);            FlatIRToCluster fir = new FlatIRToCluster();            fir.setDeclOnly(false);            ipath.accept(fir);            p.print(fir.getPrinter().getString());            p.newLine();            p.newLine();        }        // +==============================+        // | Joiner Prep Feedbackloop     |        // +==============================+                    if (joiner.getParent() instanceof SIRFeedbackLoop                && ((SIRFeedbackLoop) joiner.getParent()).getDelayInt() > 0) {            //            // Joiner is a part of feedbackloop with non-zero delay:            // we need initialization code to put enqueues onto tape from loop            // portion            // back to joiner.            //            feedbackJoineersNeedingPrep.add(joiner);            Vector<NetStream> instreams = RegisterStreams                    .getNodeInStreams(joiner);            NetStream looptape = instreams.size() > 1 ? instreams.elementAt(1) : instreams.elementAt(0);            int s = looptape.getSource();            int enqueue_count = ((SIRFeedbackLoop) joiner.getParent())                    .getDelayInt();            p.println("void __feedbackjoiner_"+thread_id+"_prep() {");            p.indent();            if (FixedBufferTape.isFixedBuffer(s, thread_id)) {                p.println("for (int i = 0; i < " + enqueue_count + "; i++) {");                p.indent();                p.print("BUFFER_" + s + "_" + thread_id + "[HEAD_" + s + "_" + thread_id + "]");                p.println(" = __Init_Path_" + thread_id + "(i);");                p.println("HEAD_" + s + "_" + thread_id + "++;");                p.outdent();                p.println("}");            } else {                p.println(looptape.consumer_name() + ".start_push("                        + enqueue_count + ");");                p.println("for (int i = 0; i < " + enqueue_count + "; i++) {");                p.indent();                p.println(looptape.consumer_name()                        + ".push(__Init_Path_" + thread_id + "(i));");                p.outdent();                p.println("}");            }            p.outdent();            p.println("}");            p.print("  " + baseType.toString() + " tmp;\n");        }                // +=============+        // | Joiner Work |        //  +============+         p.newLine();        p.print("void __joiner_"+thread_id+"_work(int ____n) {\n");        p.print("  for (;____n > 0; ____n--) {\n");        FlatNode dest_flat = NodeEnumerator.getFlatNode(out.getSource());        if (joiner.getType().equals(SIRJoinType.ROUND_ROBIN) ||             joiner.getType().equals(SIRJoinType.WEIGHTED_RR)) {                int sum = joiner.getSumOfWeights();                int offs = 0;                int _s2 = out.getSource();                int _d2 = out.getDest();		// depending on the weight unroll fully or by some constant factor		if (sum < MAX_JOINER_SUM_WEIGHTS_TO_UNROLL) {                // unroll fully!                for (int i = 0; i < in.size(); i++) {                    int num = joiner.getWeight(i);                    NetStream s = (NetStream) in.elementAt(i);                    int _s1 = s.getSource();                    int _d1 = s.getDest();                    for (int y = 0; y < num; y++) {                        // Destination                        if (FixedBufferTape.isFixedBuffer(_s2, _d2)) {                            if (!FixedBufferTape.needsModularBuffer(_s2, _d2)) {                                p.print("      BUFFER_" + _s2 + "_" + _d2                                        + "[HEAD_" + _s2 + "_" + _d2 + " + "                                        + offs + "] = \n");                            } else {                                p.print("      BUFFER_" + _s2 + "_" + _d2                                        + "[(HEAD_" + _s2 + "_" + _d2 + " + "                                        + offs + ") & __BUF_SIZE_MASK_" + _s2                                        + "_" + _d2 + "] = \n");                            }                        } else {                            if (ClusterFusion.fusedWith(node).contains(                                    dest_flat)) {                                p.print("    " + out.push_name() + "(\n");                            } else {                                p.print("    " + out.producer_name()                                        + ".push(\n");                            }                        }                        // Source                        if (FixedBufferTape.isFixedBuffer(_s1, _d1)) {                            if (!FixedBufferTape.needsModularBuffer(_s1, _d1)) {                                p.print("      BUFFER_" + _s1 + "_" + _d1                                        + "[TAIL_" + _s1 + "_" + _d1 + " + "                                        + y + "]\n");                            } else {                                p.print("      BUFFER_" + _s1 + "_" + _d1                                        + "[(TAIL_" + _s1 + "_" + _d1 + " + "                                        + y + ") & __BUF_SIZE_MASK_" + _s1                                        + "_" + _d1 + "]\n");                            }                        } else {                            p.print("    " + s.consumer_name() + ".pop()\n");                        }                        // Close Assignement to Dest or Push Operator                        if (FixedBufferTape.isFixedBuffer(_s2, _d2)) {                            p.print("    ; // assignment\n");                        } else {                            p.print("    ); // push()\n");                        }                        offs++;                    }                    if (FixedBufferTape.isFixedBuffer(_s1, _d1)) {                        p.print("    TAIL_" + _s1 + "_" + _d1 + " += " + num                                + ";\n");                        if (FixedBufferTape.needsModularBuffer(_s1, _d1)) {                            p.print("    TAIL_" + _s1 + "_" + _d1                                    + " &= __BUF_SIZE_MASK_" + _s1 + "_" + _d1                                    + ";\n");                        }                    }                }                if (FixedBufferTape.isFixedBuffer(_s2, _d2)) {                    p.print("    HEAD_" + _s2 + "_" + _d2 + " += " + sum                            + ";\n");                    if (FixedBufferTape.needsModularBuffer(_s2, _d2)) {                        p.print("    HEAD_" + _s2 + "_" + _d2                                + " &= __BUF_SIZE_MASK_" + _s2 + "_" + _d2                                + ";\n");                    }                }		} else {		    // do not unroll fully weight >= MAX_JOINER_WEIGHTS_TO_UNROLL		    for (int i = 0; i < in.size(); i++) {			int num = joiner.getWeight(i);			NetStream s = (NetStream)in.elementAt(i);       						int _s1 = s.getSource();			int _d1 = s.getDest();						p.println("  for (int k = 0; k < "+num/UNROLL_JOINER_BY+"; k++) {\n");			for (int y = 0; y < UNROLL_JOINER_BY; y++) {                        // Destination                        if (FixedBufferTape.isFixedBuffer(_s2, _d2)) {                            if (!FixedBufferTape.needsModularBuffer(_s2, _d2)) {                                p.print("      BUFFER_" + _s2 + "_" + _d2                                        + "[HEAD_" + _s2 + "_" + _d2 + " + "                                        + y + "] = \n");                            } else {                                p.print("      BUFFER_" + _s2 + "_" + _d2                                        + "[(HEAD_" + _s2 + "_" + _d2 + " + "                                        + y + ") & __BUF_SIZE_MASK_" + _s2                                        + "_" + _d2 + "] = \n");                            }                        } else {                            if (ClusterFusion.fusedWith(node).contains(                                    dest_flat)) {                                p.print("    " + out.push_name() + "(\n");                            } else {                                p.print("    " + out.producer_name()                                        + ".push(\n");                            }                        }                        // Source                        if (FixedBufferTape.isFixedBuffer(_s1, _d1)) {                            if (!FixedBufferTape.needsModularBuffer(_s1, _d1)) {                                p.print("      BUFFER_" + _s1 + "_" + _d1                                        + "[TAIL_" + _s1 + "_" + _d1 + " + "                                        + y + "]\n");                            } else {                                p.print("      BUFFER_" + _s1 + "_" + _d1                                        + "[(TAIL_" + _s1 + "_" + _d1 + " + "                                        + y + ") & __BUF_SIZE_MASK_" + _s1                                        + "_" + _d1 + "]\n");                            }                        } else {                            p.print("    " + s.consumer_name() + ".pop()\n");                        }                        // Close Assignement to Dest or Push Operator                        if (FixedBufferTape.isFixedBuffer(_s2, _d2)) {                            p.print("    ; // assignment\n");                        } else {                            p.print("    ); // push()\n");                        }                        offs++;                    }                    if (FixedBufferTape.isFixedBuffer(_s1, _d1)) {                        p.print("    TAIL_" + _s1 + "_" + _d1 + " += "                                + UNROLL_JOINER_BY + ";\n");                        if (FixedBufferTape.needsModularBuffer(_s1, _d1)) {                            p.print("    TAIL_" + _s1 + "_" + _d1                                    + " &= __BUF_SIZE_MASK_" + _s1 + "_" + _d1                                    + ";\n");                        }                    }                    if (FixedBufferTape.isFixedBuffer(_s2, _d2)) {                        p.print("    HEAD_" + _s2 + "_" + _d2 + " += "                                + UNROLL_JOINER_BY + ";\n");                        if (FixedBufferTape.needsModularBuffer(_s2, _d2)) {                            p.print("    HEAD_" + _s2 + "_" + _d2                                    + " &= __BUF_SIZE_MASK_" + _s2 + "_" + _d2                                    + ";\n");                        }                    }                    p.println("  }\n");						int rem = num % UNROLL_JOINER_BY;			for (int y = 0; y < rem; y++) {                        // Destination                        if (FixedBufferTape.isFixedBuffer(_s2, _d2)) {                            if (!FixedBufferTape.needsModularBuffer(_s2, _d2)) {                                p.print("      BUFFER_" + _s2 + "_" + _d2                                        + "[HEAD_" + _s2 + "_" + _d2 + " + "                                        + y + "] = \n");                            } else {                                p.print("      BUFFER_" + _s2 + "_" + _d2                                        + "[(HEAD_" + _s2 + "_" + _d2 + " + "                                        + y + ") & __BUF_SIZE_MASK_" + _s2                                        + "_" + _d2 + "] = \n");                            }                        } else {                            if (ClusterFusion.fusedWith(node).contains(                                    dest_flat)) {                                p.print("    " + out.push_name() + "(\n");                            } else {                                p.print("    " + out.producer_name()                                        + ".push(\n");                            }                        }                        // Source                        if (FixedBufferTape.isFixedBuffer(_s1, _d1)) {                            if (!FixedBufferTape.needsModularBuffer(_s1, _d1)) {                                p.print("      BUFFER_" + _s1 + "_" + _d1                                        + "[TAIL_" + _s1 + "_" + _d1 + " + "                                        + y + "]\n");                            } else {                                p.print("      BUFFER_" + _s1 + "_" + _d1                                        + "[(TAIL_" + _s1 + "_" + _d1 + " + "                                        + y + ") & __BUF_SIZE_MASK_" + _s1                                        + "_" + _d1 + "]\n");                            }                        } else {                            p.print("    " + s.consumer_name() + ".pop()\n");                        }                        // Close Assignement to Dest or Push Operator                        if (FixedBufferTape.isFixedBuffer(_s2, _d2)) {                            p.print("    ; // assignment\n");                        } else {                            p.print("    ); // push()\n");                        }                        offs++;                    }                    if (FixedBufferTape.isFixedBuffer(_s1, _d1)) {                        p.print("    TAIL_" + _s1 + "_" + _d1 + " += " + rem                                + ";\n");                        if (FixedBufferTape.needsModularBuffer(_s1, _d1)) {                            p.print("    TAIL_" + _s1 + "_" + _d1                                    + " &= __BUF_SIZE_MASK_" + _s1 + "_" + _d1                                    + ";\n");                        }                    }                    if (FixedBufferTape.isFixedBuffer(_s2, _d2)) {                        p.print("    HEAD_" + _s2 + "_" + _d2 + " += " + rem                                + ";\n");                        if (FixedBufferTape.needsModularBuffer(_s2, _d2)) {                            p.print("    HEAD_" + _s2 + "_" + _d2                                    + " &= __BUF_SIZE_MASK_" + _s2 + "_" + _d2                                    + ";\n");                        }                    }                }            }        }        p.print("  }\n");        p.print("}\n");        p.newLine();        //  +=============================+        //  | Joiner Main                 |        //  +=============================+        //  +=============================+        //  | Run Function                |        //  +=============================+        Vector<String> run = gen.generateRunFunction(null, "__joiner_"                + thread_id + "_main", new Vector<String>());        for (int i = 0; i < run.size(); i++) {            p.print(run.elementAt(i).toString());        }        //  +=============================+        //  | Write Joiner to File        |        //  +=============================+        try {            p.close();        }        catch (Exception e) {            System.err.println("Unable to write joiner code to file thread"                    + thread_id + ".cpp");        }        if (ClusterBackend.debugPrint)            System.out.println("Code for " + node.contents.getName() +                               " written to thread"+thread_id+".cpp");    }