[SYSTEMML-1714] Extended codegen row-wise (scalar-vector, main input) This patch extends the code generator row-wise template with scalar-vector primitives for all operations, improves the selection of the main input in row templates, and improves robustness of the related runtime operator for sparse inputs w/ empty rows.
Project: http://git-wip-us.apache.org/repos/asf/systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/728bf19e Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/728bf19e Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/728bf19e Branch: refs/heads/master Commit: 728bf19eaa567eb9e9b195ce0e70f58e6387d463 Parents: 723a751 Author: Matthias Boehm <[email protected]> Authored: Sat Jun 17 00:29:50 2017 -0700 Committer: Matthias Boehm <[email protected]> Committed: Sat Jun 17 13:11:36 2017 -0700 ---------------------------------------------------------------------- .../sysml/hops/codegen/cplan/CNodeBinary.java | 3 +- .../hops/codegen/template/TemplateRow.java | 9 +- .../runtime/codegen/LibSpoofPrimitives.java | 260 ++++++++++++++++++- .../sysml/runtime/codegen/SpoofRowwise.java | 18 +- .../functions/codegen/RowAggTmplTest.java | 20 +- .../scripts/functions/codegen/rowAggPattern20.R | 32 +++ .../functions/codegen/rowAggPattern20.dml | 27 ++ 7 files changed, 350 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/systemml/blob/728bf19e/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 0c7883a..ac0ea6f 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 @@ -237,7 +237,8 @@ public class CNodeBinary extends CNode //generate binary operation (use sparse template, if data input) boolean lsparse = sparse && (_inputs.get(0) instanceof CNodeData - && !_inputs.get(0).getVarname().startsWith("b")); + && !_inputs.get(0).getVarname().startsWith("b") + && !_inputs.get(0).isLiteral()); String var = createVarname(); String tmp = _type.getTemplate(lsparse); tmp = tmp.replaceAll("%TMP%", var); http://git-wip-us.apache.org/repos/asf/systemml/blob/728bf19e/src/main/java/org/apache/sysml/hops/codegen/template/TemplateRow.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateRow.java b/src/main/java/org/apache/sysml/hops/codegen/template/TemplateRow.java index 8364fba..ca10569 100644 --- a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateRow.java +++ b/src/main/java/org/apache/sysml/hops/codegen/template/TemplateRow.java @@ -184,7 +184,8 @@ public class TemplateRow extends TemplateBase else { String opcode = "ROW_"+((AggUnaryOp)hop).getOp().name().toUpperCase()+"S"; out = new CNodeUnary(cdata1, UnaryType.valueOf(opcode)); - inHops2.put("X", hop.getInput().get(0)); + if( cdata1 instanceof CNodeData && inHops2.isEmpty() ) + inHops2.put("X", hop.getInput().get(0)); } } else if (((AggUnaryOp)hop).getDirection() == Direction.Col && ((AggUnaryOp)hop).getOp() == AggOp.SUM ) { @@ -233,6 +234,8 @@ public class TemplateRow extends TemplateBase if( HopRewriteUtils.isUnary(hop, SUPPORTED_VECT_UNARY) ) { String opname = "VECT_"+((UnaryOp)hop).getOp().name(); out = new CNodeUnary(cdata1, UnaryType.valueOf(opname)); + if( cdata1 instanceof CNodeData && inHops2.isEmpty() ) + inHops2.put("X", hop.getInput().get(0)); } else throw new RuntimeException("Unsupported unary matrix " @@ -274,6 +277,10 @@ public class TemplateRow extends TemplateBase cdata2 = new CNodeUnary(cdata2, UnaryType.LOOKUP_R); out = new CNodeBinary(cdata1, cdata2, BinType.valueOf(opname)); } + if( cdata1 instanceof CNodeData && inHops2.isEmpty() + && !(cdata1.getDataType()==DataType.SCALAR) ) { + inHops2.put("X", hop.getInput().get(0)); + } } else throw new RuntimeException("Unsupported binary matrix " http://git-wip-us.apache.org/repos/asf/systemml/blob/728bf19e/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 d0f71ce..8e2b4b6 100644 --- a/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java +++ b/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java @@ -48,56 +48,80 @@ public class LibSpoofPrimitives // forwarded calls to LibMatrixMult public static double dotProduct(double[] a, double[] b, int ai, int bi, int len) { - if( a == null || b == null ) - return 0; + if( a == null || b == null ) return 0; return LibMatrixMult.dotProduct(a, b, ai, bi, len); } public static double dotProduct(double[] a, double[] b, int[] aix, int ai, int bi, int len) { - if( a == null || b == null ) - return 0; + if( a == null || b == null ) return 0; return LibMatrixMult.dotProduct(a, b, aix, ai, bi, len); } public static void vectMultAdd(double[] a, double bval, double[] c, int bi, int ci, int len) { + if( a == null ) return; + LibMatrixMult.vectMultiplyAdd(bval, a, c, bi, ci, len); + } + + public static void vectMultAdd(double bval, double[] a, double[] c, int bi, int ci, int len) { + if( a == null ) return; LibMatrixMult.vectMultiplyAdd(bval, a, c, bi, ci, len); } public static void vectMultAdd(double[] a, double bval, double[] c, int[] bix, int bi, int ci, int len) { + if( a == null ) return; + LibMatrixMult.vectMultiplyAdd(bval, a, c, bix, bi, ci, len); + } + + public static void vectMultAdd(double bval, double[] a, double[] c, int[] bix, int bi, int ci, int len) { + if( a == null ) return; LibMatrixMult.vectMultiplyAdd(bval, a, c, bix, bi, ci, len); } public static void vectMultAdd(double[] a, double[] b, double[] c, int bi, int ci, int len) { + if( a == null || b == null ) return; double[] tmp = vectMultWrite(a, b, 0, bi, len); LibMatrixMult.vectAdd(tmp, c, 0, ci, len); } public static double[] vectMultWrite(double[] a, double bval, int bi, int len) { double[] c = allocVector(len, false); + if( a == null ) return c; LibMatrixMult.vectMultiplyWrite(bval, a, c, bi, 0, len); return c; } + public static double[] vectMultWrite(double bval, double[] a, int bi, int len) { + return vectMultWrite(a, bval, bi, len); + } + public static double[] vectMultWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); + if( a == null || b == null ) return c; LibMatrixMult.vectMultiplyWrite(a, b, c, ai, bi, 0, len); return c; } public static double[] vectMultWrite(double[] a, double bval, int[] bix, int bi, int len) { double[] c = allocVector(len, true); + if( a == null ) return c; LibMatrixMult.vectMultiplyAdd(bval, a, c, bix, bi, 0, len); return c; } + public static double[] vectMultWrite(double bval, double[] a, int[] bix, int bi, int len) { + return vectMultWrite(a, bval, bix, bi, len); + } + public static double[] vectMultWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); + if( a == null || b == null ) return c; for( int j = ai; j < ai+len; j++ ) c[aix[j]] = a[j] * b[bi+aix[j]]; return c; } public static void vectWrite(double[] a, double[] c, int ci, int len) { + if( a == null ) return; System.arraycopy(a, 0, c, ci, len); } @@ -178,12 +202,22 @@ public class LibSpoofPrimitives for( int j = ai; j < ai+len; j++, ci++) c[ci] += a[j] / bval; } + + public static void vectDivAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += bval / a[j]; + } public static void vectDivAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += a[j] / bval; } + public static void vectDivAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++ ) + c[ci + aix[j]] += bval / a[j]; + } + public static double[] vectDivWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -191,6 +225,13 @@ public class LibSpoofPrimitives return c; } + public static double[] vectDivWrite(double bval, double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = bval / a[ai] / bval; + return c; + } + public static double[] vectDivWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++, bi++) @@ -205,6 +246,13 @@ public class LibSpoofPrimitives return c; } + public static double[] vectDivWrite(double bval, double[] a, int[] aix, int ai, int len) { + double[] c = allocVector(len, true); + for( int j = ai; j < ai+len; j++ ) + c[aix[j]] = bval / a[j]; + return c; + } + public static double[] vectDivWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = ai; j < ai+len; j++ ) @@ -218,12 +266,22 @@ public class LibSpoofPrimitives for( int j = ai; j < ai+len; j++, ci++) c[ci] += a[j] - bval; } + + public static void vectMinusAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += bval - a[j]; + } public static void vectMinusAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += a[j] - bval; } + public static void vectMinusAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++ ) + c[ci + aix[j]] += bval - a[j]; + } + public static double[] vectMinusWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -231,6 +289,13 @@ public class LibSpoofPrimitives return c; } + public static double[] vectMinusWrite(double bval, double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = bval - a[ai]; + return c; + } + public static double[] vectMinusWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++, bi++) @@ -245,6 +310,13 @@ public class LibSpoofPrimitives return c; } + public static double[] vectMinusWrite(double bval, double[] a, int[] aix, int ai, int len) { + double[] c = allocVector(len, true); + for( int j = ai; j < ai+len; j++ ) + c[aix[j]] = bval - a[j]; + return c; + } + public static double[] vectMinusWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = ai; j < ai+len; j++ ) @@ -258,12 +330,20 @@ public class LibSpoofPrimitives for( int j = ai; j < ai+len; j++, ci++) c[ci] += a[j] + bval; } + + public static void vectPlusAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + vectPlusAdd(a, bval, c, ai, ci, len); + } public static void vectPlusAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += a[j] + bval; } + public static void vectPlusAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + vectPlusAdd(a, bval, c, aix, ai, ci, len); + } + public static double[] vectPlusWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -271,6 +351,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectPlusWrite(double bval, double[] a, int ai, int len) { + return vectPlusWrite(bval, a, ai, len); + } + public static double[] vectPlusWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -285,6 +369,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectPlusWrite(double bval, double[] a, int[] aix, int ai, int len) { + return vectPlusWrite(a, bval, aix, ai, len); + } + public static double[] vectPlusWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = ai; j < ai+len; j++ ) @@ -298,12 +386,22 @@ public class LibSpoofPrimitives for( int j = ai; j < ai+len; j++, ci++) c[ci] += Math.pow(a[j], bval); } + + public static void vectPowAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += Math.pow(bval, a[j]); + } public static void vectPowAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += Math.pow(a[j], bval); } + public static void vectPowAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++ ) + c[ci + aix[j]] += Math.pow(bval, a[j]); + } + public static double[] vectPowWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -311,6 +409,13 @@ public class LibSpoofPrimitives return c; } + public static double[] vectPowWrite(double bval, double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = Math.pow(bval, a[ai]); + return c; + } + public static double[] vectPowWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++, bi++) @@ -325,18 +430,33 @@ public class LibSpoofPrimitives return c; } + public static double[] vectPowWrite(double bval, double[] a, int[] aix, int ai, int len) { + double[] c = allocVector(len, true); + for( int j = ai; j < ai+len; j++ ) + c[aix[j]] = Math.pow(bval, a[j]); + return c; + } + //custom vector min public static void vectMinAdd(double[] a, double bval, double[] c, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++, ci++) c[ci] += Math.min(a[j], bval); } + + public static void vectMinAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + vectMinAdd(a, bval, c, ai, ci, len); + } public static void vectMinAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += Math.min(a[j], bval); } + public static void vectMinAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + vectMinAdd(a, bval, c, aix, ai, ci, len); + } + public static double[] vectMinWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -344,6 +464,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectMinWrite(double bval, double[] a, int ai, int len) { + return vectMinWrite(a, bval, ai, len); + } + public static double[] vectMinWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++, bi++) @@ -358,6 +482,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectMinWrite(double bval, double[] a, int[] aix, int ai, int len) { + return vectMinWrite(a, bval, aix, ai, len); + } + public static double[] vectMinWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = ai; j < ai+len; j++ ) @@ -371,12 +499,20 @@ public class LibSpoofPrimitives for( int j = ai; j < ai+len; j++, ci++) c[ci] += Math.max(a[j], bval); } + + public static void vectMaxAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + vectMaxAdd(a, bval, c, ai, ci, len); + } public static void vectMaxAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += Math.max(a[j], bval); } + public static void vectMaxAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + vectMaxAdd(a, bval, c, aix, ai, ci, len); + } + public static double[] vectMaxWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -384,6 +520,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectMaxWrite(double bval, double[] a, int ai, int len) { + return vectMaxWrite(a, bval, ai, len); + } + public static double[] vectMaxWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++, bi++) @@ -398,6 +538,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectMaxWrite(double bval, double[] a, int[] aix, int ai, int len) { + return vectMaxWrite(a, bval, aix, ai, len); + } + public static double[] vectMaxWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = ai; j < ai+len; j++ ) @@ -670,13 +814,21 @@ public class LibSpoofPrimitives public static void vectEqualAdd(double[] a, double bval, double[] c, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++, ci++) c[ci] += (a[j] == bval) ? 1 : 0; - } + } + + public static void vectEqualAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + vectEqualAdd(a, bval, c, ai, ci, len); + } public static void vectEqualAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += (a[j] == bval) ? 1 : 0; } + public static void vectEqualAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + vectEqualAdd(a, bval, c, aix, ai, ci, len); + } + public static double[] vectEqualWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -684,6 +836,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectEqualWrite(double bval, double[] a, int ai, int len) { + return vectEqualWrite(a, bval, ai, len); + } + public static double[] vectEqualWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++, bi++) @@ -698,6 +854,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectEqualWrite(double bval, double[] a, int[] aix, int ai, int len) { + return vectEqualWrite(a, bval, aix, ai, len); + } + public static double[] vectEqualWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = ai; j < ai+len; j++ ) @@ -710,13 +870,21 @@ public class LibSpoofPrimitives public static void vectNotequalAdd(double[] a, double bval, double[] c, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++, ci++) c[ci] += (a[j] != bval) ? 1 : 0; - } + } + + public static void vectNotequalAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + vectNotequalAdd(a, bval, c, ai, ci, len); + } public static void vectNotequalAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += (a[j] != bval) ? 1 : 0; } + public static void vectNotequalAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + vectNotequalAdd(a, bval, c, aix, ai, ci, len); + } + public static double[] vectNotequalWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -724,6 +892,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectNotequalWrite(double bval, double[] a, int ai, int len) { + return vectNotequalWrite(a, bval, ai, len); + } + public static double[] vectNotequalWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++, bi++) @@ -738,6 +910,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectNotequalWrite(double bval, double[] a, int[] aix, int ai, int len) { + return vectNotequalWrite(a, bval, aix, ai, len); + } + public static double[] vectNotequalWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = ai; j < ai+len; j++ ) @@ -750,13 +926,21 @@ public class LibSpoofPrimitives public static void vectLessAdd(double[] a, double bval, double[] c, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++, ci++) c[ci] += (a[j] < bval) ? 1 : 0; - } + } + + public static void vectLessAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + vectGreaterequalAdd(a, bval, c, ai, ci, len); + } public static void vectLessAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += (a[j] < bval) ? 1 : 0; } + public static void vectLessAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + vectGreaterequalAdd(a, bval, c, aix, ai, ci, len); + } + public static double[] vectLessWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -764,6 +948,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectLessWrite(double bval, double[] a, int ai, int len) { + return vectGreaterequalWrite(a, bval, ai, len); + } + public static double[] vectLessWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++, bi++) @@ -778,6 +966,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectLessWrite(double bval, double[] a, int[] aix, int ai, int len) { + return vectGreaterequalWrite(a, bval, aix, ai, len); + } + public static double[] vectLessWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = ai; j < ai+len; j++ ) @@ -790,13 +982,21 @@ public class LibSpoofPrimitives public static void vectLessequalAdd(double[] a, double bval, double[] c, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++, ci++) c[ci] += (a[j] <= bval) ? 1 : 0; - } + } + + public static void vectLessequalAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + vectGreaterAdd(a, bval, c, ai, ci, len); + } public static void vectLessequalAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += (a[j] <= bval) ? 1 : 0; } + public static void vectLessequalAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + vectGreaterAdd(a, bval, c, aix, ai, ci, len); + } + public static double[] vectLessequalWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -804,6 +1004,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectLessequalWrite(double bval, double[] a, int ai, int len) { + return vectGreaterWrite(a, bval, ai, len); + } + public static double[] vectLessequalWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++, bi++) @@ -818,6 +1022,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectLessequalWrite(double bval, double[] a, int[] aix, int ai, int len) { + return vectGreaterWrite(a, bval, aix, ai, len); + } + public static double[] vectLessequalWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = ai; j < ai+len; j++ ) @@ -830,13 +1038,21 @@ public class LibSpoofPrimitives public static void vectGreaterAdd(double[] a, double bval, double[] c, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++, ci++) c[ci] += (a[j] > bval) ? 1 : 0; - } + } + + public static void vectGreaterAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + vectLessequalAdd(a, bval, c, ai, ci, len); + } public static void vectGreaterAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += (a[j] > bval) ? 1 : 0; } + public static void vectGreaterAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + vectLessequalAdd(a, bval, c, aix, ai, ci, len); + } + public static double[] vectGreaterWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -844,6 +1060,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectGreaterWrite(double bval, double[] a, int ai, int len) { + return vectGreaterWrite(a, bval, ai, len); + } + public static double[] vectGreaterWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++, bi++) @@ -858,6 +1078,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectGreaterWrite(double bval, double[] a, int[] aix, int ai, int len) { + return vectLessequalWrite(a, bval, aix, ai, len); + } + public static double[] vectGreaterWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = ai; j < ai+len; j++ ) @@ -870,13 +1094,21 @@ public class LibSpoofPrimitives public static void vectGreaterequalAdd(double[] a, double bval, double[] c, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++, ci++) c[ci] += (a[j] >= bval) ? 1 : 0; - } + } + + public static void vectGreaterequalAdd(double bval, double[] a, double[] c, int ai, int ci, int len) { + vectLessAdd(a, bval, c, ai, ci, len); + } public static void vectGreaterequalAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++ ) c[ci + aix[j]] += (a[j] >= bval) ? 1 : 0; } + public static void vectGreaterequalAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int len) { + vectLessAdd(a, bval, c, aix, ai, ci, len); + } + public static double[] vectGreaterequalWrite(double[] a, double bval, int ai, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++) @@ -884,6 +1116,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectGreaterequalWrite(double bval, double[] a, int ai, int len) { + return vectLessWrite(a, bval, ai, len); + } + public static double[] vectGreaterequalWrite(double[] a, double[] b, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = 0; j < len; j++, ai++, bi++) @@ -898,6 +1134,10 @@ public class LibSpoofPrimitives return c; } + public static double[] vectGreaterequalWrite(double bval, double[] a, int[] aix, int ai, int len) { + return vectLessWrite(a, bval, aix, ai, len); + } + public static double[] vectGreaterequalWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { double[] c = allocVector(len, false); for( int j = ai; j < ai+len; j++ ) http://git-wip-us.apache.org/repos/asf/systemml/blob/728bf19e/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java b/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java index 899f629..529b838 100644 --- a/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java +++ b/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java @@ -34,6 +34,7 @@ import org.apache.sysml.runtime.matrix.data.LibMatrixMult; import org.apache.sysml.runtime.matrix.data.MatrixBlock; import org.apache.sysml.runtime.matrix.data.SparseBlock; import org.apache.sysml.runtime.matrix.data.SparseRow; +import org.apache.sysml.runtime.matrix.data.SparseRowVector; import org.apache.sysml.runtime.util.UtilFunctions; @@ -211,7 +212,8 @@ public abstract class SpoofRowwise extends SpoofOperator { if( sblock == null ) return; - + + SparseRow empty = new SparseRowVector(1); for( int i=rl; i<ru; i++ ) { if( !sblock.isEmpty(i) ) { double[] avals = sblock.values(i); @@ -222,6 +224,9 @@ public abstract class SpoofRowwise extends SpoofOperator //call generated method genexecRowSparse(avals, aix, apos, b, scalars, c, alen, i); } + else + genexecRowSparse(empty.values(), + empty.indexes(), 0, b, scalars, c, 0, i); } } @@ -238,12 +243,15 @@ public abstract class SpoofRowwise extends SpoofOperator } else { //SPARSE Iterator<SparseRow> iter = a.getSparseRowIterator(rl, ru); + SparseRow empty = new SparseRowVector(1); for( int i=rl; iter.hasNext(); i++ ) { SparseRow row = iter.next(); - if( !row.isEmpty() ) { - genexecRowSparse(row.values(), row.indexes(), - 0, b, scalars, c, row.size(), i); - } + if( !row.isEmpty() ) + genexecRowSparse(row.values(), + row.indexes(), 0, b, scalars, c, row.size(), i); + else + genexecRowSparse(empty.values(), + empty.indexes(), 0, b, scalars, c, 0, i); } } } http://git-wip-us.apache.org/repos/asf/systemml/blob/728bf19e/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java b/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java index 409fbc7..809b812 100644 --- a/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java +++ b/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java @@ -55,18 +55,19 @@ public class RowAggTmplTest extends AutomatedTestBase private static final String TEST_NAME17 = TEST_NAME+"17"; //MLogreg - vector-matrix w/ indexing private static final String TEST_NAME18 = TEST_NAME+"18"; //MLogreg - matrix-vector cbind 0s private static final String TEST_NAME19 = TEST_NAME+"19"; //MLogreg - rowwise dag + private static final String TEST_NAME20 = TEST_NAME+"20"; //1 / (1 - (A / rowSums(A))) private static final String TEST_DIR = "functions/codegen/"; private static final String TEST_CLASS_DIR = TEST_DIR + RowAggTmplTest.class.getSimpleName() + "/"; private final static String TEST_CONF = "SystemML-config-codegen.xml"; private final static File TEST_CONF_FILE = new File(SCRIPT_DIR + TEST_DIR, TEST_CONF); - + private static final double eps = Math.pow(10, -10); @Override public void setUp() { TestUtils.clearAssertionInformation(); - for(int i=1; i<=19; i++) + for(int i=1; i<=20; i++) addTestConfiguration( TEST_NAME+i, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME+i, new String[] { String.valueOf(i) }) ); } @@ -355,6 +356,21 @@ public class RowAggTmplTest extends AutomatedTestBase testCodegenIntegration( TEST_NAME19, false, ExecType.SPARK ); } + @Test + public void testCodegenRowAggRewrite20CP() { + testCodegenIntegration( TEST_NAME20, true, ExecType.CP ); + } + + @Test + public void testCodegenRowAgg20CP() { + testCodegenIntegration( TEST_NAME20, false, ExecType.CP ); + } + + @Test + public void testCodegenRowAgg20SP() { + testCodegenIntegration( TEST_NAME20, false, ExecType.SPARK ); + } + private void testCodegenIntegration( String testname, boolean rewrites, ExecType instType ) { boolean oldFlag = OptimizerUtils.ALLOW_ALGEBRAIC_SIMPLIFICATION; http://git-wip-us.apache.org/repos/asf/systemml/blob/728bf19e/src/test/scripts/functions/codegen/rowAggPattern20.R ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/codegen/rowAggPattern20.R b/src/test/scripts/functions/codegen/rowAggPattern20.R new file mode 100644 index 0000000..73cf4b6 --- /dev/null +++ b/src/test/scripts/functions/codegen/rowAggPattern20.R @@ -0,0 +1,32 @@ +#------------------------------------------------------------- +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +#------------------------------------------------------------- + +args<-commandArgs(TRUE) +options(digits=22) +library("Matrix") +library("matrixStats") + +A = matrix(1, 1500, 7); + +R = A / rowSums(A)%*%matrix(1,1,ncol(A)); +R = 1 / (1 - R); + +writeMM(as(R, "CsparseMatrix"), paste(args[2], "S", sep="")); http://git-wip-us.apache.org/repos/asf/systemml/blob/728bf19e/src/test/scripts/functions/codegen/rowAggPattern20.dml ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/codegen/rowAggPattern20.dml b/src/test/scripts/functions/codegen/rowAggPattern20.dml new file mode 100644 index 0000000..d1e9712 --- /dev/null +++ b/src/test/scripts/functions/codegen/rowAggPattern20.dml @@ -0,0 +1,27 @@ +#------------------------------------------------------------- +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +#------------------------------------------------------------- + +A = matrix(1, 1500, 7); + +R = A / rowSums(A); +R = 1 / (1 - R); + +write(R, $1)
