private int recombine_partitions() { int result = 0; int last_cut = -1; int curr_cut = 0; for (curr_cut = 0; curr_cut < cont.size() - 2; curr_cut++) { if (greedyCuts[curr_cut]) { break; } } for (int i = curr_cut + 1; i < cont.size() - 2; i++) { if (greedyCuts[i]) { // last_cut + 1 ... curr_cut // curr_cut + 1 ... i FusionInfo f_all = getFusionInfo(last_cut + 1, i); if (f_all.getCost().getCost() <= f_all.getWorkEstimateNoPenalty() && !does_peek(curr_cut + 1)) { greedyCuts[curr_cut] = false; // System.out.println("recombining adjacent partitions!"); // System.out.println("recomb: ["+(last_cut+1)+ // ","+curr_cut+","+i+"]"); curr_cut = i; result--; } else { last_cut = curr_cut; curr_cut = i; } } } FusionInfo f_all = getFusionInfo(last_cut + 1, cont.size() - 1); if (f_all.getCost().getCost() <= f_all.getWorkEstimateNoPenalty() && !does_peek(curr_cut + 1)) { greedyCuts[curr_cut] = false; // System.out.println("recombining adjacent partitions!"); // System.out.println("recomb: ["+(last_cut+1)+ // ","+curr_cut+","+(cont.size()-1)+"]"); result--; } return result; }
public FusionInfo getFusionInfo(int from, int to) { // check if we have precomputed if (fusion_info[from][to] != null) return fusion_info[from][to]; long work = 0; long work_no_penalty = 0; int code = 0; int data = 0; int mult[] = new int[cont.size()]; mult[from] = 1; // init mult. of first item to 1 for (int i = from; i < to; i++) { int push = childConfig(i).getFusionInfo().getPushInt() * mult[i]; int pop = childConfig(i + 1).getFusionInfo().getPopInt(); int common = gcd(push, pop); int xtra = pop / common; if (xtra > 1) { for (int a = from; a <= i; a++) { mult[a] = mult[a] * xtra; } } mult[i + 1] = (push * xtra) / pop; } for (int i = from; i <= to; i++) { CConfig child = childConfig(i); FusionInfo fi = child.getFusionInfo(); work += fi.getWorkEstimate(); work_no_penalty += fi.getWorkEstimateNoPenalty(); code += fi.getCodeSize() * mult[i]; data += fi.getDataSize(); // * mult[i]; // removed Nov-15-2004 // removed Nov-15-2004 // if (i < to) data += fi.getOutputSize() * fi.getPushInt() * mult[i] * 2; // add impossible unroll penalty if (KjcOptions.unroll < mult[i]) work += fi.getWorkEstimate() / 2; // If peek ratio is 1024 add fusion peek overhead! if (KjcOptions.peekratio >= 1024) { if (i > from && child instanceof CConfigFilter) { CConfigFilter fc = (CConfigFilter) child; SIRFilter filter = (SIRFilter) fc.getStream(); int f_pop = filter.getPopInt(); int f_peek = filter.getPeekInt(); int f_extra = f_peek - f_pop; if (f_extra > 0) { // peek > pop // only penalize if peek rate < 25% of (peek-pop) // System.out.print("[ extra:"+f_extra+"("+(f_pop * mult[i] * 4)+") pop:"+f_pop+" // m:"+mult[i]+" ]"); if (f_extra > f_pop * mult[i] * 4) { // work += fi.getWorkEstimate()/2; // work += 1500; // System.out.print("penalty!!"); } // System.out.println(); } } if (i > from && child instanceof CConfigSplitJoin) { CConfigSplitJoin sj = (CConfigSplitJoin) child; if (sj.getPeek()) { // work += fi.getWorkEstimate()/2; // work += 1500; } } } } int to_push = childConfig(to).getFusionInfo().getPushInt(); int from_pop = childConfig(from).getFusionInfo().getPopInt(); int from_peek = childConfig(from).getFusionInfo().getPeekInt(); fusion_info[from][to] = new FusionInfo( work, work_no_penalty, code, data, from_pop * mult[from], from_pop * mult[from] + (from_peek - from_pop), to_push * mult[to], childConfig(from).getFusionInfo().getInputSize(), childConfig(to).getFusionInfo().getOutputSize()); return fusion_info[from][to]; }
private int numberOfTiles(int from, int to) { // System.out.println("Pipeline.numberOfTiles("+from+","+to+")"); if (from > to) return 0; if (from == to) return childConfig(from).numberOfTiles(); for (int i = from; i <= to; i++) { int child_tiles = childConfig(i).numberOfTiles(); if (child_tiles > 1) { int left = numberOfTiles(from, i - 1); int right = numberOfTiles(i + 1, to); if (i > 0) greedyCuts[i - 1] = true; if (i < cont.size() - 1) greedyCuts[i] = true; return left + child_tiles + right; } } // all children fit into one tile each // first try fusing everything FusionInfo f_all = getFusionInfo(from, to); // System.out.println("try one tile // ["+f_all.getCost().getCost()+","+f_all.getWorkEstimateNoPenalty()+"]"); if (f_all.getCost().getCost() <= f_all.getWorkEstimateNoPenalty()) { // System.out.println("pipeline segnemt fits into one tile!"); return 1; } // find multiplicity of filters int mult[] = new int[cont.size()]; mult[from] = 1; // init mult. of first item to 1 for (int i = from; i < to; i++) { int push = childConfig(i).getFusionInfo().getPushInt() * mult[i]; int pop = childConfig(i + 1).getFusionInfo().getPopInt(); int common = gcd(push, pop); int xtra = pop / common; if (xtra > 1) { for (int a = from; a <= i; a++) { mult[a] = mult[a] * xtra; } } mult[i + 1] = (push * xtra) / pop; } // find max bandwidth connection int max_size = 0; int max_loc = 0; for (int i = from; i < to; i++) { int size = childConfig(i).getFusionInfo().getPushInt() * mult[i]; if (size > max_size) { max_size = size; max_loc = i; } } // System.out.println("max_size: "+max_size+" max_loc: "+max_loc); int f_start = max_loc; int f_end = max_loc + 1; FusionInfo _fi = getFusionInfo(f_start, f_end); if (_fi.getCost().getCost() > _fi.getWorkEstimateNoPenalty()) { // can not fuse f_start and f_end // make cut between f_start and f_end int left = numberOfTiles(from, f_start); int right = numberOfTiles(f_end, to); greedyCuts[f_start] = true; return left + right; } // fuse up and down starting with (max_loc, max_loc + 1) while cant fuse boolean can_fuse_up = true, can_fuse_down = true; for (; ; ) { // check if still can fuse up if (can_fuse_up) { if (f_start == from) { can_fuse_up = false; } else { FusionInfo fi = getFusionInfo(f_start - 1, f_end); if (fi.getCost().getCost() > fi.getWorkEstimateNoPenalty()) { can_fuse_up = false; } } } // check if still can fuse down if (can_fuse_down) { if (f_end == to) { can_fuse_down = false; } else { FusionInfo fi = getFusionInfo(f_start, f_end + 1); if (fi.getCost().getCost() > fi.getWorkEstimateNoPenalty()) { can_fuse_down = false; } } } if (can_fuse_up && can_fuse_down) { f_start -= 1; } if (can_fuse_up && !can_fuse_down) { f_start -= 1; } if (!can_fuse_up && can_fuse_down) { f_end += 1; } if (!can_fuse_up && !can_fuse_down) { // System.out.println("done fusing ["+f_start+","+f_end+"]"); int left = numberOfTiles(from, f_start - 1); int right = numberOfTiles(f_end + 1, to); if (f_start > 0) greedyCuts[f_start - 1] = true; if (f_end < cont.size() - 1) greedyCuts[f_end] = true; return left + right + 1; } } }