int m = push / gcd(join_weight, push); mult = mult * m / gcd(mult, m);
int m = push / gcd(join_weight, push); mult = (mult / gcd(mult, m)) * m;
    public FusionInfo getFusionInfo() {        if (fusion_info != null) return fusion_info; // check if we have precomputed        int work = 0;        int work_no_penalty = 0;            int code = 0;        int data = 0;            // how many times the split join will be executed         // after fusion in a steady state        /*        HashMap sched[] = SIRScheduler.getExecutionCounts(split_join);        HashMap steady = sched[1];            int splitter_mult = 0;        int joiner_mult = 0;        int channel_mult[] = new int[cont.size()];        if (split_join.getSplitter().getSumOfWeights() > 0) {        int a[] = (int[])steady.get(split_join.getSplitter());        splitter_mult = a[0];        for (int i = 0; i < cont.size(); i++) {        int pop = childConfig(i).getFusionInfo().getPopInt();        int split_weight = split_join.getSplitter().getWeight(i);        channel_mult[i] = splitter_mult * split_weight / pop;        }                // add impossible unroll penalty        if (splitter_mult > KjcOptions.unroll) {        work += 1000;        }        }                if (split_join.getJoiner().getSumOfWeights() > 0) {        int a[] = (int[])steady.get(split_join.getJoiner());        joiner_mult = a[0];        for (int i = 0; i < cont.size(); i++) {        int push = childConfig(i).getFusionInfo().getPushInt();        int joiner_weight = split_join.getJoiner().getWeight(i);        int cmult = joiner_mult * joiner_weight / push;        if (splitter_mult > 0) assert (cmult == channel_mult[i]);        channel_mult[i] = cmult;        }                // add impossible unroll penalty        if (joiner_mult > KjcOptions.unroll) {        work += 1000;        }        }                int_obj        // add impossible unroll penalty        int_obj = (Integer)steady.get(split_join.getJoiner());        if (int_obj != null && int_obj.intValue() > KjcOptions.unroll) {        work += 1000;        }        */        int mult = 1;        int fmult[] = new int[cont.size()];        int j_sum = split_join.getJoiner().getSumOfWeights();        int s_sum = split_join.getSplitter().getSumOfWeights();        int s_mult = 0;        int j_mult = 0;        //System.out.println("[Fusion info for SplitJoin]");        //for (int i = 0; i < cont.size(); i++) {        //    System.out.println("[split: "+split_join.getSplitter().getWeight(i)+" join: "+split_join.getJoiner().getWeight(i)+" pop: "+childConfig(i).getFusionInfo().getPopInt()+" push: "+childConfig(i).getFusionInfo().getPushInt()+"]");        //}            if (split_join.getJoiner().getSumOfWeights() == 0) {            // We assume all of splitters weights are positive            //System.out.println("CASE2");            for (int i = 0; i < cont.size(); i++) {                int pop = childConfig(i).getFusionInfo().getPopInt();                int split_weight = split_join.getSplitter().getWeight(i);                int m = pop / gcd(split_weight, pop); // multiple for splitter                mult = mult * m / gcd(mult, m);            }            for (int i = 0; i < cont.size(); i++) {                int pop = childConfig(i).getFusionInfo().getPopInt();                int split_weight = split_join.getSplitter().getWeight(i);                fmult[i] = mult * split_weight / pop;                //System.out.print("[fmult["+i+"] = "+fmult[i]+"] ");            }            s_mult = mult;        } else {            // We assume all of joiners weights are positive            // Some of the splitters weights might be zero            //System.out.println("CASE1");            for (int i = 0; i < cont.size(); i++) {                int push = childConfig(i).getFusionInfo().getPushInt();                int join_weight = split_join.getJoiner().getWeight(i);                int m = push / gcd(join_weight, push); // multiple for joiner                mult = mult * m / gcd(mult, m);            }            for (int i = 0; i < cont.size(); i++) {                int push = childConfig(i).getFusionInfo().getPushInt();                int join_weight = split_join.getJoiner().getWeight(i);                fmult[i] = mult * join_weight / push;            }                    j_mult = mult;            if (s_sum > 0) {                for (int j = 0; j < cont.size(); j++) {                    int pop = childConfig(j).getFusionInfo().getPopInt();                    int splitter_weight = split_join.getSplitter().getWeight(j);                            if (splitter_weight == 0) continue;                    // items is number of items joiner has to consume                    // from branch 1                    int items = pop * fmult[j];                    int lcd = items * splitter_weight / gcd(items, splitter_weight);                            s_mult = lcd / splitter_weight;                     int xtra = lcd / items;                    j_mult *= xtra;                    for (int i = 0; i < cont.size(); i++) {                        fmult[i] *= xtra;                    }                }            }        }        /*            if (split_join.getSplitter().getSumOfWeights() == 0) {        //System.out.println("CASE1");        for (int i = 0; i < cont.size(); i++) {        int push = childConfig(i).getFusionInfo().getPushInt();        int join_weight = split_join.getJoiner().getWeight(i);        int m = push / gcd(join_weight, push); // multiple for joiner        mult = mult * m / gcd(mult, m);        }        for (int i = 0; i < cont.size(); i++) {        int push = childConfig(i).getFusionInfo().getPushInt();        int join_weight = split_join.getJoiner().getWeight(i);        fmult[i] = mult * join_weight / push;        }                j_mult = mult;        } else {        //System.out.println("CASE2");        for (int i = 0; i < cont.size(); i++) {        int pop = childConfig(i).getFusionInfo().getPopInt();        int split_weight = split_join.getSplitter().getWeight(i);        int m = pop / gcd(split_weight, pop); // multiple for splitter        mult = mult * m / gcd(mult, m);        }        for (int i = 0; i < cont.size(); i++) {        int pop = childConfig(i).getFusionInfo().getPopInt();        int split_weight = split_join.getSplitter().getWeight(i);        fmult[i] = mult * split_weight / pop;        //System.out.print("[fmult["+i+"] = "+fmult[i]+"] ");        }        s_mult = mult;                if (j_sum > 0) {        int push = childConfig(0).getFusionInfo().getPushInt();        int joiner_weight = split_join.getJoiner().getWeight(0);                // items is number of items joiner has to consume        // from branch 1        int items = push * fmult[0];        int lcd = items * joiner_weight / gcd(items, joiner_weight);                j_mult = lcd / joiner_weight;         int xtra = lcd / items;        s_mult *= xtra;        for (int i = 0; i < cont.size(); i++) {        fmult[i] *= xtra;        }        }        }        */        for (int i = 0; i < cont.size(); i++) {            //System.out.print("[fmult["+i+"] = "+fmult[i]+"] ");        }        if (s_mult > KjcOptions.unroll) work += 100;        if (j_mult > KjcOptions.unroll) work += 100;        // duplicate splitter fusion penalty        //if (split_join.getSplitter().getType().isDuplicate()) {        //    work += 100;        //}        //System.out.println("\n[s-mult: "+s_mult+" j-mult: "+j_mult+"]");        // Nov-15-2004 was 20        // Nov-29-2004 was 10        code += s_sum * s_mult * 20;         code += j_sum * j_mult * 20;        FusionInfo child0 = childConfig(0).getFusionInfo();        // removed Nov-15-2004        //data += s_sum * s_mult * child0.getInputSize() * 2;         //data += j_sum * j_mult * child0.getOutputSize() * 2;         for (int i = 0; i < cont.size(); i++) {            CConfig child = childConfig(i);            FusionInfo fi = child.getFusionInfo();                    work += fi.getWorkEstimate();            work_no_penalty += fi.getWorkEstimateNoPenalty();            code += fi.getCodeSize() * fmult[i];            data += fi.getDataSize(); // * fmult[i]; // removed Nov-15-2004            //data += fi.getInputSize() * fi.getPopInt() * fmult[i] +             //fi.getOutputSize() * fi.getPushInt() * fmult[i];                    // add impossible unroll penalty            if (KjcOptions.unroll < fmult[i]) {                work += fi.getWorkEstimate()/2;            }            //If peek ratio is 1024 add fusion peek overhead            // unless the splitter is duplicate, since            // then peek buffer can be reused!            boolean duplicate = split_join.getSplitter().getType().isDuplicate();            if (KjcOptions.peekratio >= 1024) {                 if (child.getPeek()) {                    if (!duplicate || cont.size() > 2) {                        //System.out.println("Round Robin Splitter: Channel peek!");                                    work += 1000;                    } else {                        sj_peek = true;                    }                            }            }        }        int pop = split_join.getSplitter().getSumOfWeights()*s_mult;        if (split_join.getSplitter().getType().isDuplicate()) {            pop = s_mult;        }        int push = split_join.getJoiner().getSumOfWeights()*j_mult;        //System.out.println("Fused SplitJoin Pop: "+pop+" Push: "+push);         fusion_info =             new FusionInfo(work, work_no_penalty, code, data,                           pop,                           pop,                           push,                           child0.getInputSize(),                           child0.getOutputSize());         return fusion_info;    }