use of org.apache.sysml.hops.MemoTable in project incubator-systemml by apache.
the class Recompiler method recompileHopsDag.
/**
* A) Recompile basic program block hop DAG.
*
* We support to basic types inplace or via deep copy. Deep copy is the default and is required
* in order to apply non-reversible rewrites. In-place is required in order to modify the existing
* hops (e.g., for parfor pre-recompilation).
*
* @param sb statement block
* @param hops high-level operators
* @param vars local variable map
* @param status the recompile status
* @param inplace true if in place
* @param litreplace true if literal replacement
* @param tid thread id
* @return list of instructions
* @throws DMLRuntimeException if DMLRuntimeException occurs
* @throws HopsException if HopsException occurs
* @throws LopsException if LopsException occurs
* @throws IOException if IOException occurs
*/
public static ArrayList<Instruction> recompileHopsDag(StatementBlock sb, ArrayList<Hop> hops, LocalVariableMap vars, RecompileStatus status, boolean inplace, boolean litreplace, long tid) throws DMLRuntimeException, HopsException, LopsException, IOException {
ArrayList<Instruction> newInst = null;
//however, we create deep copies for most dags to allow for concurrent recompile
synchronized (hops) {
LOG.debug("\n**************** Optimizer (Recompile) *************\nMemory Budget = " + OptimizerUtils.toMB(OptimizerUtils.getLocalMemBudget()) + " MB");
// prepare hops dag for recompile
if (!inplace) {
// deep copy hop dag (for non-reversable rewrites)
hops = deepCopyHopsDag(hops);
} else {
// clear existing lops
Hop.resetVisitStatus(hops);
for (Hop hopRoot : hops) rClearLops(hopRoot);
}
// replace scalar reads with literals
if (!inplace && litreplace) {
Hop.resetVisitStatus(hops);
for (Hop hopRoot : hops) rReplaceLiterals(hopRoot, vars, false);
}
// refresh matrix characteristics (update stats)
Hop.resetVisitStatus(hops);
for (Hop hopRoot : hops) rUpdateStatistics(hopRoot, vars);
// dynamic hop rewrites
if (!inplace) {
_rewriter.get().rewriteHopDAGs(hops, null);
//update stats after rewrites
Hop.resetVisitStatus(hops);
for (Hop hopRoot : hops) rUpdateStatistics(hopRoot, vars);
}
// refresh memory estimates (based on updated stats,
// before: init memo table with propagated worst-case estimates,
// after: extract worst-case estimates from memo table
Hop.resetVisitStatus(hops);
MemoTable memo = new MemoTable();
memo.init(hops, status);
Hop.resetVisitStatus(hops);
for (Hop hopRoot : hops) hopRoot.refreshMemEstimates(memo);
memo.extract(hops, status);
// codegen if enabled
if (ConfigurationManager.getDMLConfig().getBooleanValue(DMLConfig.CODEGEN) && SpoofCompiler.RECOMPILE_CODEGEN) {
Hop.resetVisitStatus(hops);
hops = SpoofCompiler.optimize(hops, true);
}
// construct lops
Dag<Lop> dag = new Dag<Lop>();
for (Hop hopRoot : hops) {
Lop lops = hopRoot.constructLops();
lops.addToDag(dag);
}
// generate runtime instructions (incl piggybacking)
newInst = dag.getJobs(sb, ConfigurationManager.getDMLConfig());
}
// replace thread ids in new instructions
if (//only in parfor context
tid != 0)
newInst = ProgramConverter.createDeepCopyInstructionSet(newInst, tid, -1, null, null, null, false, false);
// explain recompiled hops / instructions
if (DMLScript.EXPLAIN == ExplainType.RECOMPILE_HOPS) {
LOG.info("EXPLAIN RECOMPILE \nGENERIC (lines " + sb.getBeginLine() + "-" + sb.getEndLine() + "):\n" + Explain.explainHops(hops, 1));
}
if (DMLScript.EXPLAIN == ExplainType.RECOMPILE_RUNTIME) {
LOG.info("EXPLAIN RECOMPILE \nGENERIC (lines " + sb.getBeginLine() + "-" + sb.getEndLine() + "):\n" + Explain.explain(newInst, 1));
}
return newInst;
}
use of org.apache.sysml.hops.MemoTable in project incubator-systemml by apache.
the class Recompiler method recompileHopsDag.
/**
* B) Recompile predicate hop DAG (single root):
*
* Note: This overloaded method is required for predicate instructions because
* they have only a single hops DAG and we need to synchronize on the original
* (shared) hops object. Hence, we cannot create any wrapper arraylist for each
* recompilation - this would result in race conditions for concurrent recompilation
* in a parfor body.
*
* Note: no statementblock passed because for predicate dags we dont have separate live variable analysis information.
*
* @param hops high-level operator
* @param vars local variable map
* @param status recompile status
* @param inplace true if in place
* @param litreplace true if literal replacement
* @param tid thread id
* @return list of instructions
* @throws DMLRuntimeException if DMLRuntimeException occurs
* @throws HopsException if HopsException occurs
* @throws LopsException if LopsException occurs
* @throws IOException if IOException occurs
*/
public static ArrayList<Instruction> recompileHopsDag(Hop hops, LocalVariableMap vars, RecompileStatus status, boolean inplace, boolean litreplace, long tid) throws DMLRuntimeException, HopsException, LopsException, IOException {
ArrayList<Instruction> newInst = null;
//need for synchronization as we do temp changes in shared hops/lops
synchronized (hops) {
LOG.debug("\n**************** Optimizer (Recompile) *************\nMemory Budget = " + OptimizerUtils.toMB(OptimizerUtils.getLocalMemBudget()) + " MB");
// prepare hops dag for recompile
if (!inplace) {
// deep copy hop dag (for non-reversable rewrites)
//(this also clears existing lops in the created dag)
hops = deepCopyHopsDag(hops);
} else {
// clear existing lops
hops.resetVisitStatus();
rClearLops(hops);
}
// replace scalar reads with literals
if (!inplace && litreplace) {
hops.resetVisitStatus();
rReplaceLiterals(hops, vars, false);
}
// refresh matrix characteristics (update stats)
hops.resetVisitStatus();
rUpdateStatistics(hops, vars);
// dynamic hop rewrites
if (!inplace) {
_rewriter.get().rewriteHopDAG(hops, null);
//update stats after rewrites
hops.resetVisitStatus();
rUpdateStatistics(hops, vars);
}
// refresh memory estimates (based on updated stats)
MemoTable memo = new MemoTable();
hops.resetVisitStatus();
memo.init(hops, status);
hops.resetVisitStatus();
hops.refreshMemEstimates(memo);
// codegen if enabled
if (ConfigurationManager.getDMLConfig().getBooleanValue(DMLConfig.CODEGEN) && SpoofCompiler.RECOMPILE_CODEGEN) {
hops.resetVisitStatus();
hops = SpoofCompiler.optimize(hops, false);
}
// construct lops
Dag<Lop> dag = new Dag<Lop>();
Lop lops = hops.constructLops();
lops.addToDag(dag);
// generate runtime instructions (incl piggybacking)
newInst = dag.getJobs(null, ConfigurationManager.getDMLConfig());
}
// replace thread ids in new instructions
if (//only in parfor context
tid != 0)
newInst = ProgramConverter.createDeepCopyInstructionSet(newInst, tid, -1, null, null, null, false, false);
// explain recompiled instructions
if (DMLScript.EXPLAIN == ExplainType.RECOMPILE_HOPS)
LOG.info("EXPLAIN RECOMPILE \nPRED (line " + hops.getBeginLine() + "):\n" + Explain.explain(hops, 1));
if (DMLScript.EXPLAIN == ExplainType.RECOMPILE_RUNTIME)
LOG.info("EXPLAIN RECOMPILE \nPRED (line " + hops.getBeginLine() + "):\n" + Explain.explain(newInst, 1));
return newInst;
}
use of org.apache.sysml.hops.MemoTable in project systemml by apache.
the class DMLTranslator method refreshMemEstimates.
public void refreshMemEstimates(StatementBlock current) {
MemoTable memo = new MemoTable();
if (HopRewriteUtils.isLastLevelStatementBlock(current)) {
ArrayList<Hop> hopsDAG = current.getHops();
if (hopsDAG != null && !hopsDAG.isEmpty())
for (Hop hop : hopsDAG) hop.refreshMemEstimates(memo);
}
if (current instanceof FunctionStatementBlock) {
FunctionStatement fstmt = (FunctionStatement) current.getStatement(0);
for (StatementBlock sb : fstmt.getBody()) {
refreshMemEstimates(sb);
}
} else if (current instanceof WhileStatementBlock) {
// handle predicate
WhileStatementBlock wstb = (WhileStatementBlock) current;
wstb.getPredicateHops().refreshMemEstimates(new MemoTable());
if (wstb.getNumStatements() > 1)
LOG.debug("While statement block has more than 1 stmt");
WhileStatement ws = (WhileStatement) wstb.getStatement(0);
for (StatementBlock sb : ws.getBody()) {
refreshMemEstimates(sb);
}
} else if (current instanceof IfStatementBlock) {
// handle predicate
IfStatementBlock istb = (IfStatementBlock) current;
istb.getPredicateHops().refreshMemEstimates(new MemoTable());
if (istb.getNumStatements() > 1)
LOG.debug("If statement block has more than 1 stmt");
IfStatement is = (IfStatement) istb.getStatement(0);
for (StatementBlock sb : is.getIfBody()) {
refreshMemEstimates(sb);
}
for (StatementBlock sb : is.getElseBody()) {
refreshMemEstimates(sb);
}
} else if (current instanceof ForStatementBlock) {
// handle predicate
ForStatementBlock fsb = (ForStatementBlock) current;
if (fsb.getFromHops() != null)
fsb.getFromHops().refreshMemEstimates(new MemoTable());
if (fsb.getToHops() != null)
fsb.getToHops().refreshMemEstimates(new MemoTable());
if (fsb.getIncrementHops() != null)
fsb.getIncrementHops().refreshMemEstimates(new MemoTable());
if (fsb.getNumStatements() > 1)
LOG.debug("For statement block has more than 1 stmt");
ForStatement ws = (ForStatement) fsb.getStatement(0);
for (StatementBlock sb : ws.getBody()) {
refreshMemEstimates(sb);
}
}
}
use of org.apache.sysml.hops.MemoTable in project systemml by apache.
the class Recompiler method recompile.
/**
* Core internal primitive for the dynamic recompilation of any DAGs/predicate,
* including all variants with slightly different configurations.
*
* @param sb statement block of DAG, null for predicates
* @param hops list of DAG root nodes
* @param vars symbol table
* @param status recompilation status
* @param inplace modify DAG in place, otherwise deep copy
* @param replaceLit replace literals (only applicable on deep copy)
* @param updateStats update statistics, rewrites, and memory estimates
* @param forceEt force a given execution type, null for reset
* @param pred recompile for predicate DAG
* @param et given execution type
* @param tid thread id, 0 for main or before worker creation
* @return modified list of instructions
*/
private static ArrayList<Instruction> recompile(StatementBlock sb, ArrayList<Hop> hops, LocalVariableMap vars, RecompileStatus status, boolean inplace, boolean replaceLit, boolean updateStats, boolean forceEt, boolean pred, ExecType et, long tid) {
// prepare hops dag for recompile
if (!inplace) {
// deep copy hop dag (for non-reversable rewrites)
hops = deepCopyHopsDag(hops);
} else {
// clear existing lops
Hop.resetVisitStatus(hops);
for (Hop hopRoot : hops) rClearLops(hopRoot);
}
// replace scalar reads with literals
if (!inplace && replaceLit) {
Hop.resetVisitStatus(hops);
for (Hop hopRoot : hops) rReplaceLiterals(hopRoot, vars, false);
}
// force exec type (et=null for reset)
if (forceEt) {
Hop.resetVisitStatus(hops);
for (Hop hopRoot : hops) rSetExecType(hopRoot, et);
Hop.resetVisitStatus(hops);
}
// update statistics, rewrites, and mem estimates
if (updateStats) {
// refresh matrix characteristics (update stats)
Hop.resetVisitStatus(hops);
for (Hop hopRoot : hops) rUpdateStatistics(hopRoot, vars);
// dynamic hop rewrites
if (!inplace) {
_rewriter.get().rewriteHopDAG(hops, null);
// update stats after rewrites
Hop.resetVisitStatus(hops);
for (Hop hopRoot : hops) rUpdateStatistics(hopRoot, vars);
}
// refresh memory estimates (based on updated stats,
// before: init memo table with propagated worst-case estimates,
// after: extract worst-case estimates from memo table
Hop.resetVisitStatus(hops);
MemoTable memo = new MemoTable();
memo.init(hops, status);
Hop.resetVisitStatus(hops);
for (Hop hopRoot : hops) hopRoot.refreshMemEstimates(memo);
memo.extract(hops, status);
}
// codegen if enabled
if (ConfigurationManager.isCodegenEnabled() && // not on reset
!(forceEt && et == null) && SpoofCompiler.RECOMPILE_CODEGEN) {
// create deep copy for in-place
if (inplace)
hops = deepCopyHopsDag(hops);
Hop.resetVisitStatus(hops);
hops = SpoofCompiler.optimize(hops, (status == null || !status.isInitialCodegen()));
}
// construct lops
Dag<Lop> dag = new Dag<>();
for (Hop hopRoot : hops) {
Lop lops = hopRoot.constructLops();
lops.addToDag(dag);
}
// generate runtime instructions (incl piggybacking)
ArrayList<Instruction> newInst = dag.getJobs(sb, ConfigurationManager.getDMLConfig());
// defer the explain of instructions after additional modifications
if (DMLScript.EXPLAIN == ExplainType.RECOMPILE_HOPS) {
if (pred)
logExplainPred(hops.get(0), newInst);
else
logExplainDAG(sb, hops, newInst);
}
return newInst;
}
use of org.apache.sysml.hops.MemoTable in project incubator-systemml by apache.
the class DMLTranslator method refreshMemEstimates.
public void refreshMemEstimates(StatementBlock current) {
MemoTable memo = new MemoTable();
if (HopRewriteUtils.isLastLevelStatementBlock(current)) {
ArrayList<Hop> hopsDAG = current.getHops();
if (hopsDAG != null && !hopsDAG.isEmpty())
for (Hop hop : hopsDAG) hop.refreshMemEstimates(memo);
}
if (current instanceof FunctionStatementBlock) {
FunctionStatement fstmt = (FunctionStatement) current.getStatement(0);
for (StatementBlock sb : fstmt.getBody()) {
refreshMemEstimates(sb);
}
} else if (current instanceof WhileStatementBlock) {
// handle predicate
WhileStatementBlock wstb = (WhileStatementBlock) current;
wstb.getPredicateHops().refreshMemEstimates(new MemoTable());
if (wstb.getNumStatements() > 1)
LOG.debug("While statement block has more than 1 stmt");
WhileStatement ws = (WhileStatement) wstb.getStatement(0);
for (StatementBlock sb : ws.getBody()) {
refreshMemEstimates(sb);
}
} else if (current instanceof IfStatementBlock) {
// handle predicate
IfStatementBlock istb = (IfStatementBlock) current;
istb.getPredicateHops().refreshMemEstimates(new MemoTable());
if (istb.getNumStatements() > 1)
LOG.debug("If statement block has more than 1 stmt");
IfStatement is = (IfStatement) istb.getStatement(0);
for (StatementBlock sb : is.getIfBody()) {
refreshMemEstimates(sb);
}
for (StatementBlock sb : is.getElseBody()) {
refreshMemEstimates(sb);
}
} else if (current instanceof ForStatementBlock) {
// handle predicate
ForStatementBlock fsb = (ForStatementBlock) current;
if (fsb.getFromHops() != null)
fsb.getFromHops().refreshMemEstimates(new MemoTable());
if (fsb.getToHops() != null)
fsb.getToHops().refreshMemEstimates(new MemoTable());
if (fsb.getIncrementHops() != null)
fsb.getIncrementHops().refreshMemEstimates(new MemoTable());
if (fsb.getNumStatements() > 1)
LOG.debug("For statement block has more than 1 stmt");
ForStatement ws = (ForStatement) fsb.getStatement(0);
for (StatementBlock sb : ws.getBody()) {
refreshMemEstimates(sb);
}
}
}
Aggregations