use of org.apache.sysml.runtime.controlprogram.ProgramBlock in project incubator-systemml by apache.
the class ResourceOptimizer method optimizeResourceConfig.
public static synchronized ResourceConfig optimizeResourceConfig(ArrayList<ProgramBlock> prog, YarnClusterConfig cc, GridEnumType cptype, GridEnumType mrtype) {
ResourceConfig ROpt = null;
try {
// init statistics and counters
Timing time = new Timing(true);
initStatistics();
// get constraints (yarn-specific: force higher min to limit degree of parallelism)
long max = (long) (YarnOptimizerUtils.toB(cc.getMaxAllocationMB()) / DMLYarnClient.MEM_FACTOR);
long minCP = (long) Math.max(YarnOptimizerUtils.toB(cc.getMinAllocationMB()) / DMLYarnClient.MEM_FACTOR, MIN_CP_BUDGET);
long minMR = YarnOptimizerUtils.computeMinContraint(minCP, max, cc.getAvgNumCores());
// enumerate grid points for given types (refers to jvm max heap)
ArrayList<Long> SRc = enumerateGridPoints(prog, minCP, max, cptype);
ArrayList<Long> SRm = enumerateGridPoints(prog, minMR, max, mrtype);
// init resource config and global costs
ROpt = new ResourceConfig(prog, minMR);
double costOpt = Double.MAX_VALUE;
for (// enumerate CP memory rc
Long rc : // enumerate CP memory rc
SRc) {
// baseline compile and pruning
// unrolled Bp
ArrayList<ProgramBlock> B = compileProgram(prog, null, rc, minMR);
ArrayList<ProgramBlock> Bp = pruneProgramBlocks(B);
LOG.debug("Enum (rc=" + rc + "): |B|=" + B.size() + ", |Bp|=" + Bp.size());
// init local memo table [resource, cost]
double[][] memo = initLocalMemoTable(Bp, minMR);
for (// for all relevant blocks
int i = 0; // for all relevant blocks
i < Bp.size(); // for all relevant blocks
i++) {
ProgramBlock pb = Bp.get(i);
for (// for each MR memory
Long rm : // for each MR memory
SRm) {
// recompile program block
recompileProgramBlock(pb, rc, rm);
// local costing and memo table maintenance (cost entire program to account for
// in-memory status of variables and loops)
double lcost = getProgramCosts(pb);
if (lcost < memo[i][1]) {
// accept new local opt
memo[i][0] = rm;
memo[i][1] = lcost;
// LOG.debug("Enum (rc="+rc+"): found new local opt w/ cost="+lcost);
}
// LOG.debug("Enum (rc="+rc+", rm="+rm+"): lcost="+lcost+", mincost="+memo[i][1]);
}
}
// global costing
double[][] gmemo = initGlobalMemoTable(B, Bp, memo, minMR);
recompileProgramBlocks(B, rc, gmemo);
double gcost = getProgramCosts(B.get(0).getProgram());
if (gcost < costOpt) {
// accept new global opt
ROpt.setCPResource(rc.longValue());
ROpt.setMRResources(B, gmemo);
costOpt = gcost;
LOG.debug("Enum (rc=" + rc + "): found new opt w/ cost=" + gcost);
}
}
// print optimization summary
LOG.info("Optimization summary:");
LOG.info("-- optimal plan (rc, rm): " + YarnOptimizerUtils.toMB(ROpt.getCPResource()) + "MB, " + YarnOptimizerUtils.toMB(ROpt.getMaxMRResource()) + "MB");
LOG.info("-- costs of optimal plan: " + costOpt);
LOG.info("-- # of block compiles: " + _cntCompilePB);
LOG.info("-- # of block costings: " + _cntCostPB);
LOG.info("-- optimization time: " + String.format("%.3f", (double) time.stop() / 1000) + " sec.");
LOG.info("-- optimal plan details: " + ROpt.serialize());
} catch (Exception ex) {
throw new DMLRuntimeException(ex);
}
return ROpt;
}
use of org.apache.sysml.runtime.controlprogram.ProgramBlock in project incubator-systemml by apache.
the class ResourceOptimizer method initLocalMemoTable.
private static double[][] initLocalMemoTable(ArrayList<ProgramBlock> Bp, double min) {
// allocate memo structure
int len = Bp.size();
double[][] memo = new double[len][2];
// init with min resource and current costs
for (int i = 0; i < len; i++) {
ProgramBlock pb = Bp.get(i);
ExecutionContext ec = ExecutionContextFactory.createContext();
memo[i][0] = min;
memo[i][1] = CostEstimationWrapper.getTimeEstimate(pb.getProgram(), ec);
}
return memo;
}
use of org.apache.sysml.runtime.controlprogram.ProgramBlock in project incubator-systemml by apache.
the class DMLTranslator method createRuntimeProgramBlock.
public ProgramBlock createRuntimeProgramBlock(Program prog, StatementBlock sb, DMLConfig config) {
Dag<Lop> dag = null;
Dag<Lop> pred_dag = null;
ArrayList<Instruction> instruct;
ArrayList<Instruction> pred_instruct = null;
ProgramBlock retPB = null;
// process While Statement - add runtime program blocks to program
if (sb instanceof WhileStatementBlock) {
// create DAG for loop predicates
pred_dag = new Dag<>();
((WhileStatementBlock) sb).get_predicateLops().addToDag(pred_dag);
// create instructions for loop predicates
pred_instruct = new ArrayList<>();
ArrayList<Instruction> pInst = pred_dag.getJobs(null, config);
for (Instruction i : pInst) {
pred_instruct.add(i);
}
// create while program block
WhileProgramBlock rtpb = new WhileProgramBlock(prog, pred_instruct);
// // process the body of the while statement block ////
WhileStatementBlock wsb = (WhileStatementBlock) sb;
WhileStatement wstmt = (WhileStatement) wsb.getStatement(0);
for (StatementBlock sblock : wstmt.getBody()) {
// process the body
ProgramBlock childBlock = createRuntimeProgramBlock(prog, sblock, config);
rtpb.addProgramBlock(childBlock);
}
retPB = rtpb;
// add statement block
retPB.setStatementBlock(sb);
// add location information
retPB.setParseInfo(sb);
} else // process If Statement - add runtime program blocks to program
if (sb instanceof IfStatementBlock) {
// create DAG for loop predicates
pred_dag = new Dag<>();
((IfStatementBlock) sb).get_predicateLops().addToDag(pred_dag);
// create instructions for loop predicates
pred_instruct = new ArrayList<>();
ArrayList<Instruction> pInst = pred_dag.getJobs(null, config);
for (Instruction i : pInst) {
pred_instruct.add(i);
}
// create if program block
IfProgramBlock rtpb = new IfProgramBlock(prog, pred_instruct);
// process the body of the if statement block
IfStatementBlock isb = (IfStatementBlock) sb;
IfStatement istmt = (IfStatement) isb.getStatement(0);
// process the if body
for (StatementBlock sblock : istmt.getIfBody()) {
ProgramBlock childBlock = createRuntimeProgramBlock(prog, sblock, config);
rtpb.addProgramBlockIfBody(childBlock);
}
// process the else body
for (StatementBlock sblock : istmt.getElseBody()) {
ProgramBlock childBlock = createRuntimeProgramBlock(prog, sblock, config);
rtpb.addProgramBlockElseBody(childBlock);
}
retPB = rtpb;
// post processing for generating missing instructions
// retPB = verifyAndCorrectProgramBlock(sb.liveIn(), sb.liveOut(), sb._kill, retPB);
// add statement block
retPB.setStatementBlock(sb);
// add location information
retPB.setParseInfo(sb);
} else // NOTE: applies to ForStatementBlock and ParForStatementBlock
if (sb instanceof ForStatementBlock) {
ForStatementBlock fsb = (ForStatementBlock) sb;
// create DAGs for loop predicates
Dag<Lop> fromDag = new Dag<>();
Dag<Lop> toDag = new Dag<>();
Dag<Lop> incrementDag = new Dag<>();
if (fsb.getFromHops() != null)
fsb.getFromLops().addToDag(fromDag);
if (fsb.getToHops() != null)
fsb.getToLops().addToDag(toDag);
if (fsb.getIncrementHops() != null)
fsb.getIncrementLops().addToDag(incrementDag);
// create instructions for loop predicates
ArrayList<Instruction> fromInstructions = fromDag.getJobs(null, config);
ArrayList<Instruction> toInstructions = toDag.getJobs(null, config);
ArrayList<Instruction> incrementInstructions = incrementDag.getJobs(null, config);
// create for program block
ForProgramBlock rtpb = null;
IterablePredicate iterPred = fsb.getIterPredicate();
if (sb instanceof ParForStatementBlock && ConfigurationManager.isParallelParFor()) {
rtpb = new ParForProgramBlock(prog, iterPred.getIterVar().getName(), iterPred.getParForParams(), ((ParForStatementBlock) sb).getResultVariables());
ParForProgramBlock pfrtpb = (ParForProgramBlock) rtpb;
// used for optimization and creating unscoped variables
pfrtpb.setStatementBlock((ParForStatementBlock) sb);
} else {
// ForStatementBlock
rtpb = new ForProgramBlock(prog, iterPred.getIterVar().getName());
}
rtpb.setFromInstructions(fromInstructions);
rtpb.setToInstructions(toInstructions);
rtpb.setIncrementInstructions(incrementInstructions);
// process the body of the for statement block
ForStatement fs = (ForStatement) fsb.getStatement(0);
for (StatementBlock sblock : fs.getBody()) {
ProgramBlock childBlock = createRuntimeProgramBlock(prog, sblock, config);
rtpb.addProgramBlock(childBlock);
}
retPB = rtpb;
// add statement block
retPB.setStatementBlock(sb);
// add location information
retPB.setParseInfo(sb);
} else // process function statement block - add runtime program blocks to program
if (sb instanceof FunctionStatementBlock) {
FunctionStatementBlock fsb = (FunctionStatementBlock) sb;
FunctionStatement fstmt = (FunctionStatement) fsb.getStatement(0);
FunctionProgramBlock rtpb = null;
if (fstmt instanceof ExternalFunctionStatement) {
// create external function program block
String execType = ((ExternalFunctionStatement) fstmt).getOtherParams().get(ExternalFunctionStatement.EXEC_TYPE);
boolean isCP = (execType.equals(ExternalFunctionStatement.IN_MEMORY)) ? true : false;
StringBuilder buff = new StringBuilder();
buff.append(config.getTextValue(DMLConfig.SCRATCH_SPACE));
buff.append(Lop.FILE_SEPARATOR);
buff.append(Lop.PROCESS_PREFIX);
buff.append(DMLScript.getUUID());
buff.append(Lop.FILE_SEPARATOR);
buff.append(ProgramConverter.CP_ROOT_THREAD_ID);
buff.append(Lop.FILE_SEPARATOR);
buff.append("PackageSupport");
buff.append(Lop.FILE_SEPARATOR);
String basedir = buff.toString();
if (isCP) {
rtpb = new ExternalFunctionProgramBlockCP(prog, fstmt.getInputParams(), fstmt.getOutputParams(), ((ExternalFunctionStatement) fstmt).getOtherParams(), basedir);
} else {
rtpb = new ExternalFunctionProgramBlock(prog, fstmt.getInputParams(), fstmt.getOutputParams(), ((ExternalFunctionStatement) fstmt).getOtherParams(), basedir);
}
if (!fstmt.getBody().isEmpty()) {
LOG.error(fstmt.printErrorLocation() + "ExternalFunctionStatementBlock should have no statement blocks in body");
throw new LopsException(fstmt.printErrorLocation() + "ExternalFunctionStatementBlock should have no statement blocks in body");
}
} else {
// create function program block
rtpb = new FunctionProgramBlock(prog, fstmt.getInputParams(), fstmt.getOutputParams());
// process the function statement body
for (StatementBlock sblock : fstmt.getBody()) {
// process the body
ProgramBlock childBlock = createRuntimeProgramBlock(prog, sblock, config);
rtpb.addProgramBlock(childBlock);
}
}
// check there are actually Lops in to process (loop stmt body will not have any)
if (fsb.getLops() != null && !fsb.getLops().isEmpty()) {
LOG.error(fsb.printBlockErrorLocation() + "FunctionStatementBlock should have no Lops");
throw new LopsException(fsb.printBlockErrorLocation() + "FunctionStatementBlock should have no Lops");
}
retPB = rtpb;
// add location information
retPB.setParseInfo(sb);
} else {
// handle general case
ProgramBlock rtpb = new ProgramBlock(prog);
// DAGs for Lops
dag = new Dag<>();
// check there are actually Lops in to process (loop stmt body will not have any)
if (sb.getLops() != null && !sb.getLops().isEmpty()) {
for (Lop l : sb.getLops()) {
l.addToDag(dag);
}
// Instructions for Lops DAGs
instruct = dag.getJobs(sb, config);
rtpb.addInstructions(instruct);
}
retPB = rtpb;
// post processing for generating missing instructions
// retPB = verifyAndCorrectProgramBlock(sb.liveIn(), sb.liveOut(), sb._kill, retPB);
// add statement block
retPB.setStatementBlock(sb);
// add location information
retPB.setParseInfo(sb);
}
return retPB;
}
use of org.apache.sysml.runtime.controlprogram.ProgramBlock in project incubator-systemml by apache.
the class JMLCUtils method cleanupRuntimeProgram.
/**
* Removes rmvar instructions that would remove any of the given outputs.
* This is important for keeping registered outputs after the program terminates.
*
* @param prog the DML/PyDML program
* @param outputs registered output variables
*/
public static void cleanupRuntimeProgram(Program prog, String[] outputs) {
Map<String, FunctionProgramBlock> funcMap = prog.getFunctionProgramBlocks();
HashSet<String> blacklist = new HashSet<>(Arrays.asList(outputs));
if (funcMap != null && !funcMap.isEmpty()) {
for (Entry<String, FunctionProgramBlock> e : funcMap.entrySet()) {
FunctionProgramBlock fpb = e.getValue();
for (ProgramBlock pb : fpb.getChildBlocks()) rCleanupRuntimeProgram(pb, blacklist);
}
}
for (ProgramBlock pb : prog.getProgramBlocks()) rCleanupRuntimeProgram(pb, blacklist);
}
use of org.apache.sysml.runtime.controlprogram.ProgramBlock in project incubator-systemml by apache.
the class MLContextUtil method deleteRemoveVariableInstructions.
/**
* Recursively traverse program block to delete 'remove variable'
* instructions.
*
* @param pb
* Program block
*/
private static void deleteRemoveVariableInstructions(ProgramBlock pb) {
if (pb instanceof WhileProgramBlock) {
WhileProgramBlock wpb = (WhileProgramBlock) pb;
for (ProgramBlock pbc : wpb.getChildBlocks()) deleteRemoveVariableInstructions(pbc);
} else if (pb instanceof IfProgramBlock) {
IfProgramBlock ipb = (IfProgramBlock) pb;
for (ProgramBlock pbc : ipb.getChildBlocksIfBody()) deleteRemoveVariableInstructions(pbc);
for (ProgramBlock pbc : ipb.getChildBlocksElseBody()) deleteRemoveVariableInstructions(pbc);
} else if (pb instanceof ForProgramBlock) {
ForProgramBlock fpb = (ForProgramBlock) pb;
for (ProgramBlock pbc : fpb.getChildBlocks()) deleteRemoveVariableInstructions(pbc);
} else {
ArrayList<Instruction> instructions = pb.getInstructions();
deleteRemoveVariableInstructions(instructions);
}
}
Aggregations