Repository: systemml Updated Branches: refs/heads/master a4962f39a -> c47338400
[SYSTEMML-1923] Codegen support for trigonometric scalar and row ops Initiated by the recent addition of sinh, cosh, tanh into SystemML, this patch adds the codegen compiler and runtime support for these operations. Additionally, this patch also adds the missing compiler and runtime support for row-wise sin, cos, tan, asin, acos, and atan as well as the respective tests. Project: http://git-wip-us.apache.org/repos/asf/systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/c4733840 Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/c4733840 Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/c4733840 Branch: refs/heads/master Commit: c47338400bb1f65e21cd20b5a51febbd7ad18154 Parents: a4962f3 Author: Matthias Boehm <[email protected]> Authored: Thu Sep 21 18:59:58 2017 -0700 Committer: Matthias Boehm <[email protected]> Committed: Thu Sep 21 19:00:14 2017 -0700 ---------------------------------------------------------------------- .../sysml/hops/codegen/cplan/CNodeUnary.java | 60 ++++- .../hops/codegen/template/TemplateRow.java | 1 + .../runtime/codegen/LibSpoofPrimitives.java | 235 +++++++++++++++++++ .../codegen/CPlanVectorPrimitivesTest.java | 90 +++++++ 4 files changed, 376 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/systemml/blob/c4733840/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 541fe30..4bfb74b 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 @@ -27,16 +27,17 @@ import org.apache.sysml.runtime.util.UtilFunctions; public class CNodeUnary extends CNode { - // TODO: Add support for SINH, COSH and TANH public enum UnaryType { LOOKUP_R, LOOKUP_C, LOOKUP_RC, LOOKUP0, CBIND0, //codegen specific ROW_SUMS, ROW_MINS, ROW_MAXS, //codegen specific VECT_EXP, VECT_POW2, VECT_MULT2, VECT_SQRT, VECT_LOG, VECT_ABS, VECT_ROUND, VECT_CEIL, VECT_FLOOR, VECT_SIGN, + VECT_SIN, VECT_COS, VECT_TAN, VECT_ASIN, VECT_ACOS, VECT_ATAN, + VECT_SINH, VECT_COSH, VECT_TANH, VECT_CUMSUM, VECT_CUMMIN, VECT_CUMMAX, EXP, POW2, MULT2, SQRT, LOG, LOG_NZ, ABS, ROUND, CEIL, FLOOR, SIGN, - SIN, COS, TAN, ASIN, ACOS, ATAN, + SIN, COS, TAN, ASIN, ACOS, ATAN, SINH, COSH, TANH, SELP, SPROP, SIGMOID; public static boolean contains(String value) { @@ -66,6 +67,15 @@ public class CNodeUnary extends CNode case VECT_CEIL: case VECT_FLOOR: case VECT_SIGN: + case VECT_SIN: + case VECT_COS: + case VECT_TAN: + case VECT_ASIN: + case VECT_ACOS: + case VECT_ATAN: + case VECT_SINH: + case VECT_COSH: + case VECT_TANH: case VECT_CUMSUM: case VECT_CUMMIN: case VECT_CUMMAX:{ @@ -104,6 +114,12 @@ public class CNodeUnary extends CNode return " double %TMP% = FastMath.acos(%IN1%);\n"; case ATAN: return " double %TMP% = Math.atan(%IN1%);\n"; + case SINH: + return " double %TMP% = FastMath.sinh(%IN1%);\n"; + case COSH: + return " double %TMP% = FastMath.cosh(%IN1%);\n"; + case TANH: + return " double %TMP% = FastMath.tanh(%IN1%);\n"; case SIGN: return " double %TMP% = FastMath.signum(%IN1%);\n"; case SQRT: @@ -135,6 +151,9 @@ public class CNodeUnary extends CNode || this == VECT_LOG || this == VECT_ABS || this == VECT_ROUND || this == VECT_CEIL || this == VECT_FLOOR || this == VECT_SIGN + || this == VECT_SIN || this == VECT_COS || this == VECT_TAN + || this == VECT_ASIN || this == VECT_ACOS || this == VECT_ATAN + || this == VECT_SINH || this == VECT_COSH || this == VECT_TANH || this == VECT_CUMSUM || this == VECT_CUMMIN || this == VECT_CUMMAX; } @@ -223,12 +242,21 @@ public class CNodeUnary extends CNode case ROW_MAXS: return "u(Rmax)"; case VECT_EXP: case VECT_POW2: - case VECT_MULT2: - case VECT_SQRT: + case VECT_MULT2: + case VECT_SQRT: case VECT_LOG: case VECT_ABS: case VECT_ROUND: case VECT_CEIL: + case VECT_SIN: + case VECT_COS: + case VECT_TAN: + case VECT_ASIN: + case VECT_ACOS: + case VECT_ATAN: + case VECT_SINH: + case VECT_COSH: + case VECT_TANH: case VECT_FLOOR: case VECT_CUMSUM: case VECT_CUMMIN: @@ -236,11 +264,11 @@ public class CNodeUnary extends CNode case VECT_SIGN: return "u(v"+_type.name().toLowerCase()+")"; case LOOKUP_R: return "u(ixr)"; case LOOKUP_C: return "u(ixc)"; - case LOOKUP_RC: return "u(ixrc)"; + case LOOKUP_RC: return "u(ixrc)"; case LOOKUP0: return "u(ix0)"; case CBIND0: return "u(cbind0)"; case POW2: return "^2"; - default: return "u("+_type.name().toLowerCase()+")"; + default: return "u("+_type.name().toLowerCase()+")"; } } @@ -257,6 +285,15 @@ public class CNodeUnary extends CNode case VECT_CEIL: case VECT_FLOOR: case VECT_SIGN: + case VECT_SIN: + case VECT_COS: + case VECT_TAN: + case VECT_ASIN: + case VECT_ACOS: + case VECT_ATAN: + case VECT_SINH: + case VECT_COSH: + case VECT_TANH: case VECT_CUMSUM: case VECT_CUMMIN: case VECT_CUMMAX: @@ -272,10 +309,10 @@ public class CNodeUnary extends CNode case LOOKUP_R: case LOOKUP_C: case LOOKUP_RC: - case LOOKUP0: + case LOOKUP0: case CBIND0: case POW2: - case MULT2: + case MULT2: case ABS: case SIN: case COS: @@ -283,13 +320,16 @@ public class CNodeUnary extends CNode case ASIN: case ACOS: case ATAN: + case SINH: + case COSH: + case TANH: case SIGN: case SQRT: case LOG: - case ROUND: + case ROUND: case CEIL: case FLOOR: - case SELP: + case SELP: case SPROP: case SIGMOID: case LOG_NZ: http://git-wip-us.apache.org/repos/asf/systemml/blob/c4733840/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 1db01e4..de94969 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 @@ -58,6 +58,7 @@ public class TemplateRow extends TemplateBase private static final Hop.AggOp[] SUPPORTED_ROW_AGG = new AggOp[]{AggOp.SUM, AggOp.MIN, AggOp.MAX}; private static final Hop.OpOp1[] SUPPORTED_VECT_UNARY = new OpOp1[]{ OpOp1.EXP, OpOp1.SQRT, OpOp1.LOG, OpOp1.ABS, OpOp1.ROUND, OpOp1.CEIL, OpOp1.FLOOR, OpOp1.SIGN, + OpOp1.SIN, OpOp1.COS, OpOp1.TAN, OpOp1.ASIN, OpOp1.ACOS, OpOp1.ATAN, OpOp1.SINH, OpOp1.COSH, OpOp1.TANH, OpOp1.CUMSUM, OpOp1.CUMMIN, OpOp1.CUMMAX}; private static final Hop.OpOp2[] SUPPORTED_VECT_BINARY = new OpOp2[]{ OpOp2.MULT, OpOp2.DIV, OpOp2.MINUS, OpOp2.PLUS, OpOp2.POW, OpOp2.MIN, OpOp2.MAX, http://git-wip-us.apache.org/repos/asf/systemml/blob/c4733840/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 e061064..1a17793 100644 --- a/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java +++ b/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java @@ -958,6 +958,241 @@ public class LibSpoofPrimitives return c; } + //custom sin + + public static void vectSinAdd(double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += FastMath.sin(a[j]); + } + + public static void vectSinAdd(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.sin(a[j]); + } + + public static double[] vectSinWrite(double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = FastMath.sin(a[ai]); + return c; + } + + public static double[] vectSinWrite(double[] a, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = FastMath.sin(a[j]); + return c; + } + + //custom cos + + public static void vectCosAdd(double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += FastMath.cos(a[j]); + } + + public static void vectCosAdd(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.cos(a[j]); + } + + public static double[] vectCosWrite(double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = FastMath.cos(a[ai]); + return c; + } + + public static double[] vectCosWrite(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]] = FastMath.cos(a[j]); + return c; + } + + //custom tan + + public static void vectTanAdd(double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += FastMath.tan(a[j]); + } + + public static void vectTanAdd(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.tan(a[j]); + } + + public static double[] vectTanWrite(double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = FastMath.tan(a[ai]); + return c; + } + + public static double[] vectTanWrite(double[] a, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = FastMath.tan(a[j]); + return c; + } + + //custom asin + + public static void vectAsinAdd(double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += FastMath.asin(a[j]); + } + + public static void vectAsinAdd(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.asin(a[j]); + } + + public static double[] vectAsinWrite(double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = FastMath.asin(a[ai]); + return c; + } + + public static double[] vectAsinWrite(double[] a, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = FastMath.asin(a[j]); + return c; + } + + //custom acos + + public static void vectAcosAdd(double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += FastMath.acos(a[j]); + } + + public static void vectAcosAdd(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.acos(a[j]); + } + + public static double[] vectAcosWrite(double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = FastMath.acos(a[ai]); + return c; + } + + public static double[] vectAcosWrite(double[] a, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true, Math.PI/2); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = FastMath.acos(a[j]); + return c; + } + + //custom atan + + public static void vectAtanAdd(double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += Math.atan(a[j]); + } + + public static void vectAtanAdd(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.atan(a[j]); + } + + public static double[] vectAtanWrite(double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = Math.atan(a[ai]); + return c; + } + + public static double[] vectAtanWrite(double[] a, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = Math.atan(a[j]); + return c; + } + + + //custom sinh + + public static void vectSinhAdd(double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += FastMath.sinh(a[j]); + } + + public static void vectSinhAdd(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.sinh(a[j]); + } + + public static double[] vectSinhWrite(double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = FastMath.sinh(a[ai]); + return c; + } + + public static double[] vectSinhWrite(double[] a, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = FastMath.sinh(a[j]); + return c; + } + + //custom cosh + + public static void vectCoshAdd(double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += FastMath.cosh(a[j]); + } + + public static void vectCoshAdd(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.cosh(a[j]); + } + + public static double[] vectCoshWrite(double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = FastMath.cosh(a[ai]); + return c; + } + + public static double[] vectCoshWrite(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]] = FastMath.cosh(a[j]); + return c; + } + + //custom tanh + + public static void vectTanhAdd(double[] a, double[] c, int ai, int ci, int len) { + for( int j = ai; j < ai+len; j++, ci++) + c[ci] += FastMath.tanh(a[j]); + } + + public static void vectTanhAdd(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.tanh(a[j]); + } + + public static double[] vectTanhWrite(double[] a, int ai, int len) { + double[] c = allocVector(len, false); + for( int j = 0; j < len; j++, ai++) + c[j] = FastMath.tanh(a[ai]); + return c; + } + + public static double[] vectTanhWrite(double[] a, int[] aix, int ai, int alen, int len) { + double[] c = allocVector(len, true); + for( int j = ai; j < ai+alen; j++ ) + c[aix[j]] = FastMath.tanh(a[j]); + return c; + } + //custom sign public static void vectSignAdd(double[] a, double[] c, int ai, int ci, int len) { http://git-wip-us.apache.org/repos/asf/systemml/blob/c4733840/src/test/java/org/apache/sysml/test/integration/functions/codegen/CPlanVectorPrimitivesTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/sysml/test/integration/functions/codegen/CPlanVectorPrimitivesTest.java b/src/test/java/org/apache/sysml/test/integration/functions/codegen/CPlanVectorPrimitivesTest.java index 7cc100f..065233c 100644 --- a/src/test/java/org/apache/sysml/test/integration/functions/codegen/CPlanVectorPrimitivesTest.java +++ b/src/test/java/org/apache/sysml/test/integration/functions/codegen/CPlanVectorPrimitivesTest.java @@ -162,6 +162,96 @@ public class CPlanVectorPrimitivesTest extends AutomatedTestBase } @Test + public void testVectorSinDense() { + testVectorUnaryPrimitive(UnaryType.VECT_SIN, InputType.VECTOR_DENSE); + } + + @Test + public void testVectorSinSparse() { + testVectorUnaryPrimitive(UnaryType.VECT_SIN, InputType.VECTOR_SPARSE); + } + + @Test + public void testVectorCosDense() { + testVectorUnaryPrimitive(UnaryType.VECT_COS, InputType.VECTOR_DENSE); + } + + @Test + public void testVectorCosSparse() { + testVectorUnaryPrimitive(UnaryType.VECT_COS, InputType.VECTOR_SPARSE); + } + + @Test + public void testVectorTanDense() { + testVectorUnaryPrimitive(UnaryType.VECT_TAN, InputType.VECTOR_DENSE); + } + + @Test + public void testVectorTanSparse() { + testVectorUnaryPrimitive(UnaryType.VECT_TAN, InputType.VECTOR_SPARSE); + } + + @Test + public void testVectorASinDense() { + testVectorUnaryPrimitive(UnaryType.VECT_ASIN, InputType.VECTOR_DENSE); + } + + @Test + public void testVectorASinSparse() { + testVectorUnaryPrimitive(UnaryType.VECT_ASIN, InputType.VECTOR_SPARSE); + } + + @Test + public void testVectorACosDense() { + testVectorUnaryPrimitive(UnaryType.VECT_ACOS, InputType.VECTOR_DENSE); + } + + @Test + public void testVectorACosSparse() { + testVectorUnaryPrimitive(UnaryType.VECT_ACOS, InputType.VECTOR_SPARSE); + } + + @Test + public void testVectorATanDense() { + testVectorUnaryPrimitive(UnaryType.VECT_ATAN, InputType.VECTOR_DENSE); + } + + @Test + public void testVectorATanSparse() { + testVectorUnaryPrimitive(UnaryType.VECT_ATAN, InputType.VECTOR_SPARSE); + } + + @Test + public void testVectorSinHDense() { + testVectorUnaryPrimitive(UnaryType.VECT_SINH, InputType.VECTOR_DENSE); + } + + @Test + public void testVectorSinHSparse() { + testVectorUnaryPrimitive(UnaryType.VECT_SINH, InputType.VECTOR_SPARSE); + } + + @Test + public void testVectorCosHDense() { + testVectorUnaryPrimitive(UnaryType.VECT_COSH, InputType.VECTOR_DENSE); + } + + @Test + public void testVectorCosHSparse() { + testVectorUnaryPrimitive(UnaryType.VECT_COSH, InputType.VECTOR_SPARSE); + } + + @Test + public void testVectorTanHDense() { + testVectorUnaryPrimitive(UnaryType.VECT_TANH, InputType.VECTOR_DENSE); + } + + @Test + public void testVectorTanHSparse() { + testVectorUnaryPrimitive(UnaryType.VECT_TANH, InputType.VECTOR_SPARSE); + } + + @Test public void testVectorSignDense() { testVectorUnaryPrimitive(UnaryType.VECT_SIGN, InputType.VECTOR_DENSE); }
