[SYSTEMML-1963] Fix missing codegen dense-sparse vector primitives

This patch fixes issues that showed up with the fuse-all heuristic on
different scenarios of ALS-CG. In particular, this adds missing vector
primitives for dense-sparse vector operations and modifies the code
generator accordingly. Most of these operations are invariant to the
ordering of inputs and hence simply call the existing primitives with
permuted inputs.


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

Branch: refs/heads/master
Commit: b6b67727b9ec271995520e47dc3044eccaed2b65
Parents: 06b4b9d
Author: Matthias Boehm <mboe...@gmail.com>
Authored: Sun Oct 15 20:27:51 2017 -0700
Committer: Matthias Boehm <mboe...@gmail.com>
Committed: Sun Oct 15 20:27:51 2017 -0700

----------------------------------------------------------------------
 .../sysml/hops/codegen/cplan/CNodeBinary.java   | 33 ++++-----
 .../runtime/codegen/LibSpoofPrimitives.java     | 70 ++++++++++++++++++++
 2 files changed, 88 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/systemml/blob/b6b67727/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 1ca4aa6..cac8ab8 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
@@ -68,16 +68,16 @@ public class CNodeBinary extends CNode
                        return ssComm || vsComm || vvComm;
                }
                
-               public String getTemplate(boolean sparse, boolean scalarVector, 
boolean scalarInput) {
+               public String getTemplate(boolean sparseLhs, boolean sparseRhs, 
boolean scalarVector, boolean scalarInput) {
                        switch (this) {
                                case DOT_PRODUCT:   
-                                       return sparse ? "    double %TMP% = 
LibSpoofPrimitives.dotProduct(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, alen);\n" :
+                                       return sparseLhs ? "    double %TMP% = 
LibSpoofPrimitives.dotProduct(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, alen);\n" :
                                                                        "    
double %TMP% = LibSpoofPrimitives.dotProduct(%IN1%, %IN2%, %POS1%, %POS2%, 
%LEN%);\n";
                                case VECT_MATRIXMULT:   
-                                       return sparse ? "    double[] %TMP% = 
LibSpoofPrimitives.vectMatrixMult(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, alen, 
len);\n" :
+                                       return sparseLhs ? "    double[] %TMP% 
= LibSpoofPrimitives.vectMatrixMult(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, 
alen, len);\n" :
                                                                        "    
double[] %TMP% = LibSpoofPrimitives.vectMatrixMult(%IN1%, %IN2%, %POS1%, 
%POS2%, %LEN%);\n";
                                case VECT_OUTERMULT_ADD:   
-                                       return sparse ? "    
LibSpoofPrimitives.vectOuterMultAdd(%IN1v%, %IN2%, %OUT%, %IN1i%, %POS1%, 
%POS2%, %POSOUT%, alen, %LEN1%, %LEN2%);\n" :
+                                       return sparseLhs ? "    
LibSpoofPrimitives.vectOuterMultAdd(%IN1v%, %IN2%, %OUT%, %IN1i%, %POS1%, 
%POS2%, %POSOUT%, alen, %LEN1%, %LEN2%);\n" :
                                                                        "    
LibSpoofPrimitives.vectOuterMultAdd(%IN1%, %IN2%, %OUT%, %POS1%, %POS2%, 
%POSOUT%, %LEN1%, %LEN2%);\n";
                                
                                //vector-scalar-add operations
@@ -96,10 +96,10 @@ public class CNodeBinary extends CNode
                                case VECT_GREATEREQUAL_ADD: {
                                        String vectName = 
getVectorPrimitiveName();
                                        if( scalarVector )
-                                               return sparse ? "    
LibSpoofPrimitives.vect"+vectName+"Add(%IN1%, %IN2v%, %OUT%, %IN2i%, %POS2%, 
%POSOUT%, alen, %LEN%);\n" : 
+                                               return sparseLhs ? "    
LibSpoofPrimitives.vect"+vectName+"Add(%IN1%, %IN2v%, %OUT%, %IN2i%, %POS2%, 
%POSOUT%, alen, %LEN%);\n" : 
                                                                                
"    LibSpoofPrimitives.vect"+vectName+"Add(%IN1%, %IN2%, %OUT%, %POS2%, 
%POSOUT%, %LEN%);\n";
                                        else    
-                                               return sparse ? "    
LibSpoofPrimitives.vect"+vectName+"Add(%IN1v%, %IN2%, %OUT%, %IN1i%, %POS1%, 
%POSOUT%, alen, %LEN%);\n" : 
+                                               return sparseLhs ? "    
LibSpoofPrimitives.vect"+vectName+"Add(%IN1v%, %IN2%, %OUT%, %IN1i%, %POS1%, 
%POSOUT%, alen, %LEN%);\n" : 
                                                                                
"    LibSpoofPrimitives.vect"+vectName+"Add(%IN1%, %IN2%, %OUT%, %POS1%, 
%POSOUT%, %LEN%);\n";
                                }
                                
@@ -119,10 +119,10 @@ public class CNodeBinary extends CNode
                                case VECT_GREATEREQUAL_SCALAR: {
                                        String vectName = 
getVectorPrimitiveName();
                                        if( scalarVector )
-                                               return sparse ? "    double[] 
%TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2v%, %IN2i%, %POS2%, 
alen, %LEN%);\n" : 
+                                               return sparseLhs ? "    
double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2v%, 
%IN2i%, %POS2%, alen, %LEN%);\n" : 
                                                                                
"    double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2%, 
%POS2%, %LEN%);\n";
                                        else    
-                                               return sparse ? "    double[] 
%TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN2%, %IN1i%, %POS1%, 
alen, %LEN%);\n" : 
+                                               return sparseLhs ? "    
double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN2%, 
%IN1i%, %POS1%, alen, %LEN%);\n" : 
                                                                                
"    double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2%, 
%POS1%, %LEN%);\n";
                                }
                                
@@ -130,7 +130,7 @@ public class CNodeBinary extends CNode
                                        if( scalarInput )
                                                return  "    double[] %TMP% = 
LibSpoofPrimitives.vectCBindWrite(%IN1%, %IN2%);\n";
                                        else
-                                               return sparse ? 
+                                               return sparseLhs ? 
                                                                "    double[] 
%TMP% = LibSpoofPrimitives.vectCBindWrite(%IN1v%, %IN2%, %IN1i%, %POS1%, alen, 
%LEN%);\n" : 
                                                                "    double[] 
%TMP% = LibSpoofPrimitives.vectCBindWrite(%IN1%, %IN2%, %POS1%, %LEN%);\n";
                                
@@ -140,7 +140,7 @@ public class CNodeBinary extends CNode
                                case VECT_MINUS:
                                case VECT_PLUS:
                                case VECT_MIN:
-                               case VECT_MAX:  
+                               case VECT_MAX:
                                case VECT_EQUAL:
                                case VECT_NOTEQUAL:
                                case VECT_LESS:
@@ -148,8 +148,10 @@ public class CNodeBinary extends CNode
                                case VECT_GREATER:
                                case VECT_GREATEREQUAL: {
                                        String vectName = 
getVectorPrimitiveName();
-                                       return sparse ? 
+                                       return sparseLhs ? 
                                                "    double[] %TMP% = 
LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, 
alen, %LEN%);\n" : 
+                                                  sparseRhs ?
+                                               "    double[] %TMP% = 
LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2v%, %POS1%, %IN2i%, %POS2%, 
alen, %LEN%);\n" : 
                                                "    double[] %TMP% = 
LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2%, %POS1%, %POS2%, 
%LEN%);\n";
                                }
                                
@@ -269,14 +271,15 @@ public class CNodeBinary extends CNode
                sb.append(_inputs.get(1).codegen(sparse));
                
                //generate binary operation (use sparse template, if data input)
-               boolean lsparse = sparse 
-                       && ((_inputs.get(0) instanceof CNodeData && 
_inputs.get(0).getVarname().startsWith("a"))
-                       ||(_inputs.get(1) instanceof CNodeData && 
_inputs.get(1).getVarname().startsWith("a")));
+               boolean lsparseLhs = sparse && _inputs.get(0) instanceof 
CNodeData 
+                       && _inputs.get(0).getVarname().startsWith("a");
+               boolean lsparseRhs = sparse && _inputs.get(1) instanceof 
CNodeData 
+                       && _inputs.get(1).getVarname().startsWith("a"); 
                boolean scalarInput = _inputs.get(0).getDataType().isScalar();
                boolean scalarVector = (_inputs.get(0).getDataType().isScalar()
                        && _inputs.get(1).getDataType().isMatrix());
                String var = createVarname();
-               String tmp = _type.getTemplate(lsparse, scalarVector, 
scalarInput);
+               String tmp = _type.getTemplate(lsparseLhs, lsparseRhs, 
scalarVector, scalarInput);
                tmp = tmp.replace("%TMP%", var);
                
                //replace input references and start indexes

http://git-wip-us.apache.org/repos/asf/systemml/blob/b6b67727/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java 
b/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
index 6b4aad7..8444b5f 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
@@ -183,6 +183,11 @@ public class LibSpoofPrimitives
                return c;
        }
        
+       public static double[] vectMultWrite(double[] a, double[] b, int ai, 
int[] bix, int bi, int blen, int len) {
+               //invariant to the ordering of inputs
+               return vectMultWrite(b, a, bix, ai, bi, blen, len);
+       }
+       
        public static void vectWrite(double[] a, double[] c, int ci, int len) {
                if( a == null ) return;
                System.arraycopy(a, 0, c, ci, len);
@@ -345,6 +350,18 @@ public class LibSpoofPrimitives
                return c;
        }
        
+       public static double[] vectDivWrite(double[] a, double[] b, int ai, 
int[] bix, int bi, int blen, int len) {
+               double[] c = allocVector(len, false);
+               for( int j = 0; j < len; j++ ) {
+                       double aval = a[bi + j];
+                       c[j] = (aval==0) ? Double.NaN : (aval>0) ? 
+                               Double.POSITIVE_INFINITY : 
Double.NEGATIVE_INFINITY;
+               }
+               for( int j = bi; j < bi+blen; j++ )
+                       c[bix[j]] = a[ai+bix[j]] / b[j];
+               return c;
+       }
+       
        //custom vector minus
        
        public static void vectMinusAdd(double[] a, double bval, double[] c, 
int ai, int ci, int len) {
@@ -417,6 +434,14 @@ public class LibSpoofPrimitives
                return c;
        }
        
+       public static double[] vectMinusWrite(double[] a, double[] b, int ai, 
int[] bix, int bi, int blen, int len) {
+               double[] c = allocVector(len, false);
+               System.arraycopy(a, ai, c, 0, len);
+               for( int j = bi; j < bi+blen; j++ )
+                       c[bix[j]] -= b[j];
+               return c;
+       }
+       
        //custom vector plus
        
        public static void vectPlusAdd(double[] a, double bval, double[] c, int 
ai, int ci, int len) {
@@ -475,6 +500,11 @@ public class LibSpoofPrimitives
                return c;
        }
        
+       public static double[] vectPlusWrite(double[] a, double[] b, int ai, 
int[] bix, int bi, int blen, int len) {
+               //invariant to the ordering of inputs
+               return vectPlusWrite(b, a, bix, bi, ai, blen, len);
+       }
+       
        //custom vector pow
        
        public static void vectPowAdd(double[] a, double bval, double[] c, int 
ai, int ci, int len) {
@@ -600,6 +630,11 @@ public class LibSpoofPrimitives
                return c;
        }
        
+       public static double[] vectMinWrite(double[] a, double[] b, int ai, 
int[] bix, int bi, int blen, int len) {
+               //invariant to the ordering of inputs
+               return vectMinWrite(b, a, bix, bi, ai, blen, len);
+       }
+       
        //custom vector max
        
        public static void vectMaxAdd(double[] a, double bval, double[] c, int 
ai, int ci, int len) {
@@ -661,6 +696,11 @@ public class LibSpoofPrimitives
                        c[aix[j]] = Math.max(a[j], b[bi + aix[j]]);
                return c;
        }
+       
+       public static double[] vectMaxWrite(double[] a, double[] b, int ai, 
int[] bix, int bi, int blen, int len) {
+               //invariant to the ordering of inputs
+               return vectMaxWrite(b, a, bix, bi, ai, blen, len);
+       }
 
        //custom exp
        
@@ -1385,6 +1425,11 @@ public class LibSpoofPrimitives
                return c;
        }
        
+       public static double[] vectEqualWrite(double[] a, double[] b, int ai, 
int[] bix, int bi, int blen, int len) {
+               //invariant to the ordering of inputs
+               return vectEqualWrite(b, a, bix, bi, ai, blen, len);
+       }
+       
        //custom vector not equal
        
        public static void vectNotequalAdd(double[] a, double bval, double[] c, 
int ai, int ci, int len) {
@@ -1448,6 +1493,11 @@ public class LibSpoofPrimitives
                return c;
        }
        
+       public static double[] vectNotequalWrite(double[] a, double[] b, int 
ai, int[] bix, int bi, int blen, int len) {
+               //invariant to the ordering of inputs
+               return vectNotequalWrite(b, a, bix, bi, ai, blen, len);
+       }
+       
        //custom vector less
        
        public static void vectLessAdd(double[] a, double bval, double[] c, int 
ai, int ci, int len) {
@@ -1511,6 +1561,11 @@ public class LibSpoofPrimitives
                return c;
        }
        
+       public static double[] vectLessWrite(double[] a, double[] b, int ai, 
int[] bix, int bi, int blen, int len) {
+               //invariant to the ordering of inputs
+               return vectGreaterequalWrite(b, a, bix, bi, ai, blen, len);
+       }
+       
        //custom vector less equal
        
        public static void vectLessequalAdd(double[] a, double bval, double[] 
c, int ai, int ci, int len) {
@@ -1573,6 +1628,11 @@ public class LibSpoofPrimitives
                        c[aix[j]] = (a[j] <= b[bi+aix[j]]) ? 1 : 0;
                return c;
        }
+       
+       public static double[] vectLessequalWrite(double[] a, double[] b, int 
ai, int[] bix, int bi, int blen, int len) {
+               //invariant to the ordering of inputs
+               return vectGreaterWrite(b, a, bix, bi, ai, blen, len);
+       }
 
        //custom vector greater
        
@@ -1637,6 +1697,11 @@ public class LibSpoofPrimitives
                return c;
        }
        
+       public static double[] vectGreaterWrite(double[] a, double[] b, int ai, 
int[] bix, int bi, int blen, int len) {
+               //invariant to the ordering of inputs
+               return vectLessequalWrite(b, a, bix, bi, ai, blen, len);
+       }
+       
        //custom vector greater equal
        
        public static void vectGreaterequalAdd(double[] a, double bval, 
double[] c, int ai, int ci, int len) {
@@ -1700,6 +1765,11 @@ public class LibSpoofPrimitives
                return c;
        }
        
+       public static double[] vectGreaterequalWrite(double[] a, double[] b, 
int ai, int[] bix, int bi, int blen, int len) {
+               //invariant to the ordering of inputs
+               return vectLessWrite(b, a, bix, bi, ai, blen, len);
+       }
+       
        //complex builtin functions that are not directly generated
        //(included here in order to reduce the number of imports)
        

Reply via email to