[SYSTEMML-2072] Fix codegen integration w/ parfor inplace recompile
This patch fixes special cases, where parfor inplace recompilation
(before optimization) in combination with enabled codegen, led to
invalid plans). For example, stepwise linregDS failed with invalid sizes
because a generated operator was reused in while(){parfor(){}} scenarios
although this operator was only valid for the first parfor instance. The
issue has been addressed by creating deep copies of the hop dag in case
of inplace recompilation.
Furthermore, this patch also includes a major rework of the
recompilation code, where all six variants of recompilation are now
consolidated in a single recompile primitive in order to ensure
consistency across all code path without code duplication.
Finally, this also includes a minor fix of row-wise fused operators to
ensure that operators with different constant sizes are not merged by
common subexpression elimination or reused in the plan cache.
Project: http://git-wip-us.apache.org/repos/asf/systemml/repo
Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/b9f72025
Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/b9f72025
Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/b9f72025
Branch: refs/heads/master
Commit: b9f720256956112da92837b39e75c56d6fc4fba7
Parents: f6c12dd
Author: Matthias Boehm <[email protected]>
Authored: Sat Jan 13 22:06:54 2018 -0800
Committer: Matthias Boehm <[email protected]>
Committed: Sat Jan 13 22:06:54 2018 -0800
----------------------------------------------------------------------
.../apache/sysml/hops/codegen/SpoofFusedOp.java | 5 +-
.../sysml/hops/codegen/cplan/CNodeRow.java | 1 +
.../apache/sysml/hops/recompile/Recompiler.java | 582 +++++++------------
.../java/org/apache/sysml/lops/compile/Dag.java | 11 +-
.../codegenalg/AlgorithmStepwiseRegression.java | 1 -
5 files changed, 216 insertions(+), 384 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/systemml/blob/b9f72025/src/main/java/org/apache/sysml/hops/codegen/SpoofFusedOp.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/SpoofFusedOp.java
b/src/main/java/org/apache/sysml/hops/codegen/SpoofFusedOp.java
index 368a84a..235aa88 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/SpoofFusedOp.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/SpoofFusedOp.java
@@ -288,6 +288,7 @@ public class SpoofFusedOp extends Hop implements
MultiThreadedHop
ret._class = _class;
ret._distSupported = _distSupported;
ret._numThreads = _numThreads;
+ ret._constDim2 = _constDim2;
ret._dimsType = _dimsType;
return ret;
}
@@ -298,10 +299,12 @@ public class SpoofFusedOp extends Hop implements
MultiThreadedHop
if( !(that instanceof SpoofFusedOp) )
return false;
- SpoofFusedOp that2 = (SpoofFusedOp)that;
+ SpoofFusedOp that2 = (SpoofFusedOp)that;
+ //note: class implies dims type as well
boolean ret = ( _class.equals(that2._class)
&& _distSupported == that2._distSupported
&& _numThreads == that2._numThreads
+ && _constDim2 == that2._constDim2
&& getInput().size() ==
that2.getInput().size());
if( ret ) {
http://git-wip-us.apache.org/repos/asf/systemml/blob/b9f72025/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java
index 3e42346..1a89570 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java
@@ -179,6 +179,7 @@ public class CNodeRow extends CNodeTpl
public int hashCode() {
if( _hash == 0 ) {
int h = UtilFunctions.intHashCode(super.hashCode(),
_type.hashCode());
+ h = UtilFunctions.intHashCode(h,
Long.hashCode(_constDim2));
_hash = UtilFunctions.intHashCode(h,
Integer.hashCode(_numVectors));
}
return _hash;
http://git-wip-us.apache.org/repos/asf/systemml/blob/b9f72025/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java
b/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java
index 8751daa..058e434 100644
--- a/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java
+++ b/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java
@@ -23,8 +23,10 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -149,101 +151,16 @@ public class Recompiler
_rewriter.set(new ProgramRewriter(false, true));
}
- /**
- * 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
+ LocalVariableMap vars, RecompileStatus status, boolean
inplace, boolean replaceLit, long tid )
+ throws DMLRuntimeException, HopsException, LopsException
{
ArrayList<Instruction> newInst = null;
//need for synchronization as we do temp changes in shared
hops/lops
//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().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()
- && SpoofCompiler.RECOMPILE_CODEGEN ) {
- 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)
- newInst = dag.getJobs(sb,
ConfigurationManager.getDMLConfig());
+ synchronized( hops ) {
+ newInst = recompile(sb, hops, vars, status, inplace,
replaceLit, true, false, null, tid);
}
// replace thread ids in new instructions
@@ -255,106 +172,21 @@ public class Recompiler
newInst = JMLCUtils.cleanupRuntimeInstructions(newInst,
vars.getRegisteredOutputs());
// 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));
- }
+ logExplainDAG(sb, hops, newInst);
return newInst;
}
-
- /**
- * 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
+
+ public static ArrayList<Instruction> recompileHopsDag( Hop hop,
LocalVariableMap vars,
+ RecompileStatus status, boolean inplace, boolean
replaceLit, long tid )
+ throws DMLRuntimeException, HopsException, LopsException
{
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.isCodegenEnabled()
- && SpoofCompiler.RECOMPILE_CODEGEN ) {
- hops.resetVisitStatus();
- hops = SpoofCompiler.optimize(hops,
- (status==null ||
!status.isInitialCodegen()));
- }
-
- // construct lops
- Dag<Lop> dag = new Dag<>();
- Lop lops = hops.constructLops();
- lops.addToDag(dag);
-
- // generate runtime instructions (incl piggybacking)
- newInst = dag.getJobs(null,
ConfigurationManager.getDMLConfig());
+ synchronized( hop ) {
+ newInst = recompile(null, new
ArrayList<>(Arrays.asList(hop)),
+ vars, status, inplace, replaceLit, true, false,
null, tid);
}
// replace thread ids in new instructions
@@ -362,194 +194,213 @@ public class Recompiler
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));
+ logExplainPred(hop, newInst);
return newInst;
}
- /**
- * C) Recompile basic program block hop DAG, but forced to CP.
- *
- * This happens always 'inplace', without statistics updates, and
- * without dynamic rewrites.
- *
- * @param sb statement block
- * @param hops list of high-level operators
- * @param tid thread id
- * @param et execution type
- * @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> recompileHopsDag2Forced(
StatementBlock sb, ArrayList<Hop> hops, long tid, ExecType et )
- throws DMLRuntimeException, HopsException, LopsException,
IOException
+ public static ArrayList<Instruction> recompileHopsDag2Forced(
StatementBlock sb, ArrayList<Hop> hops, long tid, ExecType et )
+ throws DMLRuntimeException, HopsException, LopsException
{
ArrayList<Instruction> newInst = null;
//need for synchronization as we do temp changes in shared
hops/lops
//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");
-
- // clear existing lops
- Hop.resetVisitStatus(hops);
- for( Hop hopRoot : hops )
- rClearLops( hopRoot );
-
- // update exec type
- Hop.resetVisitStatus(hops);
- for( Hop hopRoot : hops )
- rSetExecType( hopRoot, et );
- Hop.resetVisitStatus(hops);
-
- // construct lops
- Dag<Lop> dag = new Dag<>();
- for( Hop hopRoot : hops ){
- Lop lops = hopRoot.constructLops();
- lops.addToDag(dag);
- }
-
- // generate runtime instructions (incl piggybacking)
- newInst = dag.getJobs(sb,
ConfigurationManager.getDMLConfig());
+ synchronized( hops ) {
+ //always in place, no stats update/rewrites, but forced
exec type
+ newInst = recompile(sb, hops, null, null, true, false,
false, true, et, tid);
}
// replace thread ids in new instructions
if( tid != 0 ) //only in parfor context
newInst =
ProgramConverter.createDeepCopyInstructionSet(newInst, tid, -1, null, null,
null, false, false);
+ // explain recompiled hops / instructions
+ logExplainDAG(sb, hops, newInst);
+
return newInst;
}
-
- /**
- * D) Recompile predicate hop DAG (single root), but forced to CP.
- *
- * This happens always 'inplace', without statistics updates, and
- * without dynamic rewrites.
- *
- * @param hops list of high-level operators
- * @param tid thread id
- * @param et execution type
- * @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> recompileHopsDag2Forced( Hop hops,
long tid, ExecType et )
- throws DMLRuntimeException, HopsException, LopsException,
IOException
+
+ public static ArrayList<Instruction> recompileHopsDag2Forced( Hop hop,
long tid, ExecType et )
+ throws DMLRuntimeException, HopsException, LopsException
{
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");
-
- // clear existing lops
- hops.resetVisitStatus();
- rClearLops( hops );
-
- // update exec type
- hops.resetVisitStatus();
- rSetExecType( hops, et );
- hops.resetVisitStatus();
-
- // construct lops
- Dag<Lop> dag = new Dag<>();
- Lop lops = hops.constructLops();
- lops.addToDag(dag);
-
- // generate runtime instructions (incl piggybacking)
- newInst = dag.getJobs(null,
ConfigurationManager.getDMLConfig());
+ synchronized( hop ) {
+ //always in place, no stats update/rewrites, but forced
exec type
+ newInst = recompile(null, new
ArrayList<>(Arrays.asList(hop)),
+ null, null, true, false, false, true, et, tid);
}
// replace thread ids in new instructions
if( tid != 0 ) //only in parfor context
newInst =
ProgramConverter.createDeepCopyInstructionSet(newInst, tid, -1, null, null,
null, false, false);
+ // explain recompiled hops / instructions
+ logExplainPred(hop, newInst);
+
return newInst;
}
public static ArrayList<Instruction> recompileHopsDagInstructions(
StatementBlock sb, ArrayList<Hop> hops )
- throws HopsException, LopsException, DMLRuntimeException,
IOException
+ throws DMLRuntimeException, HopsException, LopsException
{
ArrayList<Instruction> newInst = null;
//need for synchronization as we do temp changes in shared
hops/lops
//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");
+ synchronized( hops ) {
+ //always in place, no stats update/rewrites
+ newInst = recompile(sb, hops, null, null, true, false,
false, false, null, 0);
+ }
+
+ // explain recompiled hops / instructions
+ logExplainDAG(sb, hops, newInst);
+
+ return newInst;
+ }
+
+ public static ArrayList<Instruction> recompileHopsDagInstructions( Hop
hop )
+ throws DMLRuntimeException, HopsException, LopsException
+ {
+ ArrayList<Instruction> newInst = null;
+
+ //need for synchronization as we do temp changes in shared
hops/lops
+ synchronized( hop ) {
+ //always in place, no stats update/rewrites
+ newInst = recompile(null, new
ArrayList<>(Arrays.asList(hop)),
+ null, null, true, false, false, false, null, 0);
+ }
+
+ // explain recompiled instructions
+ logExplainPred(hop, newInst);
+
+ return newInst;
+ }
+ /**
+ * 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 et given execution type
+ * @param tid thread id, 0 for main or before worker creation
+ * @return modified list of instructions
+ * @throws HopsException if hop compile error
+ * @throws LopsException if lop compile error
+ * @throws DMLRuntimeException if runtime error on literal replacement
+ */
+ private static ArrayList<Instruction> recompile(StatementBlock sb,
ArrayList<Hop> hops, LocalVariableMap vars,
+ RecompileStatus status, boolean inplace, boolean replaceLit,
boolean updateStats, boolean forceEt, ExecType et, long tid )
+ throws HopsException, LopsException, DMLRuntimeException
+ {
+ // 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 );
- // construct lops
- Dag<Lop> dag = new Dag<>();
- for( Hop hopRoot : hops ){
- Lop lops = hopRoot.constructLops();
- lops.addToDag(dag);
- }
+ // dynamic hop rewrites
+ if( !inplace ) {
+ _rewriter.get().rewriteHopDAG( hops, null );
+
+ //update stats after rewrites
+ Hop.resetVisitStatus(hops);
+ for( Hop hopRoot : hops )
+ rUpdateStatistics( hopRoot, vars );
+ }
- // generate runtime instructions (incl piggybacking)
- newInst = dag.getJobs(sb,
ConfigurationManager.getDMLConfig());
+ // 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);
}
- // 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));
+ // codegen if enabled
+ if( ConfigurationManager.isCodegenEnabled()
+ && !(forceEt && et == null ) //not on reset
+ && 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()));
}
- if( DMLScript.EXPLAIN == ExplainType.RECOMPILE_RUNTIME ){
- LOG.info("EXPLAIN RECOMPILE \nGENERIC (lines
"+sb.getBeginLine()+"-"+sb.getEndLine()+"):\n" +
- Explain.explain(newInst, 1));
+
+ // construct lops
+ Dag<Lop> dag = new Dag<>();
+ for( Hop hopRoot : hops ){
+ Lop lops = hopRoot.constructLops();
+ lops.addToDag(dag);
}
-
- return newInst;
+
+ // generate runtime instructions (incl piggybacking)
+ return dag.getJobs(sb, ConfigurationManager.getDMLConfig());
}
-
- public static ArrayList<Instruction> recompileHopsDagInstructions( Hop
hops )
- throws DMLRuntimeException, HopsException, LopsException,
IOException
+
+ private static void logExplainDAG(StatementBlock sb, ArrayList<Hop>
hops, ArrayList<Instruction> inst)
+ throws DMLRuntimeException
{
- 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");
-
- // clear existing lops
- hops.resetVisitStatus();
- rClearLops( hops );
-
- // construct lops
- Dag<Lop> dag = new Dag<>();
- Lop lops = hops.constructLops();
- lops.addToDag(dag);
-
- // generate runtime instructions (incl piggybacking)
- newInst = dag.getJobs(null,
ConfigurationManager.getDMLConfig());
+ if( DMLScript.EXPLAIN == ExplainType.RECOMPILE_HOPS ) {
+ LOG.info("EXPLAIN RECOMPILE \nGENERIC (lines
"+sb.getBeginLine()+"-"+sb.getEndLine()+"):\n" +
+ Explain.explainHops(hops, 1));
}
-
- // explain recompiled instructions
+ if( DMLScript.EXPLAIN == ExplainType.RECOMPILE_RUNTIME ) {
+ LOG.info("EXPLAIN RECOMPILE \nGENERIC (lines
"+sb.getBeginLine()+"-"+sb.getEndLine()+"):\n" +
+ Explain.explain(inst, 1));
+ }
+ }
+
+ private static void logExplainPred(Hop hops, ArrayList<Instruction>
inst)
+ throws DMLRuntimeException
+ {
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;
+ LOG.info("EXPLAIN RECOMPILE \nPRED (line
"+hops.getBeginLine()+"):\n" + Explain.explain(inst,1));
}
public static void recompileProgramBlockHierarchy(
ArrayList<ProgramBlock> pbs, LocalVariableMap vars, long tid, ResetType
resetRecompile )
@@ -652,40 +503,23 @@ public class Recompiler
}
}
- public static boolean requiresRecompilation( ArrayList<Hop> hops )
- {
- boolean ret = false;
-
- if( hops != null )
- {
- synchronized( hops )
- {
- Hop.resetVisitStatus(hops);
- for( Hop hop : hops )
- {
- ret |= rRequiresRecompile(hop);
- if( ret ) break; // early abort
- }
- }
+ public static boolean requiresRecompilation( ArrayList<Hop> hops ) {
+ if( hops == null )
+ return false;
+ synchronized( hops ) {
+ Hop.resetVisitStatus(hops);
+ return hops.stream()
+ .anyMatch(h -> rRequiresRecompile(h));
}
-
- return ret;
}
- public static boolean requiresRecompilation( Hop hop )
- {
- boolean ret = false;
-
- if( hop != null )
- {
- synchronized( hop )
- {
- hop.resetVisitStatus();
- ret = rRequiresRecompile(hop);
- }
+ public static boolean requiresRecompilation( Hop hop ) {
+ if( hop == null )
+ return false;
+ synchronized( hop ) {
+ hop.resetVisitStatus();
+ return rRequiresRecompile(hop);
}
-
- return ret;
}
@@ -696,10 +530,10 @@ public class Recompiler
* @return list of high-level operators
* @throws HopsException if HopsException occurs
*/
- public static ArrayList<Hop> deepCopyHopsDag( ArrayList<Hop> hops )
+ public static ArrayList<Hop> deepCopyHopsDag( List<Hop> hops )
throws HopsException
{
- ArrayList<Hop> ret = new ArrayList<>();
+ ArrayList<Hop> ret = new ArrayList<>(hops.size());
try {
//note: need memo table over all independent DAGs in
order to
@@ -708,8 +542,7 @@ public class Recompiler
for( Hop hopRoot : hops )
ret.add(rDeepCopyHopsDag(hopRoot, memo));
}
- catch(Exception ex)
- {
+ catch(Exception ex) {
throw new HopsException(ex);
}
@@ -723,7 +556,7 @@ public class Recompiler
* @return high-level operator
* @throws HopsException if HopsException occurs
*/
- public static Hop deepCopyHopsDag( Hop hops )
+ public static Hop deepCopyHopsDag( Hop hops )
throws HopsException
{
Hop ret = null;
@@ -732,8 +565,7 @@ public class Recompiler
HashMap<Long, Hop> memo = new HashMap<>(); //orig ID,
new clone
ret = rDeepCopyHopsDag(hops, memo);
}
- catch(Exception ex)
- {
+ catch(Exception ex) {
throw new HopsException(ex);
}
@@ -864,34 +696,30 @@ public class Recompiler
{
//do nothing
}
- else
- {
+ else
+ {
StatementBlock sb = pb.getStatementBlock();
ArrayList<Instruction> tmp = pb.getInstructions();
-
- if( sb != null //recompile all for stats
propagation and recompile flags
- //&& Recompiler.requiresRecompilation(
sb.get_hops() )
- /*&&
!Recompiler.containsNonRecompileInstructions(tmp)*/ )
+ if( sb == null )
+ return;
+
+ //recompile all for stats propagation and recompile
flags
+ tmp = Recompiler.recompileHopsDag(
+ sb, sb.getHops(), vars, status, true, false,
tid);
+ pb.setInstructions( tmp );
+
+ //propagate stats across hops (should be executed on
clone of vars)
+ Recompiler.extractDAGOutputStatistics(sb.getHops(),
vars);
+
+ //reset recompilation flags (w/ special handling
functions)
+ if( ParForProgramBlock.RESET_RECOMPILATION_FLAGs
+ && !containsRootFunctionOp(sb.getHops())
+ && resetRecompile.isReset() )
{
- tmp = Recompiler.recompileHopsDag(
- sb, sb.getHops(), vars, status, true,
false, tid);
- pb.setInstructions( tmp );
-
- //propagate stats across hops (should be
executed on clone of vars)
-
Recompiler.extractDAGOutputStatistics(sb.getHops(), vars);
-
- //reset recompilation flags (w/ special
handling functions)
- if(
ParForProgramBlock.RESET_RECOMPILATION_FLAGs
- &&
!containsRootFunctionOp(sb.getHops())
- && resetRecompile.isReset() )
- {
-
Hop.resetRecompilationFlag(sb.getHops(), ExecType.CP, resetRecompile);
- sb.updateRecompilationFlag();
- }
+ Hop.resetRecompilationFlag(sb.getHops(),
ExecType.CP, resetRecompile);
+ sb.updateRecompilationFlag();
}
-
}
-
}
public static boolean reconcileUpdatedCallVarsLoops( LocalVariableMap
oldCallVars, LocalVariableMap callVars, StatementBlock sb )
http://git-wip-us.apache.org/repos/asf/systemml/blob/b9f72025/src/main/java/org/apache/sysml/lops/compile/Dag.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/lops/compile/Dag.java
b/src/main/java/org/apache/sysml/lops/compile/Dag.java
index ab10363..28db4ea 100644
--- a/src/main/java/org/apache/sysml/lops/compile/Dag.java
+++ b/src/main/java/org/apache/sysml/lops/compile/Dag.java
@@ -245,7 +245,7 @@ public class Dag<N extends Lop>
* @throws DMLRuntimeException if DMLRuntimeException occurs
*/
public ArrayList<Instruction> getJobs(StatementBlock sb, DMLConfig
config)
- throws LopsException, IOException, DMLRuntimeException {
+ throws LopsException, DMLRuntimeException {
if (config != null) {
total_reducers =
config.getIntValue(DMLConfig.NUM_REDUCERS);
scratch = config.getTextValue(DMLConfig.SCRATCH_SPACE)
+ "/";
@@ -638,7 +638,8 @@ public class Dag<N extends Lop>
* @throws LopsException if LopsException occurs
* @throws IOException if IOException occurs
*/
- private static void
generateInstructionsForInputVariables(ArrayList<Lop> nodes_v,
ArrayList<Instruction> inst) throws LopsException, IOException {
+ private static void
generateInstructionsForInputVariables(ArrayList<Lop> nodes_v,
ArrayList<Instruction> inst)
+ throws LopsException {
for(Lop n : nodes_v) {
if (n.getExecLocation() == ExecLocation.Data &&
!((Data) n).isTransient()
&& ((Data) n).getOperationType() ==
OperationTypes.READ
@@ -646,9 +647,9 @@ public class Dag<N extends Lop>
if ( !((Data)n).isLiteral() ) {
try {
- String inst_string =
n.getInstructions();
+ String inst_string =
n.getInstructions();
CPInstruction currInstr =
CPInstructionParser.parseSingleInstruction(inst_string);
- currInstr.setLocation(n);
+ currInstr.setLocation(n);
inst.add(currInstr);
} catch (DMLRuntimeException e) {
throw new
LopsException(n.printErrorLocation() + "error generating instructions from
input variables in Dag -- \n", e);
@@ -771,7 +772,7 @@ public class Dag<N extends Lop>
* @throws DMLRuntimeException if DMLRuntimeException occurs
*/
private ArrayList<Instruction> doGreedyGrouping(StatementBlock sb,
ArrayList<Lop> node_v)
- throws LopsException, IOException, DMLRuntimeException
+ throws LopsException, DMLRuntimeException
{
if( LOG.isTraceEnabled() )
LOG.trace("Grouping DAG ============");
http://git-wip-us.apache.org/repos/asf/systemml/blob/b9f72025/src/test/java/org/apache/sysml/test/integration/functions/codegenalg/AlgorithmStepwiseRegression.java
----------------------------------------------------------------------
diff --git
a/src/test/java/org/apache/sysml/test/integration/functions/codegenalg/AlgorithmStepwiseRegression.java
b/src/test/java/org/apache/sysml/test/integration/functions/codegenalg/AlgorithmStepwiseRegression.java
index 012250a..d0acd62 100644
---
a/src/test/java/org/apache/sysml/test/integration/functions/codegenalg/AlgorithmStepwiseRegression.java
+++
b/src/test/java/org/apache/sysml/test/integration/functions/codegenalg/AlgorithmStepwiseRegression.java
@@ -144,7 +144,6 @@ public class AlgorithmStepwiseRegression extends
AutomatedTestBase
boolean oldFlag = OptimizerUtils.ALLOW_ALGEBRAIC_SIMPLIFICATION;
RUNTIME_PLATFORM platformOld = rtplatform;
switch( instType ){
- case MR: rtplatform = RUNTIME_PLATFORM.HADOOP; break;
case SPARK: rtplatform = RUNTIME_PLATFORM.SPARK; break;
default: rtplatform = RUNTIME_PLATFORM.HYBRID_SPARK;
break;
}