/** * This static method creates the main function as described in the class comment. It first checks * that the filter has no inputs/outputs and does not declare any I/O rates Then it creates the * function and attaches it to the filter. * * @param top The single flatnode that contains the single filter of the app. * @param executionCounts The schedule for the stream graph as calculated by the scheduler. */ public static void doit(FlatNode top, HashMap[] executionCounts) { assert top.contents instanceof SIRFilter : "Error top of graph is not filter"; assert top.inputs == 0 && top.ways == 0 : "Error: Fused filter contains neighbors"; SIRFilter filter = (SIRFilter) top.contents; assert filter.getPushInt() == 0 && filter.getPopInt() == 0 && filter.getPeekInt() == 0 : "Error: fused filter declares non-zero I/O rate(s)"; // make sure there are no push, pops or peeks... assert CheckForCommunication.check(filter) == false : "Error: Communication expression found in filter"; // assert !(filter instanceof SIRTwoStageFilter) : // "Error: Fused filter is a two stage"; ExecutionCode exeCode = new ExecutionCode(); // check to see if the schedule is valid and // set the number of times the filter fires in the init // stage (weird) exeCode.checkSchedule(executionCounts, filter); // create the main function of the C code that will call // the filter JBlock block = exeCode.mainFunction(filter); // create the method and add it to the filter JMethodDeclaration mainFunct = new JMethodDeclaration( null, at.dms.kjc.Constants.ACC_PUBLIC, CStdType.Void, Names.main, JFormalParameter.EMPTY, CClassType.EMPTY, block, null, null); // make the main the new work function filter.setWork(mainFunct); }
/** * generate the code for the steady state loop. Inline the work function inside of an infinite * while loop. * * @param filter The single fused filter of the application. * @return A JStatement that is a while loop with the work function inlined. */ JStatement generateSteadyStateLoop(SIRFilter filter) { JBlock block = new JBlock(null, new JStatement[0], null); JBlock workBlock = (JBlock) ObjectDeepCloner.deepCopy(filter.getWork().getBody()); // add the cloned work function to the block block.addStatement(workBlock); // return the infinite loop return new JWhileStatement(null, new JBooleanLiteral(null, true), block, null); }
private boolean does_peek(int index) { CConfig child = childConfig(index); if (child instanceof CConfigFilter) { CConfigFilter fc = (CConfigFilter) child; SIRFilter filter = (SIRFilter) fc.getStream(); int f_pop = filter.getPopInt(); int f_peek = filter.getPeekInt(); if (f_peek > f_pop) return true; } if (child instanceof CConfigSplitJoin) { CConfigSplitJoin sj = (CConfigSplitJoin) child; if (sj.getPeek()) { return true; } } return false; }
/** * Construct the main function. * * @param filter The single SIRFilter of the application. * @return A JBlock with the statements of the main function. */ private JBlock mainFunction(SIRFilter filter) { JBlock statements = new JBlock(null, new JStatement[0], null); // create the params list, for some reason // calling toArray() on the list breaks a later pass List paramList = filter.getParams(); JExpression[] paramArray; if (paramList == null || paramList.size() == 0) paramArray = new JExpression[0]; else paramArray = (JExpression[]) paramList.toArray(new JExpression[0]); // add the call to the init function statements.addStatement( new JExpressionStatement( null, new JMethodCallExpression( null, new JThisExpression(null), filter.getInit().getName(), paramArray), null)); // add the call to the pre(init)work function if this filter // is a two stage.. if (filter instanceof SIRTwoStageFilter) { SIRTwoStageFilter two = (SIRTwoStageFilter) filter; statements.addStatement( new JExpressionStatement( null, new JMethodCallExpression( null, new JThisExpression(null), two.getInitWork().getName(), new JExpression[0]), null)); } // add the call to the work function statements.addStatement(generateSteadyStateLoop(filter)); return statements; }
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 refactor(int from, int to) { // System.out.println("refactor from:"+from+" to:"+to); int new_cuts = 0; // 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; } for (int i = from + 1; i <= to; i++) { CConfig child = childConfig(i); // If peek ratio is 1024 -- try to refactor partition if (KjcOptions.peekratio >= 1024 && 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 // double amortize_break = f_extra / ClusterBackend.getExecCounts(filter); // double amortize_fuse = f_extra / mult[i]; // System.out.print("[refactor extra:"+f_extra+"("+(f_pop * mult[i] * 4)+") pop:"+f_pop+" // m:"+mult[i]+" ]"); // break if peek rate < 25% of (peek-pop) // if (f_extra > f_pop * mult[i] * 4) { // System.out.print("Cutting partition!!"); greedyCuts[i - 1] = true; new_cuts++; // } /* else if (amortize_break * 2 < amortize_fuse) { // break if amortize_break * 2 < amortize_fuse //System.out.print("Cutting partition!!"); greedyCuts[i-1] = true; new_cuts++; } */ // System.out.println(); } } if (i > from && child instanceof CConfigSplitJoin) { CConfigSplitJoin sj = (CConfigSplitJoin) child; if (sj.getPeek()) { // System.out.print("Cutting partition!!"); greedyCuts[i - 1] = true; new_cuts++; // work += fi.getWorkEstimate()/2; // work += 1500; } } } return new_cuts; }