[SYSTEMML-1732] Codegen full support for sparse-unsafe vector primitives So far, the code generator row primitives always assumed sparse-safe operations. This patch generalizes all existing scalar-vector and vector-vector primitives for sparse-unsafe operations over sparse inputs.
Project: http://git-wip-us.apache.org/repos/asf/systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/c17b8a8e Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/c17b8a8e Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/c17b8a8e Branch: refs/heads/master Commit: c17b8a8e331819eaa7805b715386c59603612d1c Parents: 10c57fd Author: Matthias Boehm <mboe...@gmail.com> Authored: Sat Jun 24 01:27:41 2017 -0700 Committer: Matthias Boehm <mboe...@gmail.com> Committed: Sat Jun 24 13:50:36 2017 -0700 ---------------------------------------------------------------------- .../sysml/hops/codegen/cplan/CNodeBinary.java | 12 +- .../sysml/hops/codegen/cplan/CNodeRow.java | 4 +- .../sysml/hops/codegen/cplan/CNodeTpl.java | 3 +- .../sysml/hops/codegen/cplan/CNodeUnary.java | 4 +- .../runtime/codegen/LibSpoofPrimitives.java | 595 +++++++++++-------- .../sysml/runtime/codegen/SpoofRowwise.java | 31 +- .../functions/codegen/RowAggTmplTest.java | 18 +- .../scripts/functions/codegen/rowAggPattern22.R | 32 + .../functions/codegen/rowAggPattern22.dml | 28 + 9 files changed, 435 insertions(+), 292 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/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 3771de5..8d67f26 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 @@ -69,7 +69,7 @@ public class CNodeBinary extends CNode public String getTemplate(boolean sparse, boolean scalarVector) { switch (this) { case DOT_PRODUCT: - return sparse ? " double %TMP% = LibSpoofPrimitives.dotProduct(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, %LEN%);\n" : + return sparse ? " double %TMP% = LibSpoofPrimitives.dotProduct(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, alen);\n" : " double %TMP% = LibSpoofPrimitives.dotProduct(%IN1%, %IN2%, %POS1%, %POS2%, %LEN%);\n"; //vector-scalar-add operations @@ -88,10 +88,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%, %LEN%);\n" : + return sparse ? " 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%, %LEN%);\n" : + return sparse ? " LibSpoofPrimitives.vect"+vectName+"Add(%IN1v%, %IN2%, %OUT%, %IN1i%, %POS1%, %POSOUT%, alen, len);\n" : " LibSpoofPrimitives.vect"+vectName+"Add(%IN1%, %IN2%, %OUT%, %POS1%, %POSOUT%, %LEN%);\n"; } @@ -111,10 +111,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%, %LEN%);\n" : + return sparse ? " 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%, %LEN%);\n" : + return sparse ? " double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN2%, %IN1i%, %POS1%, alen, len);\n" : " double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2%, %POS1%, %LEN%);\n"; } @@ -133,7 +133,7 @@ public class CNodeBinary extends CNode case VECT_GREATEREQUAL: { String vectName = getVectorPrimitiveName(); return sparse ? - " double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, %LEN%);\n" : + " double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, alen, len);\n" : " double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2%, %POS1%, %POS2%, %LEN%);\n"; } http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java index caf379b..7cba5f7 100644 --- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java +++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java @@ -40,10 +40,10 @@ public class CNodeRow extends CNodeTpl + " public %TMP%() {\n" + " super(RowType.%TYPE%, %CBIND0%, %VECT_MEM%);\n" + " }\n" - + " protected void genexecRowDense( double[] a, int ai, double[][] b, double[] scalars, double[] c, int len, int rowIndex ) { \n" + + " protected void genexec(double[] a, int ai, double[][] b, double[] scalars, double[] c, int len, int rowIndex) { \n" + "%BODY_dense%" + " }\n" - + " protected void genexecRowSparse( double[] avals, int[] aix, int ai, double[][] b, double[] scalars, double[] c, int len, int rowIndex ) { \n" + + " protected void genexec(double[] avals, int[] aix, int ai, double[][] b, double[] scalars, double[] c, int alen, int len, int rowIndex) { \n" + "%BODY_sparse%" + " }\n" + "}\n"; http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/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 8d61588..db7ea31 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 @@ -137,7 +137,8 @@ public abstract class CNodeTpl extends CNode implements Cloneable if( newNames.containsKey(dnode.getHopID()) ) dnode.setName(newNames.get(dnode.getHopID())); } - + + node.resetHash(); node.setVisited(); } http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/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 c560878..500b309 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 @@ -49,7 +49,7 @@ public class CNodeUnary extends CNode case ROW_MINS: case ROW_MAXS: { String vectName = StringUtils.capitalize(this.toString().substring(4,7).toLowerCase()); - return sparse ? " double %TMP% = LibSpoofPrimitives.vect"+vectName+"(%IN1v%, %IN1i%, %POS1%, %LEN%);\n": + return sparse ? " double %TMP% = LibSpoofPrimitives.vect"+vectName+"(%IN1v%, %IN1i%, %POS1%, alen, len);\n": " double %TMP% = LibSpoofPrimitives.vect"+vectName+"(%IN1%, %POS1%, %LEN%);\n"; } @@ -64,7 +64,7 @@ public class CNodeUnary extends CNode case VECT_FLOOR: case VECT_SIGN: { String vectName = getVectorPrimitiveName(); - return sparse ? " double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN1i%, %POS1%, %LEN%);\n" : + return sparse ? " double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN1i%, %POS1%, alen, len);\n" : " double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %POS1%, %LEN%);\n"; } http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/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 d9f20ef..8fe35ff 100644 --- a/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java +++ b/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java @@ -58,23 +58,23 @@ public class LibSpoofPrimitives } public static void vectMultAdd(double[] a, double bval, double[] c, int bi, int ci, int len) { - if( a == null ) return; + if( a == null || bval == 0 ) 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; + if( a == null || bval == 0 ) 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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( a == null || bval == 0 ) return; + LibMatrixMult.vectMultiplyAdd(bval, a, c, aix, ai, ci, alen); } - 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 bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( a == null || bval == 0 ) return; + LibMatrixMult.vectMultiplyAdd(bval, a, c, aix, ai, ci, alen); } public static void vectMultAdd(double[] a, double[] b, double[] c, int bi, int ci, int len) { @@ -84,8 +84,9 @@ public class LibSpoofPrimitives } public static double[] vectMultWrite(double[] a, double bval, int bi, int len) { + if( a == null || bval == 0 ) + return allocVector(len, true); double[] c = allocVector(len, false); - if( a == null ) return c; LibMatrixMult.vectMultiplyWrite(bval, a, c, bi, 0, len); return c; } @@ -95,27 +96,28 @@ public class LibSpoofPrimitives } public static double[] vectMultWrite(double[] a, double[] b, int ai, int bi, int len) { + if( a == null || b == null ) + return allocVector(len, true); 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) { + public static double[] vectMultWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { double[] c = allocVector(len, true); if( a == null ) return c; - LibMatrixMult.vectMultiplyAdd(bval, a, c, bix, bi, 0, len); + LibMatrixMult.vectMultiplyAdd(bval, a, c, aix, ai, 0, alen); 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 bval, double[] a, int[] aix, int ai, int alen, int len) { + return vectMultWrite(a, bval, aix, ai, alen, len); } - public static double[] vectMultWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { - double[] c = allocVector(len, false); + public static double[] vectMultWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { + double[] c = allocVector(len, true); if( a == null || b == null ) return c; - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = a[j] * b[bi+aix[j]]; return c; } @@ -138,7 +140,7 @@ public class LibSpoofPrimitives public static double vectSum(double[] a, int ai, int len) { double val = 0; final int bn = len%8; - + //compute rest for( int i = ai; i < ai+bn; i++ ) val += a[ i ]; @@ -154,18 +156,9 @@ public class LibSpoofPrimitives return val; } - /** - * Computes c = sum(A), where A is a sparse vector. - * - * @param avals sparse input vector A values A - * @param aix sparse input vector A column indexes - * @param ai start position in A - * @param len number of processed elements - * @return sum value - */ - public static double vectSum(double[] avals, int[] aix, int ai, int len) { + public static double vectSum(double[] avals, int[] aix, int ai, int alen, int len) { //forward to dense as column indexes not required here - return vectSum(avals, ai, len); + return vectSum(avals, ai, alen); } public static double vectMin(double[] a, int ai, int len) { @@ -175,11 +168,9 @@ public class LibSpoofPrimitives return val; } - public static double vectMin(double[] avals, int[] aix, int ai, int len) { - double val = Double.MAX_VALUE; - for( int i = ai; i < ai+len; i++ ) - val = Math.min(avals[aix[i]], val); - return val; + public static double vectMin(double[] avals, int[] aix, int ai, int alen, int len) { + double val = vectMin(avals, ai, alen); + return (alen<len) ? Math.min(val, 0) : val; } public static double vectMax(double[] a, int ai, int len) { @@ -189,11 +180,9 @@ public class LibSpoofPrimitives return val; } - public static double vectMax(double[] avals, int[] aix, int ai, int len) { - double val = -Double.MAX_VALUE; - for( int i = ai; i < ai+len; i++ ) - val = Math.max(avals[aix[i]], val); - return val; + public static double vectMax(double[] avals, int[] aix, int ai, int alen, int len) { + double val = vectMax(avals, ai, alen); + return (alen<len) ? Math.max(val, 0) : val; } //custom vector div @@ -208,54 +197,54 @@ public class LibSpoofPrimitives 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++ ) + public static void vectDivAdd(double[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ai; j < ai+alen; 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++ ) + public static void vectDivAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ai; j < ai+alen; 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++) - c[j] = a[ai] / bval; + for( int j = 0; j < len; j++) + c[j] = a[ai+j] / bval; 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]; + for( int j = 0; j < len; j++) + c[j] = bval / a[ai + j]; return c; } - public static double[] vectDivWrite(double[] a, double[] b, int ai, int bi, int len) { + public static double[] vectDivWrite(double[] a, double[] b, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = 0; j < len; j++, ai++, bi++) - c[j] = a[ai] / b[bi]; + for( int j = 0; j < len; j++) + c[j] = a[ai + j] / b[bi + j]; return c; } - public static double[] vectDivWrite(double[] a, double bval, int[] aix, int ai, int len) { + public static double[] vectDivWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = a[j] / bval; return c; } - public static double[] vectDivWrite(double bval, double[] a, int[] aix, int ai, int len) { + public static double[] vectDivWrite(double bval, double[] a, int[] aix, int ai, int alen, int len) { double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; 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) { + public static double[] vectDivWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = a[j] / b[bi+aix[j]]; return c; } @@ -272,55 +261,63 @@ public class LibSpoofPrimitives 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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( bval != 0 ) //subtract bval if necessary + for( int j = ci; j < ci+len; j++ ) + c[j] -= bval; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += a[j]; } - 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 void vectMinusAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( bval != 0 ) //add bval is necessary + for( int j = ci; j < ci+len; j++ ) + c[j] += bval; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] -= 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++) - c[j] = a[ai] - bval; + for( int j = 0; j < len; j++) + c[j] = a[ai + j] - bval; 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]; + for( int j = 0; j < len; j++) + c[j] = bval - a[ai + j]; 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++) - c[j] = a[ai] - b[bi]; + for( int j = 0; j < len; j++) + c[j] = a[ai + j] - b[bi + j]; return c; } - public static double[] vectMinusWrite(double[] a, double bval, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = a[j] - bval; + public static double[] vectMinusWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true, -bval); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] += a[j]; 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]; + public static double[] vectMinusWrite(double bval, double[] a, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true, bval); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] -= a[j]; return c; } - public static double[] vectMinusWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { + public static double[] vectMinusWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = a[j] - b[bi+aix[j]]; + for( int j = 0; j < len; j++ ) + c[j] = -b[bi+j]; + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] += a[j]; return c; } @@ -334,19 +331,21 @@ public class LibSpoofPrimitives LibMatrixMult.vectAdd(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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ci; j < ci+len; j++ ) + c[j] += bval; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += a[j]; } - 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 void vectPlusAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + vectPlusAdd(a, bval, c, aix, ai, ci, alen, 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++) - c[j] = a[ai] + bval; + for( int j = 0; j < len; j++) + c[j] = a[ai + j] + bval; return c; } @@ -356,26 +355,27 @@ public class LibSpoofPrimitives 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++) - c[j] = a[ai] + b[bi]; + for( int j = 0; j < len; j++) + c[j] = a[ai+j] + b[bi+j]; return c; } - public static double[] vectPlusWrite(double[] a, double bval, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = a[j] + bval; + public static double[] vectPlusWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true, bval); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] += a[j]; 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 bval, double[] a, int[] aix, int ai, int alen, int len) { + return vectPlusWrite(a, bval, aix, ai, alen, len); } - public static double[] vectPlusWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { + public static double[] vectPlusWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = a[j] + b[bi+aix[j]]; + System.arraycopy(b, bi, c, 0, len); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] += a[j]; return c; } @@ -391,14 +391,19 @@ public class LibSpoofPrimitives 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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( bval == 0 ) //handle 0^0=1 + for( int j=0; j<len; j++ ) + c[ci + j] += 1; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += Math.pow(a[j], bval) - 1; } - 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 void vectPowAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j=0; j<len; j++ ) + c[ci + j] += 1; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += Math.pow(bval, a[j]) - 1; } public static double[] vectPowWrite(double[] a, double bval, int ai, int len) { @@ -422,16 +427,17 @@ public class LibSpoofPrimitives return c; } - public static double[] vectPowWrite(double[] a, double bval, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = Math.pow(a[j], bval); + public static double[] vectPowWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { + double init = (bval == 0) ? 1 : 0; + double[] c = allocVector(len, true, init); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = Math.pow(a[j], bval) - init; 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++ ) + public static double[] vectPowWrite(double bval, double[] a, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true, 1); + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = Math.pow(bval, a[j]); return c; } @@ -447,13 +453,16 @@ public class LibSpoofPrimitives 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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( bval < 0 ) + for( int j=0; j<len; j++ ) + c[ci +j] += bval; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += (bval >= 0) ? Math.min(a[j], bval) : 0; } - 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 void vectMinAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + vectMinAdd(a, bval, c, aix, ai, ci, alen, len); } public static double[] vectMinWrite(double[] a, double bval, int ai, int len) { @@ -474,21 +483,22 @@ public class LibSpoofPrimitives return c; } - public static double[] vectMinWrite(double[] a, double bval, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + public static double[] vectMinWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true, bval); + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = Math.min(a[j], bval); 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 bval, double[] a, int[] aix, int ai, int alen, int len) { + return vectMinWrite(a, bval, aix, ai, alen, len); } - public static double[] vectMinWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { + public static double[] vectMinWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = Math.min(a[j], b[bi+aix[j]]); + System.arraycopy(b, bi, c, 0, len); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = Math.min(a[j], c[aix[j]]); return c; } @@ -503,13 +513,16 @@ public class LibSpoofPrimitives 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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( bval > 0 ) + for( int j=0; j<len; j++ ) + c[ci + j] += bval; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += (bval <= 0) ? Math.max(a[j], bval) : 0; } - 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 void vectMaxAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + vectMaxAdd(a, bval, c, aix, ai, ci, alen, len); } public static double[] vectMaxWrite(double[] a, double bval, int ai, int len) { @@ -530,47 +543,50 @@ public class LibSpoofPrimitives return c; } - public static double[] vectMaxWrite(double[] a, double bval, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + public static double[] vectMaxWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true, bval); + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = Math.max(a[j], bval); 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 bval, double[] a, int[] aix, int ai, int alen, int len) { + return vectMaxWrite(a, bval, aix, ai, alen, len); } - public static double[] vectMaxWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { + public static double[] vectMaxWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = Math.max(a[j], b[bi+aix[j]]); + System.arraycopy(b, bi, c, 0, len); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = Math.max(a[j], c[aix[j]]); return c; } //custom exp public static void vectExpAdd(double[] a, double[] c, int ai, int ci, int len) { - for( int j = ai; j < ai+len; j++, ci++) - c[ci] += FastMath.exp(a[j]); + for( int j = 0; j < len; j++) + c[ci+j] += FastMath.exp(a[ai+j]); } - public static void vectExpAdd(double[] a, double[] c, int[] aix, int ai, int ci, int len) { - for( int j = ai; j < ai+len; j++ ) - c[ci + aix[j]] += FastMath.exp(a[j]); + public static void vectExpAdd(double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j=ci; j<ci+len; j++ ) //exp(0)=1 + c[j] += 1; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += FastMath.exp(a[j]) - 1; } public static double[] vectExpWrite(double[] a, int ai, int len) { double[] c = allocVector(len, false); - for( int j = 0; j < len; j++, ai++) - c[j] = FastMath.exp(a[ai]); + for( int j = 0; j < len; j++) + c[j] = FastMath.exp(a[ai+j]); return c; } - public static double[] vectExpWrite(double[] a, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = FastMath.exp(a[j]); + public static double[] vectExpWrite(double[] a, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true, 1); //exp(0)=1 + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = FastMath.exp(a[j]) - 1; return c; } @@ -578,11 +594,11 @@ public class LibSpoofPrimitives public static void vectLogAdd(double[] a, double[] c, int ai, int ci, int len) { for( int j = ai; j < ai+len; j++, ci++) - c[ci] += FastMath.log(a[j]); + c[ci] += FastMath.log(a[j]); } - public static void vectLogAdd(double[] a, double[] c, int[] aix, int ai, int ci, int len) { - for( int j = ai; j < ai+len; j++ ) + public static void vectLogAdd(double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ai; j < ai+alen; j++ ) c[ci + aix[j]] += FastMath.log(a[j]); } @@ -593,9 +609,9 @@ public class LibSpoofPrimitives return c; } - public static double[] vectLogWrite(double[] a, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + public static double[] vectLogWrite(double[] a, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true, Double.NEGATIVE_INFINITY); + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = FastMath.log(a[j]); return c; } @@ -607,8 +623,8 @@ public class LibSpoofPrimitives c[ci] += Math.abs(a[j]); } - public static void vectAbsAdd(double[] a, double[] c, int[] aix, int ai, int ci, int len) { - for( int j = ai; j < ai+len; j++ ) + public static void vectAbsAdd(double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ai; j < ai+alen; j++ ) c[ci + aix[j]] += Math.abs(a[j]); } @@ -619,9 +635,9 @@ public class LibSpoofPrimitives return c; } - public static double[] vectAbsWrite(double[] a, int[] aix, int ai, int len) { + public static double[] vectAbsWrite(double[] a, int[] aix, int ai, int alen, int len) { double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = Math.abs(a[j]); return c; } @@ -633,8 +649,8 @@ public class LibSpoofPrimitives c[ci] += Math.round(a[j]); } - public static void vectRoundAdd(double[] a, double[] c, int[] aix, int ai, int ci, int len) { - for( int j = ai; j < ai+len; j++ ) + public static void vectRoundAdd(double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ai; j < ai+alen; j++ ) c[ci + aix[j]] += Math.round(a[j]); } @@ -645,9 +661,9 @@ public class LibSpoofPrimitives return c; } - public static double[] vectRoundWrite(double[] a, int[] aix, int ai, int len) { + public static double[] vectRoundWrite(double[] a, int[] aix, int ai, int alen, int len) { double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = Math.round(a[j]); return c; } @@ -659,8 +675,8 @@ public class LibSpoofPrimitives c[ci] += FastMath.ceil(a[j]); } - public static void vectCeilAdd(double[] a, double[] c, int[] aix, int ai, int ci, int len) { - for( int j = ai; j < ai+len; j++ ) + public static void vectCeilAdd(double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ai; j < ai+alen; j++ ) c[ci + aix[j]] += FastMath.ceil(a[j]); } @@ -671,9 +687,9 @@ public class LibSpoofPrimitives return c; } - public static double[] vectCeilWrite(double[] a, int[] aix, int ai, int len) { + public static double[] vectCeilWrite(double[] a, int[] aix, int ai, int alen, int len) { double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = FastMath.ceil(a[j]); return c; } @@ -685,8 +701,8 @@ public class LibSpoofPrimitives c[ci] += FastMath.floor(a[j]); } - public static void vectFloorAdd(double[] a, double[] c, int[] aix, int ai, int ci, int len) { - for( int j = ai; j < ai+len; j++ ) + public static void vectFloorAdd(double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ai; j < ai+alen; j++ ) c[ci + aix[j]] += FastMath.floor(a[j]); } @@ -697,9 +713,9 @@ public class LibSpoofPrimitives return c; } - public static double[] vectFloorWrite(double[] a, int[] aix, int ai, int len) { + public static double[] vectFloorWrite(double[] a, int[] aix, int ai, int alen, int len) { double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = FastMath.floor(a[j]); return c; } @@ -711,8 +727,8 @@ public class LibSpoofPrimitives c[ci] += FastMath.signum(a[j]); } - public static void vectSignAdd(double[] a, double[] c, int[] aix, int ai, int ci, int len) { - for( int j = ai; j < ai+len; j++ ) + public static void vectSignAdd(double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ai; j < ai+alen; j++ ) c[ci + aix[j]] += FastMath.signum(a[j]); } @@ -723,9 +739,9 @@ public class LibSpoofPrimitives return c; } - public static double[] vectSignWrite(double[] a, int[] aix, int ai, int len) { + public static double[] vectSignWrite(double[] a, int[] aix, int ai, int alen, int len) { double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = FastMath.signum(a[j]); return c; } @@ -737,8 +753,8 @@ public class LibSpoofPrimitives c[ci] += a[j] * a[j]; } - public static void vectPow2Add(double[] a, double[] c, int[] aix, int ai, int ci, int len) { - for( int j = ai; j < ai+len; j++ ) + public static void vectPow2Add(double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ai; j < ai+alen; j++ ) c[ci + aix[j]] += a[j] * a[j]; } @@ -749,9 +765,9 @@ public class LibSpoofPrimitives return c; } - public static double[] vectPow2Write(double[] a, int[] aix, int ai, int len) { + public static double[] vectPow2Write(double[] a, int[] aix, int ai, int alen, int len) { double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = a[j] * a[j]; return c; } @@ -763,8 +779,8 @@ public class LibSpoofPrimitives c[ci] += a[j] + a[j]; } - public static void vectMult2Add(double[] a, double[] c, int[] aix, int ai, int ci, int len) { - for( int j = ai; j < ai+len; j++ ) + public static void vectMult2Add(double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ai; j < ai+alen; j++ ) c[ci + aix[j]] += a[j] + a[j]; } @@ -775,9 +791,9 @@ public class LibSpoofPrimitives return c; } - public static double[] vectMult2Write(double[] a, int[] aix, int ai, int len) { + public static double[] vectMult2Write(double[] a, int[] aix, int ai, int alen, int len) { double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = a[j] + a[j]; return c; } @@ -789,8 +805,8 @@ public class LibSpoofPrimitives c[ci] += Math.sqrt(a[j]); } - public static void vectSqrtAdd(double[] a, double[] c, int[] aix, int ai, int ci, int len) { - for( int j = ai; j < ai+len; j++ ) + public static void vectSqrtAdd(double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + for( int j = ai; j < ai+alen; j++ ) c[ci + aix[j]] += Math.sqrt(a[j]); } @@ -801,9 +817,9 @@ public class LibSpoofPrimitives return c; } - public static double[] vectSqrtWrite(double[] a, int[] aix, int ai, int len) { + public static double[] vectSqrtWrite(double[] a, int[] aix, int ai, int alen, int len) { double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = Math.sqrt(a[j]); return c; } @@ -819,13 +835,17 @@ public class LibSpoofPrimitives 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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( bval == 0 ) + for( int j=0; j<len; j++ ) + c[j] += 1; + else + for( int j = ai; j < ai+alen; 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 void vectEqualAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + vectEqualAdd(a, bval, c, aix, ai, ci, alen, len); } public static double[] vectEqualWrite(double[] a, double bval, int ai, int len) { @@ -846,20 +866,24 @@ public class LibSpoofPrimitives return c; } - public static double[] vectEqualWrite(double[] a, double bval, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = (a[j] == bval) ? 1 : 0; + public static double[] vectEqualWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { + double init = (bval == 0) ? 1 : 0; + double[] c = allocVector(len, true, init); + if( bval != 0 ) + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = (a[j] == bval) ? 1 : 0; 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 bval, double[] a, int[] aix, int ai, int alen, int len) { + return vectEqualWrite(a, bval, aix, ai, alen, len); } - public static double[] vectEqualWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { + public static double[] vectEqualWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = ai; j < ai+len; j++ ) + for( int j=0; j<len; j++ ) + c[j] = (b[bi+j]==0) ? 1 : 0; + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = (a[j] == b[bi+aix[j]]) ? 1 : 0; return c; } @@ -875,13 +899,17 @@ public class LibSpoofPrimitives 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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( bval != 0 ) + for( int j=0; j<len; j++ ) + c[j] += 1; + double init = (bval != 0) ? 1 : 0; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += ((a[j] != bval) ? 1 : 0) - init; } - 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 void vectNotequalAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + vectNotequalAdd(a, bval, c, aix, ai, ci, alen, len); } public static double[] vectNotequalWrite(double[] a, double bval, int ai, int len) { @@ -902,20 +930,23 @@ public class LibSpoofPrimitives return c; } - public static double[] vectNotequalWrite(double[] a, double bval, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = (a[j] != bval) ? 1 : 0; + public static double[] vectNotequalWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { + double init = (bval != 0) ? 1 : 0; + double[] c = allocVector(len, true, init); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = ((a[j] != bval) ? 1 : 0) - init; 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 bval, double[] a, int[] aix, int ai, int alen, int len) { + return vectNotequalWrite(a, bval, aix, ai, alen, len); } - public static double[] vectNotequalWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { + public static double[] vectNotequalWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = ai; j < ai+len; j++ ) + for( int j=0; j<len; j++ ) + c[j] = (b[bi+j]!=0) ? 1 : 0; + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = (a[j] != b[bi+aix[j]]) ? 1 : 0; return c; } @@ -931,13 +962,17 @@ public class LibSpoofPrimitives 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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( bval > 0 ) + for( int j=0; j<len; j++ ) + c[j] += 1; + double init = (bval > 0) ? 1 : 0; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += ((a[j] < bval) ? 1 : 0) - init; } - 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 void vectLessAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + vectGreaterequalAdd(a, bval, c, aix, ai, ci, alen, len); } public static double[] vectLessWrite(double[] a, double bval, int ai, int len) { @@ -958,20 +993,23 @@ public class LibSpoofPrimitives return c; } - public static double[] vectLessWrite(double[] a, double bval, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = (a[j] < bval) ? 1 : 0; + public static double[] vectLessWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { + double init = (bval > 0) ? 1 : 0; + double[] c = allocVector(len, true, init); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = (a[j] < bval) ? 1 : 0 - init; 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 bval, double[] a, int[] aix, int ai, int alen, int len) { + return vectGreaterequalWrite(a, bval, aix, ai, alen, len); } - public static double[] vectLessWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { + public static double[] vectLessWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = ai; j < ai+len; j++ ) + for( int j=0; j<len; j++ ) + c[j] = ( 0 < b[bi+j] ) ? 1 : 0; + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = (a[j] < b[bi+aix[j]]) ? 1 : 0; return c; } @@ -987,13 +1025,17 @@ public class LibSpoofPrimitives 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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( bval >= 0 ) + for( int j=0; j<len; j++ ) + c[j] += 1; + double init = (bval >= 0) ? 1 : 0; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += ((a[j] <= bval) ? 1 : 0) - init; } - 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 void vectLessequalAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + vectGreaterAdd(a, bval, c, aix, ai, ci, alen, len); } public static double[] vectLessequalWrite(double[] a, double bval, int ai, int len) { @@ -1014,20 +1056,23 @@ public class LibSpoofPrimitives return c; } - public static double[] vectLessequalWrite(double[] a, double bval, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); + public static double[] vectLessequalWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { + double init = (bval >= 0) ? 1 : 0; + double[] c = allocVector(len, true, init); for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = (a[j] <= bval) ? 1 : 0; + c[aix[j]] = ((a[j] <= bval) ? 1 : 0) - init; 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 bval, double[] a, int[] aix, int ai, int alen, int len) { + return vectGreaterWrite(a, bval, aix, ai, alen, len); } - public static double[] vectLessequalWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { + public static double[] vectLessequalWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = ai; j < ai+len; j++ ) + for( int j=0; j<len; j++ ) + c[j] = ( 0 <= b[bi+j] ) ? 1 : 0; + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = (a[j] <= b[bi+aix[j]]) ? 1 : 0; return c; } @@ -1043,13 +1088,17 @@ public class LibSpoofPrimitives 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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( bval < 0 ) + for( int j=0; j<len; j++ ) + c[j] += 1; + double init = (bval < 0) ? 1 : 0; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += ((a[j] > bval) ? 1 : 0) - init; } - 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 void vectGreaterAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + vectLessequalAdd(a, bval, c, aix, ai, ci, alen, len); } public static double[] vectGreaterWrite(double[] a, double bval, int ai, int len) { @@ -1070,20 +1119,23 @@ public class LibSpoofPrimitives return c; } - public static double[] vectGreaterWrite(double[] a, double bval, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); - for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = (a[j] > bval) ? 1 : 0; + public static double[] vectGreaterWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { + double init = (bval < 0) ? 1 : 0; + double[] c = allocVector(len, true, init); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = ((a[j] > bval) ? 1 : 0) - init; 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 bval, double[] a, int[] aix, int ai, int alen, int len) { + return vectLessequalWrite(a, bval, aix, ai, alen, len); } - public static double[] vectGreaterWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { + public static double[] vectGreaterWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = ai; j < ai+len; j++ ) + for( int j=0; j<len; j++ ) + c[j] = ( 0 > b[bi+j] ) ? 1 : 0; + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = (a[j] > b[bi+aix[j]]) ? 1 : 0; return c; } @@ -1099,13 +1151,17 @@ public class LibSpoofPrimitives 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[] a, double bval, double[] c, int[] aix, int ai, int ci, int alen, int len) { + if( bval <= 0 ) + for( int j=0; j<len; j++ ) + c[j] += 1; + double init = (bval <= 0) ? 1 : 0; + for( int j = ai; j < ai+alen; j++ ) + c[ci + aix[j]] += ((a[j] >= bval) ? 1 : 0) - init; } - 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 void vectGreaterequalAdd(double bval, double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) { + vectLessAdd(a, bval, c, aix, ai, ci, alen, len); } public static double[] vectGreaterequalWrite(double[] a, double bval, int ai, int len) { @@ -1126,20 +1182,23 @@ public class LibSpoofPrimitives return c; } - public static double[] vectGreaterequalWrite(double[] a, double bval, int[] aix, int ai, int len) { - double[] c = allocVector(len, true); + public static double[] vectGreaterequalWrite(double[] a, double bval, int[] aix, int ai, int alen, int len) { + double init = (bval < 0) ? 1 : 0; + double[] c = allocVector(len, true, init); for( int j = ai; j < ai+len; j++ ) - c[aix[j]] = (a[j] >= bval) ? 1 : 0; + c[aix[j]] = ((a[j] >= bval) ? 1 : 0) - init; 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 bval, double[] a, int[] aix, int ai, int alen, int len) { + return vectLessWrite(a, bval, aix, ai, alen, len); } - public static double[] vectGreaterequalWrite(double[] a, double[] b, int[] aix, int ai, int bi, int len) { + public static double[] vectGreaterequalWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) { double[] c = allocVector(len, false); - for( int j = ai; j < ai+len; j++ ) + for( int j=0; j<len; j++ ) + c[j] = ( 0 >= b[bi+j] ) ? 1 : 0; + for( int j = ai; j < ai+alen; j++ ) c[aix[j]] = (a[j] >= b[bi+aix[j]]) ? 1 : 0; return c; } @@ -1170,11 +1229,19 @@ public class LibSpoofPrimitives } private static double[] allocVector(int len, boolean reset) { + return allocVector(len, reset, 0); + } + + private static double[] allocVector(int len, boolean reset, double resetVal) { LinkedList<double[]> list = memPool.get(); //sanity check for missing setup - if( list.isEmpty() ) - return new double[len]; + if( list.isEmpty() ) { + double[] tmp = new double[len]; + if( reset && resetVal != 0 ) + Arrays.fill(tmp, resetVal); + return tmp; + } //get and re-queue first entry double[] tmp = list.removeFirst(); @@ -1182,7 +1249,7 @@ public class LibSpoofPrimitives //reset vector if required if( reset ) - Arrays.fill(tmp, 0); + Arrays.fill(tmp, resetVal); return tmp; } } http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/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 104a1bf..611e4ad 100644 --- a/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java +++ b/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java @@ -132,7 +132,7 @@ public abstract class SpoofRowwise extends SpoofOperator executeDense(a.getDenseBlock(), b, scalars, c, n, 0, m); else executeSparse(a.getSparseBlock(), b, scalars, c, n, 0, m); - + //post-processing if( allocTmp ) LibSpoofPrimitives.cleanupThreadLocalMemory(); @@ -220,29 +220,26 @@ public abstract class SpoofRowwise extends SpoofOperator for( int i=rl, aix=rl*n; i<ru; i++, aix+=n ) { //call generated method - genexecRowDense( a, aix, b, scalars, c, n, i ); + genexec( a, aix, b, scalars, c, n, i ); } } private void executeSparse(SparseBlock sblock, double[][] b, double[] scalars, double[] c, int n, int rl, int ru) { - if( sblock == null ) - return; - SparseRow empty = new SparseRowVector(1); for( int i=rl; i<ru; i++ ) { - if( !sblock.isEmpty(i) ) { + if( sblock!=null && !sblock.isEmpty(i) ) { double[] avals = sblock.values(i); int[] aix = sblock.indexes(i); int apos = sblock.pos(i); int alen = sblock.size(i); //call generated method - genexecRowSparse(avals, aix, apos, b, scalars, c, alen, i); + genexec(avals, aix, apos, b, scalars, c, alen, n, i); } else - genexecRowSparse(empty.values(), - empty.indexes(), 0, b, scalars, c, 0, i); + genexec(empty.values(), + empty.indexes(), 0, b, scalars, c, 0, n, i); } } @@ -254,7 +251,7 @@ public abstract class SpoofRowwise extends SpoofOperator if( !a.isInSparseFormat() ) { //DENSE Iterator<double[]> iter = a.getDenseRowIterator(rl, ru); for( int i=rl; iter.hasNext(); i++ ) { - genexecRowDense(iter.next(), 0, b, scalars, c, n, i); + genexec(iter.next(), 0, b, scalars, c, n, i); } } else { //SPARSE @@ -263,20 +260,22 @@ public abstract class SpoofRowwise extends SpoofOperator 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); + genexec(row.values(), + row.indexes(), 0, b, scalars, c, row.size(), n, i); else - genexecRowSparse(empty.values(), - empty.indexes(), 0, b, scalars, c, 0, i); + genexec(empty.values(), + empty.indexes(), 0, b, scalars, c, 0, n, i); } } } //methods to be implemented by generated operators of type SpoofRowAggrgate - protected abstract void genexecRowDense( double[] a, int ai, double[][] b, double[] scalars, double[] c, int len, int rowIndex ); + protected abstract void genexec(double[] a, int ai, + double[][] b, double[] scalars, double[] c, int len, int rowIndex); - protected abstract void genexecRowSparse( double[] avals, int[] aix, int ai, double[][] b, double[] scalars, double[] c, int len, int rowIndex ); + protected abstract void genexec(double[] avals, int[] aix, int ai, + double[][] b, double[] scalars, double[] c, int alen, int n, int rowIndex); /** http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/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 f867e18..614d6e0 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 @@ -57,6 +57,7 @@ public class RowAggTmplTest extends AutomatedTestBase 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_NAME21 = TEST_NAME+"21"; //sum(X/rowSums(X)) + private static final String TEST_NAME22 = TEST_NAME+"22"; //((7+X)+(X-7)+exp(X))/(rowMins(X)+0.5) private static final String TEST_DIR = "functions/codegen/"; private static final String TEST_CLASS_DIR = TEST_DIR + RowAggTmplTest.class.getSimpleName() + "/"; @@ -68,7 +69,7 @@ public class RowAggTmplTest extends AutomatedTestBase @Override public void setUp() { TestUtils.clearAssertionInformation(); - for(int i=1; i<=21; i++) + for(int i=1; i<=22; i++) addTestConfiguration( TEST_NAME+i, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME+i, new String[] { String.valueOf(i) }) ); } @@ -387,6 +388,21 @@ public class RowAggTmplTest extends AutomatedTestBase testCodegenIntegration( TEST_NAME21, false, ExecType.SPARK ); } + @Test + public void testCodegenRowAggRewrite22CP() { + testCodegenIntegration( TEST_NAME22, true, ExecType.CP ); + } + + @Test + public void testCodegenRowAgg22CP() { + testCodegenIntegration( TEST_NAME22, false, ExecType.CP ); + } + + @Test + public void testCodegenRowAgg22SP() { + testCodegenIntegration( TEST_NAME22, 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/c17b8a8e/src/test/scripts/functions/codegen/rowAggPattern22.R ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/codegen/rowAggPattern22.R b/src/test/scripts/functions/codegen/rowAggPattern22.R new file mode 100644 index 0000000..97f0b27 --- /dev/null +++ b/src/test/scripts/functions/codegen/rowAggPattern22.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") + +X = matrix(seq(1,3000), 60, 50, byrow=TRUE)/10000; +X[,5:45] = matrix(0, 60, 41); + +R = ((7+X)+(X-7)+(X^2<=7))/((rowMaxs(X)%*%matrix(1,1,50))+0.5) + +writeMM(as(R, "CsparseMatrix"), paste(args[2], "S", sep="")); http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/src/test/scripts/functions/codegen/rowAggPattern22.dml ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/codegen/rowAggPattern22.dml b/src/test/scripts/functions/codegen/rowAggPattern22.dml new file mode 100644 index 0000000..5e3968a --- /dev/null +++ b/src/test/scripts/functions/codegen/rowAggPattern22.dml @@ -0,0 +1,28 @@ +#------------------------------------------------------------- +# +# 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. +# +#------------------------------------------------------------- + + +X = matrix(seq(1,3000), 60, 50)/10000; +X[,5:45] = matrix(0, 60, 41); + +R = ((7+X)+(X-7)+(X^2<=7))/(rowMaxs(X)+0.5) + +write(R, $1)