Repository: systemml
Updated Branches:
  refs/heads/master b2700839b -> 16e803f2a


[SYSTEMML-1834] Codegen plan enumeration with partial costing

This PR adds conditions to the fusion plan enumerator to stop costing a
plan when its partially computed cost exceeds the cost of the best plan
found so far (an upper bound).

The Statistics class reports the number of partially costed plans
separately from the number of fully costed plans. I attempted to count
the number of Hops costed per plan in order to measure the effectiveness
of stopping costing early at a more fine-grained level, but this count
was inaccurate for some reason. On StratStats, 2301 out of 3742 plans
can be stopped costed early.

Closes #611.


Project: http://git-wip-us.apache.org/repos/asf/systemml/repo
Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/16e803f2
Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/16e803f2
Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/16e803f2

Branch: refs/heads/master
Commit: 16e803f2a2ea160f99b709af0d0cecba053b8c4f
Parents: b270083
Author: Dylan Hutchison <dhutc...@cs.washington.edu>
Authored: Thu Aug 10 21:04:45 2017 -0700
Committer: Matthias Boehm <mboe...@gmail.com>
Committed: Thu Aug 10 21:04:46 2017 -0700

----------------------------------------------------------------------
 .../sysml/hops/codegen/SpoofCompiler.java       |   8 +-
 .../opt/PlanSelectionFuseCostBasedV2.java       | 123 +++++++++++--------
 .../hops/codegen/opt/ReachabilityGraph.java     |  10 +-
 .../java/org/apache/sysml/utils/Statistics.java |  43 +++++--
 src/test/config/SystemML-config.xml             |   2 +-
 5 files changed, 116 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/systemml/blob/16e803f2/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java 
b/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java
index 49a1686..ca3c233 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java
@@ -558,10 +558,10 @@ public class SpoofCompiler
                //generate cplan for existing memo table entry
                if( memo.containsTopLevel(hop.getHopID()) ) {
                        cplans.put(hop.getHopID(), TemplateUtils
-                               
.createTemplate(memo.getBest(hop.getHopID()).type)
-                               .constructCplan(hop, memo, compileLiterals));
-                       if( DMLScript.STATISTICS )
-                               Statistics.incrementCodegenCPlanCompile(1); 
+                                       
.createTemplate(memo.getBest(hop.getHopID()).type)
+                                       .constructCplan(hop, memo, 
compileLiterals));
+                       if (DMLScript.STATISTICS)
+                               Statistics.incrementCodegenCPlanCompile(1);
                }
                
                //process children recursively, but skip compiled operator

http://git-wip-us.apache.org/repos/asf/systemml/blob/16e803f2/src/main/java/org/apache/sysml/hops/codegen/opt/PlanSelectionFuseCostBasedV2.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/hops/codegen/opt/PlanSelectionFuseCostBasedV2.java
 
b/src/main/java/org/apache/sysml/hops/codegen/opt/PlanSelectionFuseCostBasedV2.java
index e66c9c3..f818c06 100644
--- 
a/src/main/java/org/apache/sysml/hops/codegen/opt/PlanSelectionFuseCostBasedV2.java
+++ 
b/src/main/java/org/apache/sysml/hops/codegen/opt/PlanSelectionFuseCostBasedV2.java
@@ -25,11 +25,11 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
-import java.util.Map.Entry;
-import java.util.stream.Collectors;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
 
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.ArrayUtils;
@@ -52,11 +52,11 @@ import org.apache.sysml.hops.TernaryOp;
 import org.apache.sysml.hops.UnaryOp;
 import org.apache.sysml.hops.codegen.opt.ReachabilityGraph.SubProblem;
 import org.apache.sysml.hops.codegen.template.CPlanMemoTable;
+import org.apache.sysml.hops.codegen.template.CPlanMemoTable.MemoTableEntry;
+import org.apache.sysml.hops.codegen.template.TemplateBase.TemplateType;
 import org.apache.sysml.hops.codegen.template.TemplateOuterProduct;
 import org.apache.sysml.hops.codegen.template.TemplateRow;
 import org.apache.sysml.hops.codegen.template.TemplateUtils;
-import org.apache.sysml.hops.codegen.template.CPlanMemoTable.MemoTableEntry;
-import org.apache.sysml.hops.codegen.template.TemplateBase.TemplateType;
 import org.apache.sysml.hops.rewrite.HopRewriteUtils;
 import org.apache.sysml.runtime.codegen.LibSpoofPrimitives;
 import 
org.apache.sysml.runtime.controlprogram.parfor.stat.InfrastructureAnalyzer;
@@ -148,7 +148,7 @@ public class PlanSelectionFuseCostBasedV2 extends 
PlanSelection
                                for( Long hopID : part.getPartition() )
                                        memo.pruneRedundant(hopID, true, 
part.getMatPointsExt());
                        }
-                       
+
                        //enumerate and cost plans, returns optional plan
                        boolean[] bestPlan = enumPlans(memo, part, costs, 
rgraph, 
                                        part.getMatPointsExt(), 0, 
Double.MAX_VALUE);
@@ -188,20 +188,23 @@ public class PlanSelectionFuseCostBasedV2 extends 
PlanSelection
         * @return optimal assignment of materialization points
         */
        private static boolean[] enumPlans(CPlanMemoTable memo, PlanPartition 
part, StaticCosts costs, 
-               ReachabilityGraph rgraph, InterestingPoint[] matPoints, int 
off, double bestC) 
+               ReachabilityGraph rgraph, InterestingPoint[] matPoints, int 
off, double bestC)
        {
                //scan linearized search space, w/ skips for branch and bound 
pruning
                //and structural pruning (where we solve conditionally 
independent problems)
                //bestC is monotonically non-increasing and serves as the upper 
bound
-               long len = (long)Math.pow(2, matPoints.length-off);
+               long len = 1L << matPoints.length-off;
                boolean[] bestPlan = null;
-               int numEvalPlans = 0;
-               
+               long numEvalPlans = 0, numEvalPartialPlans = 0, numSkipPlans = 
0;
+
                for( long i=0; i<len; i++ ) {
                        //construct assignment
                        boolean[] plan = createAssignment(matPoints.length-off, 
off, i);
+                       if( bestPlan == null )
+                               bestPlan = plan;
                        long pskip = 0; //skip after costing
-                       
+
+
                        //skip plans with structural pruning
                        if( USE_STRUCTURAL_PRUNING && (rgraph!=null) && 
rgraph.isCutSet(plan) ) {
                                //compute skip (which also acts as boundary for 
subproblems)
@@ -222,43 +225,52 @@ public class PlanSelectionFuseCostBasedV2 extends 
PlanSelection
                        }
                        //skip plans with branch and bound pruning (cost)
                        else if( USE_COST_PRUNING ) {
-                               double lbC = Math.max(costs._read, 
costs._compute) + costs._write 
-                                       + getMaterializationCost(part, 
matPoints, memo, plan);
+                               double lbC = Math.max(costs._read, 
costs._compute) + costs._write
+                                               + getMaterializationCost(part, 
matPoints, memo, plan);
                                if( lbC >= bestC ) {
                                        long skip = getNumSkipPlans(plan);
                                        if( LOG.isTraceEnabled() )
                                                LOG.trace("Enum: Skip "+skip+" 
plans (by cost).");
                                        i += skip - 1;
+                                       numSkipPlans += skip;
                                        continue;
                                }
                        }
                        
-                       //cost assignment on hops
-                       double C = getPlanCost(memo, part, matPoints, plan, 
costs._computeCosts);
-                       numEvalPlans ++;
-                       if( LOG.isTraceEnabled() )
-                               LOG.trace("Enum: "+Arrays.toString(plan)+" -> 
"+C);
-                       
-                       //cost comparisons
-                       if( bestPlan == null || C < bestC ) {
-                               bestC = C;
-                               bestPlan = plan;
-                               if( LOG.isTraceEnabled() )
-                                       LOG.trace("Enum: Found new best plan.");
+                       //cost assignment on hops. Stop early if exceeds bestC.
+                       double C = getPlanCost(memo, part, matPoints, plan, 
costs._computeCosts, bestC);
+                       if (LOG.isTraceEnabled())
+                               LOG.trace("Enum: " + Arrays.toString(plan) + " 
-> " + C);
+                       if( C == Double.POSITIVE_INFINITY ) {
+                               numEvalPartialPlans++;
+                       } else {
+                               numEvalPlans++;
+                               //cost comparisons
+                               if( C < bestC ) {
+                                       bestC = C;
+                                       bestPlan = plan;
+                                       if( LOG.isTraceEnabled() )
+                                               LOG.trace("Enum: Found new best 
plan.");
+                               }
                        }
-                       
+
                        //post skipping
                        i += pskip;
+                       numSkipPlans += pskip;
                        if( pskip !=0 && LOG.isTraceEnabled() )
                                LOG.trace("Enum: Skip "+pskip+" plans (by 
structure).");
                }
                
-               if( DMLScript.STATISTICS )
+               if( DMLScript.STATISTICS ) {
                        Statistics.incrementCodegenFPlanCompile(numEvalPlans);
+                       
Statistics.incrementCodegenFPlanPartialCost(numEvalPartialPlans);
+                       Statistics.incrementCodegenFPlanSkip(numSkipPlans);
+               }
                if( LOG.isTraceEnabled() )
                        LOG.trace("Enum: Optimal plan: 
"+Arrays.toString(bestPlan));
                
                //copy best plan w/o fixed offset plan
+               assert bestPlan != null;
                return Arrays.copyOfRange(bestPlan, off, bestPlan.length);
        }
        
@@ -267,15 +279,16 @@ public class PlanSelectionFuseCostBasedV2 extends 
PlanSelection
                Arrays.fill(ret, 0, off, true);
                long tmp = pos;
                for( int i=0; i<len; i++ ) {
-                       ret[off+i] = (tmp >= Math.pow(2, len-i-1));
-                       tmp %= Math.pow(2, len-i-1);
+                       long mask = 1L << len-i-1;
+                       ret[off+i] = tmp >= mask;
+                       tmp %= mask;
                }
                return ret;     
        }
        
        private static long getNumSkipPlans(boolean[] plan) {
                int pos = ArrayUtils.lastIndexOf(plan, true);
-               return (long) Math.pow(2, plan.length-pos-1);
+               return 1L << plan.length-pos-1;
        }
        
        private static double getMaterializationCost(PlanPartition part, 
InterestingPoint[] M, CPlanMemoTable memo, boolean[] plan) {
@@ -757,7 +770,8 @@ public class PlanSelectionFuseCostBasedV2 extends 
PlanSelection
        //////////
        
        private static double getPlanCost(CPlanMemoTable memo, PlanPartition 
part, 
-               InterestingPoint[] matPoints,boolean[] plan, HashMap<Long, 
Double> computeCosts) 
+                       InterestingPoint[] matPoints,boolean[] plan, 
HashMap<Long, Double> computeCosts,
+                       final double bestC)
        {
                //high level heuristic: every hop or fused operator has the 
following cost: 
                //WRITE + max(COMPUTE, READ), where WRITE costs are given by 
the output size, 
@@ -766,17 +780,25 @@ public class PlanSelectionFuseCostBasedV2 extends 
PlanSelection
                
                HashSet<VisitMarkCost> visited = new HashSet<>();
                double costs = 0;
+               int rem = part.getRoots().size();
                for( Long hopID : part.getRoots() ) {
                        costs += rGetPlanCosts(memo, 
memo.getHopRefs().get(hopID), 
-                               visited, part, matPoints, plan, computeCosts, 
null, null);
+                               visited, part, matPoints, plan, computeCosts, 
null, null, bestC - costs);
+                       rem--;
+                       // stop early if we exceed bestC
+                       if( costs >= bestC && rem > 0 ) {
+                               costs = Double.POSITIVE_INFINITY;
+                               break;
+                       }
                }
                return costs;
        }
        
-       private static double rGetPlanCosts(CPlanMemoTable memo, Hop current, 
HashSet<VisitMarkCost> visited, 
-               PlanPartition part, InterestingPoint[] matPoints, boolean[] 
plan, HashMap<Long, Double> computeCosts, 
-               CostVector costsCurrent, TemplateType currentType) 
+       private static double rGetPlanCosts(CPlanMemoTable memo, final Hop 
current, HashSet<VisitMarkCost> visited,
+                       PlanPartition part, InterestingPoint[] matPoints, 
boolean[] plan, HashMap<Long, Double> computeCosts,
+                       CostVector costsCurrent, TemplateType currentType, 
final double costBudget)
        {
+               final long currentHopId = current.getHopID();
                //memoization per hop id and cost vector to account for 
redundant
                //computation without double counting materialized results or 
compute
                //costs of complex operation DAGs within a single fused operator
@@ -788,21 +810,20 @@ public class PlanSelectionFuseCostBasedV2 extends 
PlanSelection
                //under awareness of current plan choice
                MemoTableEntry best = null;
                boolean opened = (currentType == null);
-               if( memo.contains(current.getHopID()) ) {
+               if( memo.contains(currentHopId) ) {
                        //note: this is the inner loop of plan enumeration and 
hence, we do not 
                        //use streams, lambda expressions, etc to avoid 
unnecessary overhead
-                       long hopID = current.getHopID();
                        if( currentType == null ) {
-                               for( MemoTableEntry me : memo.get(hopID) )
+                               for( MemoTableEntry me : memo.get(currentHopId) 
)
                                        best = isValid(me, current) 
-                                               && hasNoRefToMatPoint(hopID, 
me, matPoints, plan) 
+                                               && 
hasNoRefToMatPoint(currentHopId, me, matPoints, plan)
                                                && 
BasicPlanComparator.icompare(me, best)<0 ? me : best;
                                opened = true;
                        }
                        else {
-                               for( MemoTableEntry me : memo.get(hopID) )
+                               for( MemoTableEntry me : memo.get(currentHopId) 
)
                                        best = (me.type == currentType || 
me.type==TemplateType.CELL)
-                                               && hasNoRefToMatPoint(hopID, 
me, matPoints, plan) 
+                                               && 
hasNoRefToMatPoint(currentHopId, me, matPoints, plan)
                                                && 
TypedPlanComparator.icompare(me, best, currentType)<0 ? me : best;
                        }
                }
@@ -814,11 +835,13 @@ public class PlanSelectionFuseCostBasedV2 extends 
PlanSelection
                //add other roots for multi-agg template to account for shared 
costs
                if( opened && best != null && best.type == TemplateType.MAGG ) {
                        //account costs to first multi-agg root 
-                       if( best.input1 == current.getHopID() )
+                       if( best.input1 == currentHopId )
                                for( int i=1; i<3; i++ ) {
                                        if( !best.isPlanRef(i) ) continue;
                                        costs += rGetPlanCosts(memo, 
memo.getHopRefs().get(best.input(i)), visited, 
-                                               part, matPoints, plan, 
computeCosts, costVect, TemplateType.MAGG);
+                                               part, matPoints, plan, 
computeCosts, costVect, TemplateType.MAGG, costBudget - costs);
+                                       if( costs >= costBudget )
+                                               return Double.POSITIVE_INFINITY;
                                }
                        //skip other multi-agg roots
                        else
@@ -826,28 +849,32 @@ public class PlanSelectionFuseCostBasedV2 extends 
PlanSelection
                }
                
                //add compute costs of current operator to costs vector
-               costVect.computeCosts += computeCosts.get(current.getHopID());
+               costVect.computeCosts += computeCosts.get(currentHopId);
                
                //process children recursively
                for( int i=0; i< current.getInput().size(); i++ ) {
                        Hop c = current.getInput().get(i);
                        if( best!=null && best.isPlanRef(i) )
-                               costs += rGetPlanCosts(memo, c, visited, part, 
matPoints, plan, computeCosts, costVect, best.type);
+                               costs += rGetPlanCosts(memo, c, visited, part, 
matPoints,
+                                               plan, computeCosts, costVect, 
best.type, costBudget - costs);
                        else if( best!=null && isImplicitlyFused(current, i, 
best.type) )
                                
costVect.addInputSize(c.getInput().get(0).getHopID(), getSize(c));
                        else { //include children and I/O costs
                                if( part.getPartition().contains(c.getHopID()) )
-                                       costs += rGetPlanCosts(memo, c, 
visited, part, matPoints, plan, computeCosts, null, null);
+                                       costs += rGetPlanCosts(memo, c, 
visited, part, matPoints,
+                                               plan, computeCosts, null, null, 
costBudget - costs);
                                if( costVect != null && 
c.getDataType().isMatrix() )
                                        costVect.addInputSize(c.getHopID(), 
getSize(c));
                        }
+                       if( costs >= costBudget )
+                               return Double.POSITIVE_INFINITY;
                }
                
                //add costs for opened fused operator
                if( opened ) {
                        if( LOG.isTraceEnabled() ) {
                                String type = (best !=null) ? best.type.name() 
: "HOP";
-                               LOG.trace("Cost vector ("+type+" 
"+current.getHopID()+"): "+costVect);
+                               LOG.trace("Cost vector ("+type+" 
"+currentHopId+"): "+costVect);
                        }
                        double tmpCosts = costVect.outSize * 8 / 
WRITE_BANDWIDTH //time for output write
                                + Math.max(costVect.getSumInputSizes() * 8 / 
READ_BANDWIDTH,
@@ -861,8 +888,8 @@ public class PlanSelectionFuseCostBasedV2 extends 
PlanSelection
                }
                //add costs for non-partition read in the middle of fused 
operator
                else if( part.getExtConsumed().contains(current.getHopID()) ) {
-                       costs += rGetPlanCosts(memo, current, visited,
-                               part, matPoints, plan, computeCosts, null, 
null);
+                       costs += rGetPlanCosts(memo, current, visited, part, 
matPoints, plan,
+                               computeCosts, null, null, costBudget - costs);
                }
                
                //sanity check non-negative costs

http://git-wip-us.apache.org/repos/asf/systemml/blob/16e803f2/src/main/java/org/apache/sysml/hops/codegen/opt/ReachabilityGraph.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/hops/codegen/opt/ReachabilityGraph.java 
b/src/main/java/org/apache/sysml/hops/codegen/opt/ReachabilityGraph.java
index de1ed92..fb7c8d9 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/opt/ReachabilityGraph.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/opt/ReachabilityGraph.java
@@ -175,7 +175,7 @@ public class ReachabilityGraph
                for( CutSet cs : _cutSets )
                        if( isCutSet(cs, plan) ) {
                                int pos = cs.posCut[cs.posCut.length-1];        
                        
-                               return (long) Math.pow(2, plan.length-pos-1);
+                               return 1L << plan.length-pos-1;
                        }
                throw new RuntimeException("Failed to compute "
                        + "number of skip plans for plan without cutset.");
@@ -240,11 +240,11 @@ public class ReachabilityGraph
                        if( !CollectionUtils.containsAny(part1, part2) 
                                && !part1.isEmpty() && !part2.isEmpty()) {
                                //score cutsets (smaller is better)
-                               double base = Math.pow(2, _matPoints.size());
-                               double numComb = Math.pow(2, cand.size());
+                               double base = 1L << _matPoints.size();
+                               double numComb = 1L << cand.size();
                                double score = (numComb-1)/numComb * base
-                                       + 1/numComb * Math.pow(2, part1.size())
-                                       + 1/numComb * Math.pow(2, part2.size());
+                                       + 1/numComb * (1L << part1.size())
+                                       + 1/numComb * (1L << part2.size());
                                
                                //construct cutset
                                cutSets.add(Pair.of(new CutSet(

http://git-wip-us.apache.org/repos/asf/systemml/blob/16e803f2/src/main/java/org/apache/sysml/utils/Statistics.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/utils/Statistics.java 
b/src/main/java/org/apache/sysml/utils/Statistics.java
index 8891a6c..b294ba6 100644
--- a/src/main/java/org/apache/sysml/utils/Statistics.java
+++ b/src/main/java/org/apache/sysml/utils/Statistics.java
@@ -77,6 +77,8 @@ public class Statistics
        private static final LongAdder codegenClassCompileTime = new 
LongAdder(); //in nano
        private static final LongAdder codegenHopCompile = new LongAdder(); 
//count
        private static final LongAdder codegenFPlanCompile = new LongAdder(); 
//count
+       private static final LongAdder codegenFPlanPartialCost = new 
LongAdder(); //count
+       private static final LongAdder codegenFPlanSkip = new LongAdder(); 
//count
        private static final LongAdder codegenCPlanCompile = new LongAdder(); 
//count
        private static final LongAdder codegenClassCompile = new LongAdder(); 
//count
        private static final LongAdder codegenPlanCacheHits = new LongAdder(); 
//count
@@ -260,6 +262,12 @@ public class Statistics
        public static void incrementCodegenFPlanCompile(long delta) {
                codegenFPlanCompile.add(delta);
        }
+       public static void incrementCodegenFPlanPartialCost(long delta) {
+               codegenFPlanPartialCost.add(delta);
+       }
+       public static void incrementCodegenFPlanSkip(long delta) {
+               codegenFPlanSkip.add(delta);
+       }
        
        public static void incrementCodegenClassCompile() {
                codegenClassCompile.increment();
@@ -292,6 +300,12 @@ public class Statistics
        public static long getCodegenFPlanCompile() {
                return codegenFPlanCompile.longValue();
        }
+       public static long getCodegenFPlanPartialCost() {
+               return codegenFPlanPartialCost.longValue();
+       }
+       public static long getCodegenFPlanSkip() {
+               return codegenFPlanSkip.longValue();
+       }
        
        public static long getCodegenClassCompile() {
                return codegenClassCompile.longValue();
@@ -387,6 +401,8 @@ public class Statistics
                
                codegenHopCompile.reset();
                codegenFPlanCompile.reset();
+               codegenFPlanPartialCost.reset();
+               codegenFPlanSkip.reset();
                codegenCPlanCompile.reset();
                codegenClassCompile.reset();
                codegenCompileTime.reset();
@@ -725,10 +741,10 @@ public class Statistics
                
                sb.append("SystemML Statistics:\n");
                if( DMLScript.STATISTICS ) {
-                       sb.append("Total elapsed time:\t\t" + 
String.format("%.3f", (getCompileTime()+getRunTime())*1e-9) + " sec.\n"); // 
nanoSec --> sec
-                       sb.append("Total compilation time:\t\t" + 
String.format("%.3f", getCompileTime()*1e-9) + " sec.\n"); // nanoSec --> sec
+                       sb.append("Total elapsed time:\t\t\t\t" + 
String.format("%.3f", (getCompileTime()+getRunTime())*1e-9) + " sec.\n"); // 
nanoSec --> sec
+                       sb.append("Total compilation time:\t\t\t" + 
String.format("%.3f", getCompileTime()*1e-9) + " sec.\n"); // nanoSec --> sec
                }
-               sb.append("Total execution time:\t\t" + String.format("%.3f", 
getRunTime()*1e-9) + " sec.\n"); // nanoSec --> sec
+               sb.append("Total execution time:\t\t\t" + String.format("%.3f", 
getRunTime()*1e-9) + " sec.\n"); // nanoSec --> sec
                if( OptimizerUtils.isSparkExecutionMode() ) {
                        if( DMLScript.STATISTICS ) //moved into stats on Shiv's 
request
                                sb.append("Number of compiled Spark inst:\t" + 
getNoOfCompiledSPInst() + ".\n");
@@ -764,26 +780,29 @@ public class Statistics
                        }
                        
                        sb.append("Cache hits (Mem, WB, FS, HDFS):\t" + 
CacheStatistics.displayHits() + ".\n");
-                       sb.append("Cache writes (WB, FS, HDFS):\t" + 
CacheStatistics.displayWrites() + ".\n");
+                       sb.append("Cache writes (WB, FS, HDFS):   \t" + 
CacheStatistics.displayWrites() + ".\n");
                        sb.append("Cache times (ACQr/m, RLS, EXP):\t" + 
CacheStatistics.displayTime() + " sec.\n");
                        sb.append("HOP DAGs recompiled (PRED, SB):\t" + 
getHopRecompiledPredDAGs() + "/" + getHopRecompiledSBDAGs() + ".\n");
-                       sb.append("HOP DAGs recompile time:\t" + 
String.format("%.3f", ((double)getHopRecompileTime())/1000000000) + " sec.\n");
+                       sb.append("HOP DAGs recompile time:       \t" + 
String.format("%.3f", ((double)getHopRecompileTime())/1000000000) + " sec.\n");
                        if( getFunRecompiles()>0 ) {
                                sb.append("Functions recompiled:\t\t" + 
getFunRecompiles() + ".\n");
                                sb.append("Functions recompile time:\t" + 
String.format("%.3f", ((double)getFunRecompileTime())/1000000000) + " sec.\n"); 
      
                        }
                        if( ConfigurationManager.isCodegenEnabled() ) {
-                               sb.append("Codegen compile (DAG,FP,CP,JC):\t" + 
getCodegenDAGCompile() + "/" + getCodegenFPlanCompile() 
-                                       + "/" + getCodegenCPlanCompile() + "/" 
+ getCodegenClassCompile() + ".\n");
+                               sb.append("Codegen compile    (DAG,CP,JC):\t" + 
getCodegenDAGCompile() + "/"
+                                               + getCodegenCPlanCompile() + 
"/" + getCodegenClassCompile() + ".\n");
+                               sb.append("Codegen enum  (full,part,skip):\t" + 
getCodegenFPlanCompile() + "/"
+                                               + getCodegenFPlanPartialCost() 
+ "/"
+                                               + getCodegenFPlanSkip() + 
".\n");
                                sb.append("Codegen compile times (DAG,JC):\t" + 
String.format("%.3f", (double)getCodegenCompileTime()/1000000000) + "/" + 
                                                String.format("%.3f", 
(double)getCodegenClassCompileTime()/1000000000)  + " sec.\n");
-                               sb.append("Codegen plan cache hits:\t" + 
getCodegenPlanCacheHits() + "/" + getCodegenPlanCacheTotal() + ".\n");
+                               sb.append("Codegen plan cache hits:       \t" + 
getCodegenPlanCacheHits() + "/" + getCodegenPlanCacheTotal() + ".\n");
                        }
                        if( OptimizerUtils.isSparkExecutionMode() ){
                                String lazy = 
SparkExecutionContext.isLazySparkContextCreation() ? "(lazy)" : "(eager)";
                                sb.append("Spark ctx create time "+lazy+":\t"+
                                                String.format("%.3f", 
((double)sparkCtxCreateTime)*1e-9)  + " sec.\n" ); // nanoSec --> sec
-                               sb.append("Spark trans counts (par,bc,col):" +
+                               sb.append("Spark trans counts(par,bc,col):\t" +
                                                String.format("%d/%d/%d.\n", 
sparkParallelizeCount.longValue(), 
                                                                
sparkBroadcastCount.longValue(), sparkCollectCount.longValue()));
                                sb.append("Spark trans times (par,bc,col):\t" +
@@ -800,9 +819,9 @@ public class Statistics
                                sb.append("ParFor total update in-place:\t" + 
lTotalUIPVar + "/" + lTotalLixUIP + "/" + lTotalLix + "\n");
                        }
 
-                       sb.append("Total JIT compile time:\t\t" + 
((double)getJITCompileTime())/1000 + " sec.\n");
-                       sb.append("Total JVM GC count:\t\t" + getJVMgcCount() + 
".\n");
-                       sb.append("Total JVM GC time:\t\t" + 
((double)getJVMgcTime())/1000 + " sec.\n");
+                       sb.append("Total JIT compile time:\t\t\t" + 
((double)getJITCompileTime())/1000 + " sec.\n");
+                       sb.append("Total JVM GC count:\t\t\t\t" + 
getJVMgcCount() + ".\n");
+                       sb.append("Total JVM GC time:\t\t\t\t" + 
((double)getJVMgcTime())/1000 + " sec.\n");
                        LibMatrixDNN.appendStatistics(sb);
                        sb.append("Heavy hitter instructions:\n" + 
getHeavyHitters(maxHeavyHitters));
                }

http://git-wip-us.apache.org/repos/asf/systemml/blob/16e803f2/src/test/config/SystemML-config.xml
----------------------------------------------------------------------
diff --git a/src/test/config/SystemML-config.xml 
b/src/test/config/SystemML-config.xml
index 9b52a6d..3b25d99 100644
--- a/src/test/config/SystemML-config.xml
+++ b/src/test/config/SystemML-config.xml
@@ -25,7 +25,7 @@
    <scratch>scratch_space</scratch> 
 
    <!-- compiler optimization level, valid values: 0 | 1 | 2 | 3 | 4, default: 
2 -->
-   <optlevel>2</optlevel>  
+   <optlevel>2</optlevel>
 
    <!-- default number of reduce tasks per MR job, default: 2 x number of 
nodes -->
    <numreducers>10</numreducers> 

Reply via email to