Repository: incubator-systemml
Updated Branches:
  refs/heads/master a929ae6e6 -> 0dd095ffb


[MINOR] Fix code generator (templates, existing ops, input ordering)

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

Branch: refs/heads/master
Commit: 0dd095ffb8a951ccdd52e889d3dcb4bfb2c95545
Parents: a929ae6
Author: Matthias Boehm <[email protected]>
Authored: Fri Mar 24 19:32:08 2017 -0700
Committer: Matthias Boehm <[email protected]>
Committed: Fri Mar 24 19:32:08 2017 -0700

----------------------------------------------------------------------
 .../sysml/hops/codegen/cplan/CNodeTernary.java  |  2 +-
 .../sysml/hops/codegen/template/CellTpl.java    | 47 +++++++++++++++-----
 .../sysml/hops/codegen/template/RowAggTpl.java  | 37 ++++++++++++---
 .../hops/codegen/template/TemplateUtils.java    |  9 ++--
 .../sysml/runtime/codegen/SpoofOperator.java    |  4 +-
 5 files changed, 76 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/0dd095ff/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTernary.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTernary.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTernary.java
index c9b389d..eb26eff 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTernary.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTernary.java
@@ -43,7 +43,7 @@ public class CNodeTernary extends CNode
                                        return "    double %TMP% = %IN1% + 
%IN2% * %IN3%;\n" ;
                                
                                case MINUS_MULT:
-                                       return "    double %TMP% = %IN1% - 
%IN2% * %IN3%;\n;\n" ;
+                                       return "    double %TMP% = %IN1% - 
%IN2% * %IN3%;\n" ;
                                        
                                case LOOKUP_RC1:
                                        return "    double %TMP% = 
%IN1%[rowIndex*%IN2%+%IN3%-1];\n";   

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/0dd095ff/src/main/java/org/apache/sysml/hops/codegen/template/CellTpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/template/CellTpl.java 
b/src/main/java/org/apache/sysml/hops/codegen/template/CellTpl.java
index c645eed..b919b6d 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/template/CellTpl.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/template/CellTpl.java
@@ -20,9 +20,11 @@
 package org.apache.sysml.hops.codegen.template;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
 
 import org.apache.sysml.hops.AggBinaryOp;
 import org.apache.sysml.hops.AggUnaryOp;
@@ -98,15 +100,12 @@ public class CellTpl extends BaseTpl
                rConstructCplan(hop, memo, tmp, inHops, compileLiterals);
                hop.resetVisitStatus();
                
-               //reorder inputs (ensure matrices/vectors come first, prune 
literals)
-               LinkedList<Hop> sinHops = new LinkedList<Hop>();
-               for( int i : new int[]{0,1,2} ) //matrices, vectors, scalars
-                       for( Hop h : inHops ) //matrices
-                               if( (i==0 && h.getDataType().isMatrix() && 
!TemplateUtils.isVector(h))
-                                       || (i==1 && h.getDataType().isMatrix() 
&& TemplateUtils.isVector(h))
-                                       || (i==2 && h.getDataType().isScalar() 
&& !tmp.get(h.getHopID()).isLiteral())) {
-                                       sinHops.add(h);
-                               }
+               //reorder inputs (ensure matrices/vectors come first) and prune 
literals
+               //note: we order by number of cells and subsequently sparsity 
to ensure
+               //that sparse inputs are used as the main input w/o unnecessary 
conversion
+               List<Hop> sinHops = inHops.stream()
+                       .filter(h -> !(h.getDataType().isScalar() && 
tmp.get(h.getHopID()).isLiteral()))
+                       .sorted(new 
HopInputComparator()).collect(Collectors.toList());
                
                //construct template node
                ArrayList<CNode> inputs = new ArrayList<CNode>();
@@ -115,8 +114,8 @@ public class CellTpl extends BaseTpl
                CNode output = tmp.get(hop.getHopID());
                CNodeCell tpl = new CNodeCell(inputs, output);
                tpl.setCellType(TemplateUtils.getCellType(hop));
-               tpl.setSparseSafe((HopRewriteUtils.isBinary(hop, OpOp2.MULT) && 
hop.getInput().contains(sinHops.getFirst()))
-                               || (HopRewriteUtils.isBinary(hop, OpOp2.DIV) && 
hop.getInput().get(0) == sinHops.getFirst()));
+               tpl.setSparseSafe((HopRewriteUtils.isBinary(hop, OpOp2.MULT) && 
hop.getInput().contains(sinHops.get(0)))
+                               || (HopRewriteUtils.isBinary(hop, OpOp2.DIV) && 
hop.getInput().get(0) == sinHops.get(0)));
                tpl.setRequiresCastDtm(hop instanceof AggBinaryOp);
                
                // return cplan instance
@@ -278,4 +277,28 @@ public class CellTpl extends BaseTpl
                                || isBinaryMatrixScalar || isBinaryMatrixVector 
|| isBinaryMatrixMatrixDense 
                                || isTernaryVectorScalarVector || 
isTernaryMatrixScalarMatrixDense);    
        }
+       
+       /**
+        * Comparator to order input hops of the cell template. We try to order 
+        * matrices-vectors-scalars via sorting by number of cells and for 
+        * equal number of cells by sparsity to prefer sparse inputs as the 
main 
+        * input for sparsity exploitation.
+        */
+       public static class HopInputComparator implements Comparator<Hop> 
+       {
+               @Override
+               public int compare(Hop h1, Hop h2) {
+                       long ncells1 = h1.getDataType()==DataType.SCALAR ? 
Long.MIN_VALUE : 
+                               h1.dimsKnown() ? h1.getDim1()*h1.getDim2() : 
Long.MAX_VALUE;
+                       long ncells2 = h2.getDataType()==DataType.SCALAR ? 
Long.MIN_VALUE :
+                               h2.dimsKnown() ? h2.getDim1()*h2.getDim2() : 
Long.MAX_VALUE;
+                       if( ncells1 > ncells2 ) 
+                               return -1;
+                       else if( ncells1 < ncells2) 
+                               return 1;
+                       return Long.compare(
+                               h1.dimsKnown(true) ? h1.getNnz() : ncells1, 
+                               h2.dimsKnown(true) ? h2.getNnz() : ncells2);
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/0dd095ff/src/main/java/org/apache/sysml/hops/codegen/template/RowAggTpl.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/hops/codegen/template/RowAggTpl.java 
b/src/main/java/org/apache/sysml/hops/codegen/template/RowAggTpl.java
index 1aa380b..c16c831 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/template/RowAggTpl.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/template/RowAggTpl.java
@@ -20,9 +20,11 @@
 package org.apache.sysml.hops.codegen.template;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
 
 import org.apache.sysml.hops.AggBinaryOp;
 import org.apache.sysml.hops.AggUnaryOp;
@@ -100,10 +102,10 @@ public class RowAggTpl extends BaseTpl {
                rConstructCplan(hop, memo, tmp, inHops, inHops2, 
compileLiterals);
                hop.resetVisitStatus();
                
-               //reorder inputs (ensure matrix is first input)
-               LinkedList<Hop> sinHops = new LinkedList<Hop>(inHops);
-               Hop X = inHops2.get("X");
-               sinHops.remove(X); sinHops.addFirst(X);
+               //reorder inputs (ensure matrix is first input, and other 
inputs ordered by size)
+               List<Hop> sinHops = inHops.stream()
+                       .filter(h -> !(h.getDataType().isScalar() && 
tmp.get(h.getHopID()).isLiteral()))
+                       .sorted(new 
HopInputComparator(inHops2.get("X"))).collect(Collectors.toList());
                
                //construct template node
                ArrayList<CNode> inputs = new ArrayList<CNode>();
@@ -216,4 +218,29 @@ public class RowAggTpl extends BaseTpl {
                
                tmp.put(hop.getHopID(), out);
        }
+       
+       /**
+        * Comparator to order input hops of the row aggregate template. We try 
+        * to order matrices-vectors-scalars via sorting by number of cells but 
+        * we keep the given main input always at the first position.
+        */
+       public static class HopInputComparator implements Comparator<Hop> 
+       {
+               private final Hop _X;
+               
+               public HopInputComparator(Hop X) {
+                       _X = X;
+               }
+               
+               @Override
+               public int compare(Hop h1, Hop h2) {
+                       long ncells1 = h1.getDataType()==DataType.SCALAR ? 
Long.MIN_VALUE : 
+                               (h1==_X) ? Long.MAX_VALUE : 
+                               h1.dimsKnown() ? h1.getDim1()*h1.getDim2() : 
Long.MAX_VALUE-1;
+                       long ncells2 = h2.getDataType()==DataType.SCALAR ? 
Long.MIN_VALUE : 
+                               (h2==_X) ? Long.MAX_VALUE : 
+                               h2.dimsKnown() ? h2.getDim1()*h2.getDim2() : 
Long.MAX_VALUE-1;
+                       return (ncells1 > ncells2) ? -1 : (ncells1 < ncells2) ? 
1 : 0; 
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/0dd095ff/src/main/java/org/apache/sysml/hops/codegen/template/TemplateUtils.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateUtils.java 
b/src/main/java/org/apache/sysml/hops/codegen/template/TemplateUtils.java
index 862c4f6..6c2fe8d 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateUtils.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/template/TemplateUtils.java
@@ -254,13 +254,16 @@ public class TemplateUtils
        public static boolean hasSingleOperation(CNodeTpl tpl) {
                CNode output = tpl.getOutput();
                return (output instanceof CNodeUnary || output instanceof 
CNodeBinary
-                               || output instanceof CNodeTernary) && 
hasOnlyDataNodeInputs(output);
+                               || output instanceof CNodeTernary) && 
hasOnlyDataNodeOrLookupInputs(output);
        }
        
-       public static boolean hasOnlyDataNodeInputs(CNode node) {
+       public static boolean hasOnlyDataNodeOrLookupInputs(CNode node) {
                boolean ret = true;
                for( CNode c : node.getInput() )
-                       ret &= (c instanceof CNodeData);
+                       ret &= (c instanceof CNodeData || (c instanceof 
CNodeUnary 
+                               && 
(((CNodeUnary)c).getType()==UnaryType.LOOKUP0 
+                                       || 
((CNodeUnary)c).getType()==UnaryType.LOOKUP_R 
+                                       || 
((CNodeUnary)c).getType()==UnaryType.LOOKUP_RC)));
                return ret;
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/0dd095ff/src/main/java/org/apache/sysml/runtime/codegen/SpoofOperator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/codegen/SpoofOperator.java 
b/src/main/java/org/apache/sysml/runtime/codegen/SpoofOperator.java
index 8cb6692..6142396 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/SpoofOperator.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/SpoofOperator.java
@@ -72,8 +72,8 @@ public abstract class SpoofOperator implements Serializable
                                || inputs.get(i).isInSparseFormat() ) {
                                MatrixBlock tmp = inputs.get(i);
                                b[i-offset] = 
DataConverter.convertToDoubleVector(tmp);
-                               LOG.warn("Converted 
"+tmp.getNumRows()+"x"+tmp.getNumColumns() + 
-                                               " sideways input matrix from 
sparse to dense.");
+                               LOG.warn(getClass().getName()+": Converted 
"+tmp.getNumRows()+"x"+tmp.getNumColumns()+
+                                               ", nnz="+tmp.getNonZeros()+" 
sideways input matrix from sparse to dense.");
                        }
                        //use existing dense block
                        else {

Reply via email to