Repository: incubator-systemml
Updated Branches:
  refs/heads/master d65c7b5bb -> 8936e4f8a


[SYSTEMML-1297] Extended explain tool for code generation plans

This patch extends the existing explain tool for code generation plans
(cplans). In order to provide a useful explain output, we also extended
the cnode base with individual ids, dag handling, and operation codes.
Furthermore, the explain of code generation plans and source code has
been fully integrated with the various explain types. 


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

Branch: refs/heads/master
Commit: e449cae627cf5b0ea601cde5349c16b425724560
Parents: d65c7b5
Author: Matthias Boehm <mboe...@gmail.com>
Authored: Sat Mar 4 20:37:15 2017 -0800
Committer: Matthias Boehm <mboe...@gmail.com>
Committed: Sat Mar 4 20:44:26 2017 -0800

----------------------------------------------------------------------
 .../sysml/hops/codegen/SpoofCompiler.java       | 25 +++---
 .../apache/sysml/hops/codegen/cplan/CNode.java  | 34 +++++++-
 .../sysml/hops/codegen/cplan/CNodeBinary.java   | 14 +++-
 .../sysml/hops/codegen/cplan/CNodeCell.java     | 10 +++
 .../sysml/hops/codegen/cplan/CNodeData.java     |  2 +-
 .../hops/codegen/cplan/CNodeOuterProduct.java   | 10 +++
 .../hops/codegen/cplan/CNodeRowAggVector.java   |  7 ++
 .../sysml/hops/codegen/cplan/CNodeTpl.java      |  9 +++
 .../sysml/hops/codegen/cplan/CNodeUnary.java    |  8 +-
 .../apache/sysml/hops/recompile/Recompiler.java |  2 +-
 .../java/org/apache/sysml/utils/Explain.java    | 85 +++++++++++++++++++-
 .../functions/codegen/DAGCellwiseTmplTest.java  |  2 +-
 .../functions/codegen/SumProductChainTest.java  |  2 +-
 13 files changed, 188 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/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 760eff0..f40a883 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/SpoofCompiler.java
@@ -62,7 +62,6 @@ import org.apache.sysml.runtime.codegen.CodegenUtils;
 import org.apache.sysml.runtime.codegen.SpoofCellwise.CellType;
 import org.apache.sysml.runtime.matrix.data.Pair;
 import org.apache.sysml.utils.Explain;
-import org.apache.sysml.utils.Explain.ExplainType;
 import org.apache.sysml.utils.Statistics;
 
 public class SpoofCompiler 
@@ -152,7 +151,7 @@ public class SpoofCompiler
                if( roots == null )
                        return roots;
 
-               ArrayList<Hop> optimized = SpoofCompiler.optimize(roots, true);
+               ArrayList<Hop> optimized = SpoofCompiler.optimize(roots, false);
                Hop.resetVisitStatus(roots);
                Hop.resetVisitStatus(optimized);
                
@@ -164,15 +163,15 @@ public class SpoofCompiler
         * Main interface of sum-product optimizer, predicate dag.
         * 
         * @param root dag root node
-        * @param compileLiterals if true literals compiled as constants, 
otherwise as scalar variables
+        * @param recompile true if invoked during dynamic recompilation
         * @return dag root node of modified dag
         * @throws DMLRuntimeException if optimization failed
         */
-       public static Hop optimize( Hop root, boolean compileLiterals ) throws 
DMLRuntimeException {
+       public static Hop optimize( Hop root, boolean recompile ) throws 
DMLRuntimeException {
                if( root == null )
                        return root;
                
-               return optimize(new ArrayList<Hop>(Arrays.asList(root)), 
compileLiterals).get(0);
+               return optimize(new ArrayList<Hop>(Arrays.asList(root)), 
recompile).get(0);
        }
        
        public static void cleanupCodeGenerator() {
@@ -186,12 +185,12 @@ public class SpoofCompiler
         * Main interface of sum-product optimizer, statement block dag.
         * 
         * @param roots dag root nodes
-        * @param compileLiterals if true literals compiled as constants, 
otherwise as scalar variables
+        * @param recompile true if invoked during dynamic recompilation
         * @return dag root nodes of modified dag 
         * @throws DMLRuntimeException if optimization failed
         */
        @SuppressWarnings("unused")
-       public static ArrayList<Hop> optimize(ArrayList<Hop> roots, boolean 
compileLiterals) 
+       public static ArrayList<Hop> optimize(ArrayList<Hop> roots, boolean 
recompile) 
                throws DMLRuntimeException 
        {
                if( roots == null || roots.isEmpty() || !OPTIMIZE )
@@ -202,6 +201,9 @@ public class SpoofCompiler
                
                try
                {
+                       //context-sensitive literal replacement (only integers 
during recompile)
+                       boolean compileLiterals = ALWAYS_COMPILE_LITERALS || 
!recompile;
+                       
                        //construct codegen plans
                        HashMap<Long, Pair<Hop[],CNodeTpl>>  cplans = 
constructCPlans(roots, compileLiterals);
                        
@@ -223,8 +225,13 @@ public class SpoofCompiler
                                        //generate java source code
                                        String src = 
tmp.getValue().codegen(false);
                                        
-                                       //explain debug output generated source 
code
-                                       if( LDEBUG || DMLScript.EXPLAIN != 
ExplainType.NONE ) {
+                                       //explain debug output cplans or 
generated source code
+                                       if( LDEBUG || 
DMLScript.EXPLAIN.isHopsType(recompile) ) {
+                                               LOG.info("Codegen EXPLAIN 
(generated cplan for HopID: " +  cplan.getKey() +"):");
+                                               
LOG.info(tmp.getValue().getClassname()
+                                                               
+Explain.explainCPlan(cplan.getValue().getValue()));
+                                       }
+                                       if( LDEBUG || 
DMLScript.EXPLAIN.isRuntimeType(recompile) ) {
                                                LOG.info("Codegen EXPLAIN 
(generated code for HopID: " +  cplan.getKey() +"):");
                                                LOG.info(src);
                                        }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/src/main/java/org/apache/sysml/hops/codegen/cplan/CNode.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNode.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNode.java
index ac276b6..446da32 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNode.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNode.java
@@ -27,10 +27,13 @@ import 
org.apache.sysml.runtime.controlprogram.parfor.util.IDSequence;
 
 public abstract class CNode
 {
-       private static final IDSequence _seq = new IDSequence();
+       private static final IDSequence _seqVar = new IDSequence();
+       private static final IDSequence _seqID = new IDSequence();
        
+       protected final long _ID; 
        protected ArrayList<CNode> _inputs = null; 
        protected CNode _output = null; 
+       protected boolean _visited = false;
        protected boolean _generated = false;
        protected String _genVar = null;
        protected long _rows = -1;
@@ -43,21 +46,26 @@ public abstract class CNode
        protected int _hash = 0;
        
        public CNode() {
+               _ID = _seqID.getNextID();
                _inputs = new ArrayList<CNode>();
                _generated = false;
        }
+       
+       public long getID() {
+               return _ID;
+       }
 
        public ArrayList<CNode> getInput() {
                return _inputs;
        }
        
        public String createVarname() {
-               _genVar = "TMP"+_seq.getNextID();
+               _genVar = "TMP"+_seqVar.getNextID();
                return _genVar; 
        }
        
        protected String getCurrentVarName() {
-               return "TMP"+(_seq.getCurrentID()-1);
+               return "TMP"+(_seqVar.getCurrentID()-1);
        }
        
        public String getVarname() {
@@ -118,6 +126,26 @@ public abstract class CNode
                _hash = 0;
        }
        
+       public boolean isVisited() {
+               return _visited; 
+       }
+       
+       public void setVisited() {
+               setVisited(true);
+       }
+       
+       public void setVisited(boolean flag) {
+               _visited = flag;
+       }
+       
+       public void resetVisitStatus() {
+               if( !isVisited() )
+                       return;
+               for( CNode h : getInput() )
+                       h.resetVisitStatus();
+               setVisited(false);
+       }
+       
        public abstract String codegen(boolean sparse) ;
        
        public abstract void setOutputDims();

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
index fcd2d16..9da9915 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
@@ -181,10 +181,20 @@ public class CNodeBinary extends CNode
                        case VECT_DIV_ADD: return "b(vda)";
                        case MULT: return "b(*)";
                        case DIV: return "b(/)";
+                       case PLUS: return "b(+)";
+                       case MINUS: return "b(-)";
+                       case MODULUS: return "b(%%)";
+                       case INTDIV: return "b(%/%)";
+                       case LESS: return "b(<)";
+                       case LESSEQUAL: return "b(<=)";
+                       case GREATER: return "b(>)";
+                       case GREATEREQUAL: return "b(>=)";
+                       case EQUAL: return "b(==)";
+                       case NOTEQUAL: return "b(!=)";
+                       case MINUS1_MULT: return "b(1-*)";
                        case VECT_DIV_SCALAR:  return "b(vector/)";
                        case VECT_MULT_SCALAR:  return "b(vector*)";
-                       default:
-                               return super.toString();        
+                       default: return "b("+_type.name()+")";
                }
        }
        

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeCell.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeCell.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeCell.java
index 9fdaa62..db278e4 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeCell.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeCell.java
@@ -141,4 +141,14 @@ public class CNodeCell extends CNodeTpl
                return super.equals(that)
                        && _type == that._type;
        }
+       
+       @Override
+       public String getTemplateInfo() {
+               StringBuilder sb = new StringBuilder();
+               sb.append("SPOOF CELLWISE [type=");
+               sb.append(_type.name());
+               sb.append(", mc="+_multipleConsumers);
+               sb.append("]");
+               return sb.toString();
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeData.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeData.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeData.java
index d5457e8..6bf760f 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeData.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeData.java
@@ -72,7 +72,7 @@ public class CNodeData extends CNode
        
        @Override
        public String toString() {
-               return "CdataNode[name="+_name+", id="+_hopID+"]";
+               return "data("+_name+", hopid="+_hopID+")";
        }
        
        @Override

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeOuterProduct.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeOuterProduct.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeOuterProduct.java
index 6a543cc..addc20b 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeOuterProduct.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeOuterProduct.java
@@ -162,4 +162,14 @@ public class CNodeOuterProduct extends CNodeTpl
                        && _type == that._type
                        && _transposeOutput == that._transposeOutput;
        }
+       
+       @Override
+       public String getTemplateInfo() {
+               StringBuilder sb = new StringBuilder();
+               sb.append("SPOOF OUTERPRODUCT [type=");
+               sb.append(_type.name());
+               sb.append(", to="+_transposeOutput);
+               sb.append("]");
+               return sb.toString();
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRowAggVector.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRowAggVector.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRowAggVector.java
index 09967aa..d3a39e3 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRowAggVector.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRowAggVector.java
@@ -108,4 +108,11 @@ public class CNodeRowAggVector extends CNodeTpl
                return (o instanceof CNodeRowAggVector
                        && super.equals(o));
        }
+       
+       @Override
+       public String getTemplateInfo() {
+               StringBuilder sb = new StringBuilder();
+               sb.append("SPOOF ROWAGGREGATE");
+               return sb.toString();
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTpl.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTpl.java
index 343aba4..df20b4d 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTpl.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTpl.java
@@ -55,6 +55,13 @@ public abstract class CNodeTpl extends CNode implements 
Cloneable
                _inputs = tmp;
        }
        
+       public String[] getInputNames() {
+               String[] ret = new String[_inputs.size()];
+               for( int i=0; i<_inputs.size(); i++ )
+                       ret[i] = _inputs.get(i).getVarname();
+               return ret;
+       }
+       
        public String codegen() {
                return codegen(false);
        }
@@ -63,6 +70,8 @@ public abstract class CNodeTpl extends CNode implements 
Cloneable
        
        public abstract SpoofOutputDimsType getOutputDimType();
        
+       public abstract String getTemplateInfo();
+       
        protected void renameInputs(ArrayList<CNode> inputs, int startIndex) {
                //create map of hopID to data nodes with new names, used for CSE
                HashMap<Long, CNode> nodes = new HashMap<Long, CNode>();

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
index f491609..5d4c63e 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
@@ -156,9 +156,11 @@ public class CNodeUnary extends CNode
        @Override
        public String toString() {
                switch(_type) {
-                       case ROW_SUMS: return "u(R+)";
-                       default:
-                               return super.toString();
+                       case ROW_SUMS:  return "u(R+)";
+                       case LOOKUP_R:  return "u(ixr)";
+                       case LOOKUP_RC: return "u(ixrc)";
+                       case LOOKUP0:   return "u(ix0)";
+                       default:                return "u("+_type.name()+")";
                }
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/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 da13d0a..f8b2a62 100644
--- a/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java
+++ b/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java
@@ -215,7 +215,7 @@ public class Recompiler
                        // codegen if enabled
                        if( 
ConfigurationManager.getDMLConfig().getBooleanValue(DMLConfig.CODEGEN) && 
SpoofCompiler.RECOMPILE ) {
                                Hop.resetVisitStatus(hops);
-                               hops = SpoofCompiler.optimize(hops, 
SpoofCompiler.ALWAYS_COMPILE_LITERALS);
+                               hops = SpoofCompiler.optimize(hops, true);
                        }
                        
                        // construct lops                       

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/src/main/java/org/apache/sysml/utils/Explain.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/utils/Explain.java 
b/src/main/java/org/apache/sysml/utils/Explain.java
index ccc9853..a03ad73 100644
--- a/src/main/java/org/apache/sysml/utils/Explain.java
+++ b/src/main/java/org/apache/sysml/utils/Explain.java
@@ -32,6 +32,8 @@ import org.apache.sysml.hops.Hop.VisitStatus;
 import org.apache.sysml.hops.HopsException;
 import org.apache.sysml.hops.LiteralOp;
 import org.apache.sysml.hops.OptimizerUtils;
+import org.apache.sysml.hops.codegen.cplan.CNode;
+import org.apache.sysml.hops.codegen.cplan.CNodeTpl;
 import org.apache.sysml.hops.globalopt.gdfgraph.GDFLoopNode;
 import org.apache.sysml.hops.globalopt.gdfgraph.GDFNode;
 import org.apache.sysml.hops.globalopt.gdfgraph.GDFNode.NodeType;
@@ -85,7 +87,14 @@ public class Explain
                HOPS,     // explain program and hops
                RUNTIME,  // explain runtime program (default)
                RECOMPILE_HOPS, // explain hops, incl recompile
-               RECOMPILE_RUNTIME, // explain runtime program, incl recompile 
+               RECOMPILE_RUNTIME;  // explain runtime program, incl recompile 
+
+               public boolean isHopsType(boolean recompile) {
+                       return (this==RECOMPILE_HOPS || (!recompile && 
this==HOPS));
+               }
+               public boolean isRuntimeType(boolean recompile) {
+                       return (this==RECOMPILE_RUNTIME || (!recompile && 
this==RUNTIME));
+               }
        };
        
        public static class ExplainCounts {
@@ -359,6 +368,34 @@ public class Explain
                
                return ret;
        }
+       
+       public static String explainCPlan( CNodeTpl cplan ) 
+               throws DMLRuntimeException 
+       {
+               StringBuilder sb = new StringBuilder();
+               
+               //create template header
+               sb.append("\n----------------------------------------\n");
+               sb.append("CPLAN: "+cplan.getTemplateInfo()+"\n");
+               sb.append("--inputs: 
"+Arrays.toString(cplan.getInputNames())+"\n");
+               sb.append("----------------------------------------\n");
+               
+               //explain body dag
+               cplan.getOutput().resetVisitStatus();
+               sb.append(explainCNode(cplan.getOutput(), 1));
+               cplan.getOutput().resetVisitStatus();
+               sb.append("----------------------------------------\n");
+               
+               return sb.toString();
+       }
+       
+       public static String explain( CNode node ) throws DMLRuntimeException {
+               return explain(node, 0);
+       }
+       
+       public static String explain( CNode node, int level ) throws 
DMLRuntimeException {
+               return explainCNode(node, level);
+       }
 
        public static String explainGDFNodes( ArrayList<GDFNode> gdfnodes ) 
                throws DMLRuntimeException
@@ -601,6 +638,52 @@ public class Explain
        }
 
        //////////////
+       // internal explain CNODE
+
+       private static String explainCNode(CNode cnode, int level) 
+               throws DMLRuntimeException 
+       {
+               if( cnode.isVisited() )
+                       return "";
+               
+               StringBuilder sb = new StringBuilder();
+               String offset = createOffset(level);
+               
+               for( CNode input : cnode.getInput() )
+                       sb.append(explainCNode(input, level));
+               
+               //indentation
+               sb.append(offset);
+               
+               //hop id
+               if( SHOW_DATA_DEPENDENCIES )
+                       sb.append("("+cnode.getID()+") ");
+               
+               //operation string
+               sb.append(cnode.toString());
+               
+               //input hop references 
+               if( SHOW_DATA_DEPENDENCIES ) {
+                       StringBuilder childs = new StringBuilder();
+                       childs.append(" (");
+                       boolean childAdded = false;
+                       for( CNode input : cnode.getInput() ) {
+                               childs.append(childAdded?",":"");
+                               childs.append(input.getID());
+                               childAdded = true;
+                       }
+                       childs.append(")");             
+                       if( childAdded )
+                               sb.append(childs.toString());
+               }
+               
+               sb.append('\n');
+               cnode.setVisited();
+               
+               return sb.toString();
+       }
+       
+       //////////////
        // internal explain GDFNODE
 
        /**

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/src/test/java/org/apache/sysml/test/integration/functions/codegen/DAGCellwiseTmplTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/sysml/test/integration/functions/codegen/DAGCellwiseTmplTest.java
 
b/src/test/java/org/apache/sysml/test/integration/functions/codegen/DAGCellwiseTmplTest.java
index 65be916..cb2f480 100644
--- 
a/src/test/java/org/apache/sysml/test/integration/functions/codegen/DAGCellwiseTmplTest.java
+++ 
b/src/test/java/org/apache/sysml/test/integration/functions/codegen/DAGCellwiseTmplTest.java
@@ -135,7 +135,7 @@ public class DAGCellwiseTmplTest extends AutomatedTestBase
                        
                        String HOME = SCRIPT_DIR + TEST_DIR;
                        fullDMLScriptName = HOME + testname + ".dml";
-                       programArgs = new String[]{"-explain", "runtime", 
"-stats", 
+                       programArgs = new String[]{"-explain", "hops", 
"-stats", 
                                        "-config=" + HOME + TEST_CONF, "-args", 
String.valueOf(cols), output("S") };
                        
                        fullRScriptName = HOME + testname + ".R";

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/e449cae6/src/test/java/org/apache/sysml/test/integration/functions/codegen/SumProductChainTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/sysml/test/integration/functions/codegen/SumProductChainTest.java
 
b/src/test/java/org/apache/sysml/test/integration/functions/codegen/SumProductChainTest.java
index 2ba9ffa..35dfa82 100644
--- 
a/src/test/java/org/apache/sysml/test/integration/functions/codegen/SumProductChainTest.java
+++ 
b/src/test/java/org/apache/sysml/test/integration/functions/codegen/SumProductChainTest.java
@@ -118,7 +118,7 @@ public class SumProductChainTest extends AutomatedTestBase
                        
                        String HOME = SCRIPT_DIR + TEST_DIR;
                        fullDMLScriptName = HOME + testname + ".dml";
-                       programArgs = new String[]{"-explain", "-stats", 
+                       programArgs = new String[]{"-explain", "hops", 
"-stats", 
                                        "-config=" + HOME + TEST_CONF, "-args", 
input("X"), output("R") };
                        
                        fullRScriptName = HOME + testname + ".R";

Reply via email to