You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@systemml.apache.org by mb...@apache.org on 2018/02/04 21:59:44 UTC

systemml git commit: [SYSTEMML-2068] Codegen support for xor operations

Repository: systemml
Updated Branches:
  refs/heads/master a671883fc -> c3601d419


[SYSTEMML-2068] Codegen support for xor operations

Closes #718.


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

Branch: refs/heads/master
Commit: c3601d419a47f218af1517eaee66383d820ada86
Parents: a671883
Author: Janardhan Pulivarthi <j1...@protonmail.com>
Authored: Sun Feb 4 13:53:00 2018 -0800
Committer: Matthias Boehm <mb...@gmail.com>
Committed: Sun Feb 4 13:55:19 2018 -0800

----------------------------------------------------------------------
 .../sysml/hops/codegen/cplan/CNodeBinary.java   | 28 ++++--
 .../hops/codegen/template/TemplateRow.java      |  2 +-
 .../runtime/codegen/LibSpoofPrimitives.java     | 95 +++++++++++++++++++-
 .../codegen/CPlanVectorPrimitivesTest.java      | 32 ++++++-
 .../functions/codegen/CellwiseTmplTest.java     | 22 ++++-
 .../functions/codegen/RowAggTmplTest.java       | 21 ++++-
 .../scripts/functions/codegen/cellwisetmpl17.R  | 33 +++++++
 .../functions/codegen/cellwisetmpl17.dml        | 29 ++++++
 .../scripts/functions/codegen/rowAggPattern36.R | 33 +++++++
 .../functions/codegen/rowAggPattern36.dml       | 29 ++++++
 10 files changed, 309 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/systemml/blob/c3601d41/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 d771a84..2f7feb0 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
@@ -35,22 +35,24 @@ public class CNodeBinary extends CNode
 		VECT_POW_ADD, VECT_MIN_ADD, VECT_MAX_ADD,
 		VECT_EQUAL_ADD, VECT_NOTEQUAL_ADD, VECT_LESS_ADD, 
 		VECT_LESSEQUAL_ADD, VECT_GREATER_ADD, VECT_GREATEREQUAL_ADD,
-		VECT_CBIND_ADD,
+		VECT_CBIND_ADD, VECT_XOR_ADD,
 		//vector-scalar operations
 		VECT_MULT_SCALAR, VECT_DIV_SCALAR, VECT_MINUS_SCALAR, VECT_PLUS_SCALAR,
 		VECT_POW_SCALAR, VECT_MIN_SCALAR, VECT_MAX_SCALAR,
 		VECT_EQUAL_SCALAR, VECT_NOTEQUAL_SCALAR, VECT_LESS_SCALAR, 
 		VECT_LESSEQUAL_SCALAR, VECT_GREATER_SCALAR, VECT_GREATEREQUAL_SCALAR,
 		VECT_CBIND,
+		VECT_XOR_SCALAR,
 		//vector-vector operations
 		VECT_MULT, VECT_DIV, VECT_MINUS, VECT_PLUS, VECT_MIN, VECT_MAX, VECT_EQUAL, 
 		VECT_NOTEQUAL, VECT_LESS, VECT_LESSEQUAL, VECT_GREATER, VECT_GREATEREQUAL,
+		VECT_XOR,
 		//scalar-scalar operations
 		MULT, DIV, PLUS, MINUS, MODULUS, INTDIV, 
 		LESS, LESSEQUAL, GREATER, GREATEREQUAL, EQUAL,NOTEQUAL,
-		MIN, MAX, AND, OR, LOG, LOG_NZ, POW,
+		MIN, MAX, AND, OR, XOR, LOG, LOG_NZ, POW,
 		MINUS1_MULT, MINUS_NZ;
-		
+
 		public static boolean contains(String value) {
 			for( BinType bt : values()  )
 				if( bt.name().equals(value) )
@@ -88,6 +90,7 @@ public class CNodeBinary extends CNode
 				case VECT_MINUS_ADD:
 				case VECT_PLUS_ADD:
 				case VECT_POW_ADD:
+				case VECT_XOR_ADD:
 				case VECT_MIN_ADD:
 				case VECT_MAX_ADD:	
 				case VECT_EQUAL_ADD:
@@ -112,6 +115,7 @@ public class CNodeBinary extends CNode
 				case VECT_MINUS_SCALAR:
 				case VECT_PLUS_SCALAR:
 				case VECT_POW_SCALAR:
+				case VECT_XOR_SCALAR:
 				case VECT_MIN_SCALAR:
 				case VECT_MAX_SCALAR:
 				case VECT_EQUAL_SCALAR:
@@ -142,6 +146,7 @@ public class CNodeBinary extends CNode
 				case VECT_DIV:
 				case VECT_MINUS:
 				case VECT_PLUS:
+				case VECT_XOR:
 				case VECT_MIN:
 				case VECT_MAX:
 				case VECT_EQUAL:
@@ -199,6 +204,8 @@ public class CNodeBinary extends CNode
 					return "    double %TMP% = 1 - %IN1% * %IN2%;\n";
 				case MINUS_NZ:
 					return "    double %TMP% = (%IN1% != 0) ? %IN1% - %IN2% : 0;\n";
+				case XOR:
+					return "    double %TMP% = ( (%IN1% != 0) != (%IN2% != 0) ) ? 1 : 0;\n";
 					
 				default: 
 					throw new RuntimeException("Invalid binary type: "+this.toString());
@@ -217,7 +224,8 @@ public class CNodeBinary extends CNode
 				|| this == VECT_EQUAL_SCALAR || this == VECT_NOTEQUAL_SCALAR
 				|| this == VECT_LESS_SCALAR || this == VECT_LESSEQUAL_SCALAR
 				|| this == VECT_GREATER_SCALAR || this == VECT_GREATEREQUAL_SCALAR
-				|| this == VECT_CBIND;
+				|| this == VECT_CBIND
+				|| this == VECT_XOR_SCALAR;
 		}
 		public boolean isVectorVectorPrimitive() {
 			return this == VECT_DIV || this == VECT_MULT 
@@ -225,7 +233,8 @@ public class CNodeBinary extends CNode
 				|| this == VECT_MIN || this == VECT_MAX
 				|| this == VECT_EQUAL || this == VECT_NOTEQUAL
 				|| this == VECT_LESS || this == VECT_LESSEQUAL
-				|| this == VECT_GREATER || this == VECT_GREATEREQUAL;
+				|| this == VECT_GREATER || this == VECT_GREATEREQUAL
+				|| this == VECT_XOR;
 		}
 		public boolean isVectorMatrixPrimitive() {
 			return this == VECT_MATRIXMULT
@@ -351,6 +360,7 @@ public class CNodeBinary extends CNode
 			case VECT_DIV_SCALAR:          return "b(vd)";
 			case VECT_MINUS_SCALAR:        return "b(vmi)";
 			case VECT_PLUS_SCALAR:         return "b(vp)";
+			case VECT_XOR_SCALAR:          return "v(vxor)";
 			case VECT_POW_SCALAR:          return "b(vpow)";
 			case VECT_MIN_SCALAR:          return "b(vmin)";
 			case VECT_MAX_SCALAR:          return "b(vmax)";
@@ -364,6 +374,7 @@ public class CNodeBinary extends CNode
 			case VECT_DIV:                 return "b(v2d)";
 			case VECT_MINUS:               return "b(v2mi)";
 			case VECT_PLUS:                return "b(v2p)";
+			case VECT_XOR:                 return "b(v2xor)";
 			case VECT_MIN:                 return "b(v2min)";
 			case VECT_MAX:                 return "b(v2max)";
 			case VECT_EQUAL:               return "b(v2eq)";
@@ -388,6 +399,7 @@ public class CNodeBinary extends CNode
 			case NOTEQUAL:                 return "b(!=)";
 			case OR:                       return "b(|)";
 			case AND:                      return "b(&)";
+			case XOR:                      return "b(xor)";
 			case MINUS1_MULT:              return "b(1-*)";
 			case MINUS_NZ:                 return "b(-nz)";
 			default: return "b("+_type.name().toLowerCase()+")";
@@ -413,6 +425,7 @@ public class CNodeBinary extends CNode
 			case VECT_GREATER_ADD: 
 			case VECT_GREATEREQUAL_ADD:
 			case VECT_CBIND_ADD:
+			case VECT_XOR_ADD:
 				boolean vectorScalar = _inputs.get(1).getDataType()==DataType.SCALAR;
 				_rows = _inputs.get(vectorScalar ? 0 : 1)._rows;
 				_cols = _inputs.get(vectorScalar ? 0 : 1)._cols;
@@ -435,6 +448,7 @@ public class CNodeBinary extends CNode
 			case VECT_MULT_SCALAR:
 			case VECT_MINUS_SCALAR:
 			case VECT_PLUS_SCALAR:
+			case VECT_XOR_SCALAR:
 			case VECT_POW_SCALAR:
 			case VECT_MIN_SCALAR:
 			case VECT_MAX_SCALAR:
@@ -449,6 +463,7 @@ public class CNodeBinary extends CNode
 			case VECT_MULT:
 			case VECT_MINUS:
 			case VECT_PLUS:
+			case VECT_XOR:
 			case VECT_MIN:
 			case VECT_MAX:
 			case VECT_EQUAL: 
@@ -491,7 +506,8 @@ public class CNodeBinary extends CNode
 			case MIN: 
 			case MAX: 
 			case AND: 
-			case OR: 
+			case OR:
+			case XOR:
 			case LOG: 
 			case LOG_NZ:
 			case POW: 

http://git-wip-us.apache.org/repos/asf/systemml/blob/c3601d41/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 5bc8f4f..74d7b78 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
@@ -65,7 +65,7 @@ public class TemplateRow extends TemplateBase
 			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,
+			OpOp2.MULT, OpOp2.DIV, OpOp2.MINUS, OpOp2.PLUS, OpOp2.POW, OpOp2.MIN, OpOp2.MAX, OpOp2.XOR,
 			OpOp2.EQUAL, OpOp2.NOTEQUAL, OpOp2.LESS, OpOp2.LESSEQUAL, OpOp2.GREATER, OpOp2.GREATEREQUAL};
 	
 	public TemplateRow() {

http://git-wip-us.apache.org/repos/asf/systemml/blob/c3601d41/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 8edb25e..33b18b9 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
@@ -560,9 +560,98 @@ public class LibSpoofPrimitives
 		//invariant to the ordering of inputs
 		return vectPlusWrite(b, a, bix, bi, ai, blen, len);
 	}
-	
+
+	//custom vector xor
+	/**
+	 * Computes c = xor(A,B)
+	 *
+	 * @param a dense input vector A
+	 * @param ai start position in A
+	 * @param bval scalar value
+	 * @param c resultant vector
+	 * @param ci index of c
+	 * @param len number of processed elements
+	 * @return resultant value
+	 */
+	public static void vectXorAdd(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] != 0) != (bval != 0) ) ? 1 : 0;
+	}
+
+	public static void vectXorAdd(double bval, double[] a, double[] c, int ai, int ci, int len) {
+		for( int j = ai; j < ai+len; j++, ci++)
+			c[ci] += ( (bval != 0) != (a[j] != 0) ) ? 1 : 0;
+	}
+
+	public static void vectXorAdd(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] != 0) != (bval != 0) ) ? 1 : 0;
+	}
+
+	public static void vectXorAdd(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 != 0) != (a[j] != 0) ) ? 1 : 0;
+	}
+
+	//1. scalar vs. dense vector
+	public static double[] vectXorWrite(double[] a, double bval, int ai, int len) {
+		double[] c = allocVector(len, false);
+		for( int j = 0; j < len; j++)
+			c[j] = ( ( a[ai+j] != 0) != (bval != 0) ) ? 1 : 0;
+		return c;
+	}
+
+	//2. dense vector vs. scalar
+	public static double[] vectXorWrite(double bval, double[] a, int ai, int len) {
+		double[] c = allocVector(len, false);
+		for( int j = 0; j < len; j++)
+			c[j] = ( (bval != 0) != (a[ai + j] != 0) ) ? 1 : 0;
+		return c;
+	}
+
+	//3. dense vector vs. dense vector
+	public static double[] vectXorWrite(double[] a, double[] b, int ai, int bi, int len) {
+		double[] c = allocVector(len, false);
+		for( int j = 0; j < len; j++)
+			c[j] = ( (a[ai + j] != 0) != (b[bi + j] != 0) ) ? 1 : 0;
+		return c;
+	}
+
+	//4. sparse vector vs scalar
+	public static double[] vectXorWrite(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] != 0) ? 0 : 1;
+		return c;
+	}
+
+	//5. scalar vs. sparse vector
+	public static double[] vectXorWrite(double bval, double[] a, 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] != 0) ? 0 : 1;
+		return c;
+	}
+
+	//6. sparse vector vs. dense vector
+	public static double[] vectXorWrite(double[] a, double[] b, int[] aix, int ai, int bi, int alen, int len) {
+		double[] c = allocVector(len, false);
+		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] != 0) != (c[aix[j]] != 0) )? 1 : 0;
+		return c;
+	}
+
+	//6. sparse vector vs. dense vector
+	public static void vectXorWrite(double[] a, double[] b, int ai, int[] aix, int bi, int alen, int len) {
+		vectXorWrite(a, b, aix, ai, bi, alen, len);
+	}
+
 	//custom vector pow
-	
+
 	public static void vectPowAdd(double[] a, double bval, double[] c, int ai, int ci, int len) {
 		for( int j = ai; j < ai+len; j++, ci++)
 			c[ci] += Math.pow(a[j], bval);
@@ -1862,7 +1951,7 @@ public class LibSpoofPrimitives
 	}
 	
 	protected static double[] allocVector(int len, boolean reset, double resetVal) {
-		VectorBuffer buff = memPool.get(); 
+		VectorBuffer buff = memPool.get();
 		
 		//find next matching vector in ring buffer or
 		//allocate new vector if required

http://git-wip-us.apache.org/repos/asf/systemml/blob/c3601d41/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 c2c4704..d43ffa5 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
@@ -644,7 +644,37 @@ public class CPlanVectorPrimitivesTest extends AutomatedTestBase
 	public void testVectorVectorGreaterEqualSparseDense() {
 		testVectorBinaryPrimitive(BinType.VECT_GREATEREQUAL, InputType.VECTOR_SPARSE, InputType.VECTOR_DENSE);
 	}
-	
+
+	@Test
+	public void testScalarVectorXorDense() {
+		testVectorBinaryPrimitive(BinType.VECT_XOR_SCALAR, InputType.SCALAR, InputType.VECTOR_DENSE);
+	}
+
+	@Test
+	public void testVectorScalarXorDense() {
+		testVectorBinaryPrimitive(BinType.VECT_XOR_SCALAR, InputType.VECTOR_DENSE, InputType.VECTOR_DENSE);
+	}
+
+	@Test
+	public void testVectorVectorDenseDense() {
+		testVectorBinaryPrimitive(BinType.VECT_XOR, InputType.VECTOR_DENSE, InputType.VECTOR_DENSE);
+	}
+
+	@Test
+	public void testVectorScalarSparse() {
+		testVectorBinaryPrimitive(BinType.VECT_XOR_SCALAR, InputType.VECTOR_SPARSE, InputType.SCALAR);
+	}
+
+	@Test
+	public void testScalarVectorSparse() {
+		testVectorBinaryPrimitive(BinType.VECT_XOR_SCALAR, InputType.SCALAR, InputType.VECTOR_SPARSE);
+	}
+
+	@Test
+	public void testVectorVectorSparseDense() {
+		testVectorBinaryPrimitive(BinType.VECT_XOR, InputType.VECTOR_SPARSE, InputType.VECTOR_DENSE);
+	}
+
 	@SuppressWarnings("incomplete-switch")
 	private static void testVectorAggPrimitive(UnaryType aggtype, InputType type1)
 	{

http://git-wip-us.apache.org/repos/asf/systemml/blob/c3601d41/src/test/java/org/apache/sysml/test/integration/functions/codegen/CellwiseTmplTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/sysml/test/integration/functions/codegen/CellwiseTmplTest.java b/src/test/java/org/apache/sysml/test/integration/functions/codegen/CellwiseTmplTest.java
index 701a367..bd3b36a 100644
--- a/src/test/java/org/apache/sysml/test/integration/functions/codegen/CellwiseTmplTest.java
+++ b/src/test/java/org/apache/sysml/test/integration/functions/codegen/CellwiseTmplTest.java
@@ -51,7 +51,8 @@ public class CellwiseTmplTest extends AutomatedTestBase
 	private static final String TEST_NAME13 = TEST_NAME+13; //min(X + 7 * Y) large
 	private static final String TEST_NAME14 = TEST_NAME+14; //-2 * X + t(Y); t(Y) is rowvector
 	private static final String TEST_NAME15 = TEST_NAME+15; //colMins(2*log(X))
-	private static final String TEST_NAME16 = TEST_NAME+16; //colSums(2*log(X)); 
+	private static final String TEST_NAME16 = TEST_NAME+16; //colSums(2*log(X));
+	private static final String TEST_NAME17 = TEST_NAME+17; //xor operation
 	
 	
 	private static final String TEST_DIR = "functions/codegen/";
@@ -65,7 +66,7 @@ public class CellwiseTmplTest extends AutomatedTestBase
 	@Override
 	public void setUp() {
 		TestUtils.clearAssertionInformation();
-		for( int i=1; i<=16; i++ ) {
+		for( int i=1; i<=17; i++ ) {
 			addTestConfiguration( TEST_NAME+i, new TestConfiguration(
 					TEST_CLASS_DIR, TEST_NAME+i, new String[] {String.valueOf(i)}) );
 		}
@@ -287,6 +288,21 @@ public class CellwiseTmplTest extends AutomatedTestBase
 	public void testCodegenCellwiseRewrite16_sp() {
 		testCodegenIntegration( TEST_NAME16, true, ExecType.SPARK );
 	}
+
+	@Test
+	public void testCodegenCellwiseRewrite17() {
+		testCodegenIntegration( TEST_NAME17, true, ExecType.CP );
+	}
+
+	@Test
+	public void testCodegenCellwise17() {
+		testCodegenIntegration( TEST_NAME17, false, ExecType.CP );
+	}
+
+	@Test
+	public void testCodegenCellwiseRewrite17_sp() {
+		testCodegenIntegration( TEST_NAME17, true, ExecType.SPARK );
+	}
 	
 	
 	private void testCodegenIntegration( String testname, boolean rewrites, ExecType instType )
@@ -352,6 +368,8 @@ public class CellwiseTmplTest extends AutomatedTestBase
 				Assert.assertTrue(!heavyHittersContainsSubString("uacmin"));
 			else if( testname.equals(TEST_NAME16) )
 				Assert.assertTrue(!heavyHittersContainsSubString("uack+"));
+			else if( testname.equals(TEST_NAME17) )
+				Assert.assertTrue(!heavyHittersContainsSubString("xor"));
 		}
 		finally {
 			rtplatform = platformOld;

http://git-wip-us.apache.org/repos/asf/systemml/blob/c3601d41/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 6124c77..129178d 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
@@ -72,6 +72,7 @@ public class RowAggTmplTest extends AutomatedTestBase
 	private static final String TEST_NAME33 = TEST_NAME+"33"; //Kmeans, inner loop
 	private static final String TEST_NAME34 = TEST_NAME+"34"; //X / rowSums(X!=0)
 	private static final String TEST_NAME35 = TEST_NAME+"35"; //cbind(X/rowSums(X), Y, Z)
+	private static final String TEST_NAME36 = TEST_NAME+"36"; //xor operation
 	
 	private static final String TEST_DIR = "functions/codegen/";
 	private static final String TEST_CLASS_DIR = TEST_DIR + RowAggTmplTest.class.getSimpleName() + "/";
@@ -83,7 +84,7 @@ public class RowAggTmplTest extends AutomatedTestBase
 	@Override
 	public void setUp() {
 		TestUtils.clearAssertionInformation();
-		for(int i=1; i<=35; i++)
+		for(int i=1; i<=36; i++)
 			addTestConfiguration( TEST_NAME+i, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME+i, new String[] { String.valueOf(i) }) );
 	}
 	
@@ -611,7 +612,21 @@ public class RowAggTmplTest extends AutomatedTestBase
 	public void testCodegenRowAgg35SP() {
 		testCodegenIntegration( TEST_NAME35, false, ExecType.SPARK );
 	}
-	
+
+	@Test
+	public void testCodegenRowAggRewrite36CP() {
+		testCodegenIntegration( TEST_NAME36, true, ExecType.CP );
+	}
+
+	@Test
+	public void testCodegenRowAgg36CP() {
+		testCodegenIntegration( TEST_NAME36, false, ExecType.CP );
+	}
+
+	@Test
+	public void testCodegenRowAgg36SP() {
+		testCodegenIntegration( TEST_NAME36, false, ExecType.SPARK );
+	}
 	
 	private void testCodegenIntegration( String testname, boolean rewrites, ExecType instType )
 	{
@@ -667,6 +682,8 @@ public class RowAggTmplTest extends AutomatedTestBase
 			if( testname.equals(TEST_NAME35) )
 				Assert.assertTrue(!heavyHittersContainsSubString("spoofRA", 2)
 					&& !heavyHittersContainsSubString("cbind"));
+			if( testname.equals(TEST_NAME36) )
+				Assert.assertTrue(!heavyHittersContainsSubString("xor"));
 		}
 		finally {
 			rtplatform = platformOld;

http://git-wip-us.apache.org/repos/asf/systemml/blob/c3601d41/src/test/scripts/functions/codegen/cellwisetmpl17.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/cellwisetmpl17.R b/src/test/scripts/functions/codegen/cellwisetmpl17.R
new file mode 100644
index 0000000..a1ae201
--- /dev/null
+++ b/src/test/scripts/functions/codegen/cellwisetmpl17.R
@@ -0,0 +1,33 @@
+#-------------------------------------------------------------
+#
+# 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")
+
+X = matrix(seq(7, 1100*200+6), 1100, 200, byrow=TRUE);
+
+R1 = (X/3) %% 0.6;
+R2 = (X/3) %/% 0.6;
+
+R = xor(R1, R2);
+
+writeMM(as(R,"CsparseMatrix"), paste(args[2], "S", sep=""));

http://git-wip-us.apache.org/repos/asf/systemml/blob/c3601d41/src/test/scripts/functions/codegen/cellwisetmpl17.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/cellwisetmpl17.dml b/src/test/scripts/functions/codegen/cellwisetmpl17.dml
new file mode 100644
index 0000000..151b4f7
--- /dev/null
+++ b/src/test/scripts/functions/codegen/cellwisetmpl17.dml
@@ -0,0 +1,29 @@
+#-------------------------------------------------------------
+#
+# 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(7, 1100*200+6), 1100, 200);
+
+R1 = (X/3) %% 0.6;
+R2 = (X/3) %/% 0.6;
+
+S = xor(R1, R2);
+
+write(S, $1)

http://git-wip-us.apache.org/repos/asf/systemml/blob/c3601d41/src/test/scripts/functions/codegen/rowAggPattern36.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/rowAggPattern36.R b/src/test/scripts/functions/codegen/rowAggPattern36.R
new file mode 100644
index 0000000..349720e
--- /dev/null
+++ b/src/test/scripts/functions/codegen/rowAggPattern36.R
@@ -0,0 +1,33 @@
+#-------------------------------------------------------------
+#
+# 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, 6000)/600, 300, 20);
+
+Y = X/rowSums(X)
+
+R = xor(X,Y);
+
+writeMM(as(R, "CsparseMatrix"), paste(args[2], "S", sep=""));

http://git-wip-us.apache.org/repos/asf/systemml/blob/c3601d41/src/test/scripts/functions/codegen/rowAggPattern36.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/rowAggPattern36.dml b/src/test/scripts/functions/codegen/rowAggPattern36.dml
new file mode 100644
index 0000000..cded6cc
--- /dev/null
+++ b/src/test/scripts/functions/codegen/rowAggPattern36.dml
@@ -0,0 +1,29 @@
+#-------------------------------------------------------------
+#
+# 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, 6000)/600, 300, 20);
+
+Y = X/rowSums(X)
+
+S = xor(X, Y);
+
+write(S, $1);
+