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 2016/09/11 22:33:29 UTC

[1/2] incubator-systemml git commit: [SYSTEMML-816] New min/max aggregates (rc/r/c) over compressed matrices

Repository: incubator-systemml
Updated Branches:
  refs/heads/master f0c91ed0d -> bf4669232


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/test/java/org/apache/sysml/test/integration/functions/compress/ParUnaryAggregateTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/sysml/test/integration/functions/compress/ParUnaryAggregateTest.java b/src/test/java/org/apache/sysml/test/integration/functions/compress/ParUnaryAggregateTest.java
index 5224298..dde370d 100644
--- a/src/test/java/org/apache/sysml/test/integration/functions/compress/ParUnaryAggregateTest.java
+++ b/src/test/java/org/apache/sysml/test/integration/functions/compress/ParUnaryAggregateTest.java
@@ -59,7 +59,13 @@ public class ParUnaryAggregateTest extends AutomatedTestBase
 		SUM,
 		ROWSUMSSQ,
 		COLSUMSSQ,
-		SUMSQ
+		SUMSQ,
+		ROWMAXS,
+		COLMAXS,
+		MAX,
+		ROWMINS,
+		COLMINS,
+		MIN,
 	}
 	
 	@Override
@@ -486,6 +492,427 @@ public class ParUnaryAggregateTest extends AutomatedTestBase
 	public void testSumSqSparseConstDataNoCompression() {
 		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.SUMSQ, false);
 	}
+	
+
+	@Test
+	public void testRowMaxsDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.COLMAXS, false);
+	}
+
+	@Test
+	public void testMaxDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testRowMinsDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testColMinsDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.COLMINS, false);
+	}
+
+	@Test
+	public void testMinDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.MIN, false);
+	}
 		
 	/**
 	 * 
@@ -520,6 +947,12 @@ public class ParUnaryAggregateTest extends AutomatedTestBase
 				case SUMSQ: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uasqk+"); break;
 				case ROWSUMSSQ: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uarsqk+"); break;
 				case COLSUMSSQ: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uacsqk+"); break;
+				case MAX: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uamax"); break;
+				case ROWMAXS: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uarmax"); break;
+				case COLMAXS: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uacmax"); break;
+				case MIN: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uamin"); break;
+				case ROWMINS: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uarmin"); break;
+				case COLMINS: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uacmin"); break;
 			}
 			auop.setNumThreads(InfrastructureAnalyzer.getLocalParallelism());
 			
@@ -537,8 +970,10 @@ public class ParUnaryAggregateTest extends AutomatedTestBase
 			//compare result with input
 			double[][] d1 = DataConverter.convertToDoubleMatrix(ret1);
 			double[][] d2 = DataConverter.convertToDoubleMatrix(ret2);
-			int dim1 = (aggtype == AggType.ROWSUMS)?rows:1;
-			int dim2 = (aggtype == AggType.COLSUMS)?cols1:1;
+			int dim1 = (aggtype == AggType.ROWSUMS || aggtype == AggType.ROWSUMSSQ 
+					|| aggtype == AggType.ROWMINS || aggtype == AggType.ROWMINS)?rows:1;
+			int dim2 = (aggtype == AggType.COLSUMS || aggtype == AggType.COLSUMSSQ 
+					|| aggtype == AggType.COLMAXS || aggtype == AggType.COLMINS)?cols1:1;
 			TestUtils.compareMatrices(d1, d2, dim1, dim2, 0.00000000001);
 		}
 		catch(Exception ex) {


[2/2] incubator-systemml git commit: [SYSTEMML-816] New min/max aggregates (rc/r/c) over compressed matrices

Posted by mb...@apache.org.
[SYSTEMML-816] New min/max aggregates (rc/r/c) over compressed matrices 

This patch introduces min/max/rowMins/rowMax/colMins/colMaxs over
compressed matrix blocks. Full min/max and colMins/colMaxs are computed
purely over the dictionary of distinct values (incl zero handling),
while rowMins/rowMaxs are computed in a cache-conscious manner.
Furthermore, this also includes additional tests for various compression
formats over dense and sparse data.

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

Branch: refs/heads/master
Commit: bf4669232a0681d0115c8cc3bb9ea86714ed420d
Parents: f0c91ed
Author: Matthias Boehm <mb...@us.ibm.com>
Authored: Mon Sep 12 00:22:07 2016 +0200
Committer: Matthias Boehm <mb...@us.ibm.com>
Committed: Mon Sep 12 00:22:07 2016 +0200

----------------------------------------------------------------------
 .../sysml/runtime/compress/ColGroupBitmap.java  |  89 +++-
 .../sysml/runtime/compress/ColGroupOLE.java     |  83 +++-
 .../sysml/runtime/compress/ColGroupRLE.java     |  79 +++-
 .../runtime/compress/CompressedMatrixBlock.java |  51 ++-
 .../runtime/compress/UncompressedBitmap.java    |  13 +-
 .../runtime/compress/utils/ConverterUtils.java  |   8 +-
 .../sysml/runtime/functionobjects/Builtin.java  | 148 +++----
 .../runtime/instructions/InstructionUtils.java  |  24 +-
 .../sysml/runtime/matrix/data/LibMatrixAgg.java |   6 +-
 .../runtime/matrix/data/LibMatrixOuterAgg.java  |   8 +-
 .../sysml/runtime/matrix/data/MatrixBlock.java  |  12 +-
 .../matrix/data/OperationsOnMatrixValues.java   |   4 +-
 .../matrix/operators/BinaryOperator.java        |  12 +-
 .../matrix/operators/ScalarOperator.java        |  10 +-
 .../runtime/matrix/operators/UnaryOperator.java |  10 +-
 .../compress/BasicUnaryAggregateTest.java       | 440 +++++++++++++++++-
 .../compress/ParUnaryAggregateTest.java         | 441 ++++++++++++++++++-
 17 files changed, 1265 insertions(+), 173 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/compress/ColGroupBitmap.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/compress/ColGroupBitmap.java b/src/main/java/org/apache/sysml/runtime/compress/ColGroupBitmap.java
index 5bd3e52..d939d3f 100644
--- a/src/main/java/org/apache/sysml/runtime/compress/ColGroupBitmap.java
+++ b/src/main/java/org/apache/sysml/runtime/compress/ColGroupBitmap.java
@@ -30,6 +30,8 @@ import java.util.Map.Entry;
 
 import org.apache.sysml.runtime.DMLRuntimeException;
 import org.apache.sysml.runtime.compress.utils.LinearAlgebraUtils;
+import org.apache.sysml.runtime.functionobjects.Builtin;
+import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinCode;
 import org.apache.sysml.runtime.matrix.data.MatrixBlock;
 import org.apache.sysml.runtime.matrix.operators.ScalarOperator;
 
@@ -63,6 +65,7 @@ public abstract class ColGroupBitmap extends ColGroup
 	/** Bitmaps, one per uncompressed value in {@link #values}. */
 	protected int[] _ptr; //bitmap offsets per value
 	protected char[] _data; //linearized bitmaps (variable length)
+	protected boolean _zeros; //contains zero values
 	
 	protected int[] _skiplist;
 	
@@ -91,6 +94,8 @@ public abstract class ColGroupBitmap extends ColGroup
 		final int numVals = ubm.getNumValues();
 		
 		_values = new double[numVals*numCols];
+		_zeros = (ubm.getNumOffsets() < numRows);
+		
 		for (int i=0; i<numVals; i++) {
 			//note: deep copied internally on getValues
 			double[] tmp = ubm.getValues(i);
@@ -109,8 +114,9 @@ public abstract class ColGroupBitmap extends ColGroup
 	 *            set of distinct values for the block (associated bitmaps are
 	 *            kept in the subclass)
 	 */
-	protected ColGroupBitmap(CompressionType type, int[] colIndices, int numRows, double[] values) {
+	protected ColGroupBitmap(CompressionType type, int[] colIndices, int numRows, boolean zeros, double[] values) {
 		super(type, colIndices, numRows);
+		_zeros = zeros;
 		_values = values;
 	}
 	
@@ -118,6 +124,8 @@ public abstract class ColGroupBitmap extends ColGroup
 		return _ptr[k+1] - _ptr[k];
 	}
 
+	
+	
 	/**
 	 * 
 	 * @param numVals
@@ -339,6 +347,23 @@ public abstract class ColGroupBitmap extends ColGroup
 			LinearAlgebraUtils.vectMultiplyAdd(b[i], _values, c, off, 0, numVals);
 	}
 
+	/**
+	 * 
+	 * @param bitmapIx
+	 * @param builtin
+	 * @return
+	 */
+	protected final double mxxValues(int bitmapIx, Builtin builtin)
+	{
+		final int numCols = getNumCols();
+		final int valOff = bitmapIx * numCols;
+		
+		double val = Double.MAX_VALUE * ((builtin.getBuiltinCode()==BuiltinCode.MAX)?-1:1);
+		for( int i = 0; i < numCols; i++ )
+			val = builtin.execute2(val, _values[valOff+i]);
+		
+		return val;
+	}
 
 	/**
 	 * 
@@ -397,6 +422,60 @@ public abstract class ColGroupBitmap extends ColGroup
 		
 		return ret;
 	}
+	
+	/**
+	 * NOTE: Shared across OLE/RLE because value-only computation. 
+	 * 
+	 * @param result
+	 * @throws DMLRuntimeException 
+	 */
+	protected void computeMxx(MatrixBlock result, Builtin builtin) 
+	{
+		//init and 0-value handling
+		double val = Double.MAX_VALUE * ((builtin.getBuiltinCode()==BuiltinCode.MAX)?-1:1);
+		if( _zeros )
+			val = builtin.execute2(val, 0);
+		
+		//iterate over all values only
+		final int numVals = getNumValues();
+		final int numCols = getNumCols();		
+		for (int k = 0; k < numVals; k++)
+			for( int j=0, valOff = k*numCols; j<numCols; j++ )
+				val = builtin.execute2(val, _values[ valOff+j ]);
+		
+		//compute new partial aggregate
+		val = builtin.execute2(val, result.quickGetValue(0, 0));
+		result.quickSetValue(0, 0, val);
+	}
+	
+	/**
+	 * NOTE: Shared across OLE/RLE because value-only computation. 
+	 * 
+	 * @param result
+	 */
+	protected void computeColMxx(MatrixBlock result, Builtin builtin)
+	{
+		final int numVals = getNumValues();
+		final int numCols = getNumCols();
+		
+		//init and 0-value handling
+		double[] vals = new double[numCols];
+		Arrays.fill(vals, Double.MAX_VALUE * ((builtin.getBuiltinCode()==BuiltinCode.MAX)?-1:1));
+		if( _zeros ) {
+			for( int j = 0; j < numCols; j++ )
+				vals[j] = builtin.execute2(vals[j], 0);		
+		}
+		
+		//iterate over all values only
+		for (int k = 0; k < numVals; k++) 
+			for( int j=0, valOff=k*numCols; j<numCols; j++ )
+				vals[j] = builtin.execute2(vals[j], _values[ valOff+j ]);
+		
+		//copy results to output
+		for( int j=0; j<numCols; j++ )
+			result.quickSetValue(0, _colIndexes[j], vals[j]);
+	}
+	
 
 	/**
 	 * @return the number of distinct sets of values associated with the bitmaps
@@ -426,6 +505,10 @@ public abstract class ColGroupBitmap extends ColGroup
 		return _ptr;
 	}
 
+	public boolean hasZeros() {
+		return _zeros;
+	}
+	
 	/**
 	 * @param bmpIx
 	 *            index of a specific compressed bitmap (stored in subclass,
@@ -469,6 +552,7 @@ public abstract class ColGroupBitmap extends ColGroup
 		_numRows = in.readInt();
 		int numCols = in.readInt();
 		int numVals = in.readInt();
+		_zeros = in.readBoolean();
 		
 		//read col indices
 		_colIndexes = new int[ numCols ];
@@ -503,6 +587,7 @@ public abstract class ColGroupBitmap extends ColGroup
 		out.writeInt(_numRows);
 		out.writeInt(numCols);
 		out.writeInt(numVals);
+		out.writeBoolean(_zeros);
 		
 		//write col indices
 		for( int i=0; i<_colIndexes.length; i++ )
@@ -528,7 +613,7 @@ public abstract class ColGroupBitmap extends ColGroup
 
 	@Override
 	public long getExactSizeOnDisk() {
-		long ret = 12; //header
+		long ret = 13; //header
 		//col indices
 		ret += 4 * _colIndexes.length; 
 		//distinct values (groups of values)

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/compress/ColGroupOLE.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/compress/ColGroupOLE.java b/src/main/java/org/apache/sysml/runtime/compress/ColGroupOLE.java
index f648dee..b31cb74 100644
--- a/src/main/java/org/apache/sysml/runtime/compress/ColGroupOLE.java
+++ b/src/main/java/org/apache/sysml/runtime/compress/ColGroupOLE.java
@@ -25,6 +25,8 @@ import java.util.Iterator;
 import org.apache.sysml.runtime.DMLRuntimeException;
 import org.apache.sysml.runtime.compress.utils.ConverterUtils;
 import org.apache.sysml.runtime.compress.utils.LinearAlgebraUtils;
+import org.apache.sysml.runtime.functionobjects.Builtin;
+import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinCode;
 import org.apache.sysml.runtime.functionobjects.KahanFunction;
 import org.apache.sysml.runtime.functionobjects.KahanPlus;
 import org.apache.sysml.runtime.functionobjects.KahanPlusSq;
@@ -98,8 +100,8 @@ public class ColGroupOLE extends ColGroupBitmap
 	/**
 	 * Constructor for internal use.
 	 */
-	public ColGroupOLE(int[] colIndices, int numRows, double[] values, char[] bitmaps, int[] bitmapOffs) {
-		super(CompressionType.OLE_BITMAP, colIndices, numRows, values);
+	public ColGroupOLE(int[] colIndices, int numRows, boolean zeros, double[] values, char[] bitmaps, int[] bitmapOffs) {
+		super(CompressionType.OLE_BITMAP, colIndices, numRows, zeros, values);
 		_data = bitmaps;
 		_ptr = bitmapOffs;
 	}
@@ -238,7 +240,7 @@ public class ColGroupOLE extends ColGroupBitmap
 		//fast path: sparse-safe operations
 		// Note that bitmaps don't change and are shallow-copied
 		if( op.sparseSafe || val0==0 ) {
-			return new ColGroupOLE(_colIndexes, _numRows, 
+			return new ColGroupOLE(_colIndexes, _numRows, _zeros, 
 					applyScalarOp(op), _data, _ptr);
 		}
 		
@@ -247,7 +249,7 @@ public class ColGroupOLE extends ColGroupBitmap
 		boolean[] lind = computeZeroIndicatorVector();
 		int[] loff = computeOffsets(lind);
 		if( loff.length==0 ) { //empty offset list: go back to fast path
-			return new ColGroupOLE(_colIndexes, _numRows, 
+			return new ColGroupOLE(_colIndexes, _numRows, true,
 					applyScalarOp(op), _data, _ptr);
 		}
 		
@@ -258,7 +260,7 @@ public class ColGroupOLE extends ColGroupBitmap
 		int[] rbitmapOffs = Arrays.copyOf(_ptr, _ptr.length+1);
 		rbitmapOffs[rbitmapOffs.length-1] = rbitmaps.length; 
 		
-		return new ColGroupOLE(_colIndexes, _numRows, 
+		return new ColGroupOLE(_colIndexes, _numRows, loff.length<_numRows,
 				rvalues, rbitmaps, rbitmapOffs);
 	}
 
@@ -430,15 +432,33 @@ public class ColGroupOLE extends ColGroupBitmap
 	public void unaryAggregateOperations(AggregateUnaryOperator op, MatrixBlock result) 
 		throws DMLRuntimeException 
 	{
-		KahanFunction kplus = (op.aggOp.increOp.fn instanceof KahanPlus) ?
-				KahanPlus.getKahanPlusFnObject() : KahanPlusSq.getKahanPlusSqFnObject();
-		
-		if( op.indexFn instanceof ReduceAll )
-			computeSum(result, kplus);
-		else if( op.indexFn instanceof ReduceCol )
-			computeRowSums(result, kplus);
-		else if( op.indexFn instanceof ReduceRow )
-			computeColSums(result, kplus);
+		//sum and sumsq (reduceall/reducerow over tuples and counts)
+		if( op.aggOp.increOp.fn instanceof KahanPlus || op.aggOp.increOp.fn instanceof KahanPlusSq ) 
+		{
+			KahanFunction kplus = (op.aggOp.increOp.fn instanceof KahanPlus) ?
+					KahanPlus.getKahanPlusFnObject() : KahanPlusSq.getKahanPlusSqFnObject();
+			
+			if( op.indexFn instanceof ReduceAll )
+				computeSum(result, kplus);
+			else if( op.indexFn instanceof ReduceCol )
+				computeRowSums(result, kplus);
+			else if( op.indexFn instanceof ReduceRow )
+				computeColSums(result, kplus);
+		}
+		//min and max (reduceall/reducerow over tuples only)
+		else if(op.aggOp.increOp.fn instanceof Builtin 
+				&& (((Builtin)op.aggOp.increOp.fn).getBuiltinCode()==BuiltinCode.MAX 
+				|| ((Builtin)op.aggOp.increOp.fn).getBuiltinCode()==BuiltinCode.MIN)) 
+		{		
+			Builtin builtin = (Builtin) op.aggOp.increOp.fn;
+
+			if( op.indexFn instanceof ReduceAll )
+				computeMxx(result, builtin);
+			else if( op.indexFn instanceof ReduceCol )
+				computeRowMxx(result, builtin);
+			else if( op.indexFn instanceof ReduceRow )
+				computeColMxx(result, builtin);
+		}
 	}
 	
 	/**
@@ -542,6 +562,41 @@ public class ColGroupOLE extends ColGroupBitmap
 		}
 	}
 	
+	
+	/**
+	 * 
+	 * @param result
+	 */
+	private void computeRowMxx(MatrixBlock result, Builtin builtin)
+	{
+		//NOTE: zeros handled once for all column groups outside
+		
+		final int blksz = BitmapEncoder.BITMAP_BLOCK_SZ;
+		final int numVals = getNumValues();
+		
+		//iterate over all values and their bitmaps
+		for (int k = 0; k < numVals; k++) 
+		{
+			//prepare value-to-add for entire value bitmap
+			int boff = _ptr[k];
+			int blen = len(k);
+			double val = mxxValues(k, builtin);
+			
+			//iterate over bitmap blocks and add values
+			if (val != 0) {
+				int slen;
+				for( int bix=0, off=0; bix < blen; bix += slen + 1, off += blksz ) {
+					slen = _data[boff+bix];
+					for (int i = 1; i <= slen; i++) {
+						int rix = off + _data[boff+bix + i];
+						result.quickSetValue(rix, 0, 
+							builtin.execute2(result.quickGetValue(rix, 0), val));
+					}
+				}
+			}
+		}
+	}
+	
 	/**
 	 * Utility function of sparse-unsafe operations.
 	 * 

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/compress/ColGroupRLE.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/compress/ColGroupRLE.java b/src/main/java/org/apache/sysml/runtime/compress/ColGroupRLE.java
index 00b0ef9..19fede7 100644
--- a/src/main/java/org/apache/sysml/runtime/compress/ColGroupRLE.java
+++ b/src/main/java/org/apache/sysml/runtime/compress/ColGroupRLE.java
@@ -25,12 +25,14 @@ import java.util.Iterator;
 import org.apache.sysml.runtime.DMLRuntimeException;
 import org.apache.sysml.runtime.compress.utils.ConverterUtils;
 import org.apache.sysml.runtime.compress.utils.LinearAlgebraUtils;
+import org.apache.sysml.runtime.functionobjects.Builtin;
 import org.apache.sysml.runtime.functionobjects.KahanFunction;
 import org.apache.sysml.runtime.functionobjects.KahanPlus;
 import org.apache.sysml.runtime.functionobjects.KahanPlusSq;
 import org.apache.sysml.runtime.functionobjects.ReduceAll;
 import org.apache.sysml.runtime.functionobjects.ReduceCol;
 import org.apache.sysml.runtime.functionobjects.ReduceRow;
+import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinCode;
 import org.apache.sysml.runtime.instructions.cp.KahanObject;
 import org.apache.sysml.runtime.matrix.data.MatrixBlock;
 import org.apache.sysml.runtime.matrix.operators.AggregateUnaryOperator;
@@ -77,8 +79,8 @@ public class ColGroupRLE extends ColGroupBitmap
 	/**
 	 * Constructor for internal use.
 	 */
-	public ColGroupRLE(int[] colIndices, int numRows, double[] values, char[] bitmaps, int[] bitmapOffs) {
-		super(CompressionType.RLE_BITMAP, colIndices, numRows, values);
+	public ColGroupRLE(int[] colIndices, int numRows, boolean zeros, double[] values, char[] bitmaps, int[] bitmapOffs) {
+		super(CompressionType.RLE_BITMAP, colIndices, numRows, zeros, values);
 		_data = bitmaps;
 		_ptr = bitmapOffs;
 	}
@@ -409,7 +411,7 @@ public class ColGroupRLE extends ColGroupBitmap
 		//fast path: sparse-safe operations
 		// Note that bitmaps don't change and are shallow-copied
 		if( op.sparseSafe || val0==0 ) {
-			return new ColGroupRLE(_colIndexes, _numRows, 
+			return new ColGroupRLE(_colIndexes, _numRows, _zeros,
 					applyScalarOp(op), _data, _ptr);
 		}
 		
@@ -418,7 +420,7 @@ public class ColGroupRLE extends ColGroupBitmap
 		boolean[] lind = computeZeroIndicatorVector();
 		int[] loff = computeOffsets(lind);
 		if( loff.length==0 ) { //empty offset list: go back to fast path
-			return new ColGroupRLE(_colIndexes, _numRows, 
+			return new ColGroupRLE(_colIndexes, _numRows, true,
 					applyScalarOp(op), _data, _ptr);
 		}
 		
@@ -429,7 +431,7 @@ public class ColGroupRLE extends ColGroupBitmap
 		int[] rbitmapOffs = Arrays.copyOf(_ptr, _ptr.length+1);
 		rbitmapOffs[rbitmapOffs.length-1] = rbitmaps.length; 
 		
-		return new ColGroupRLE(_colIndexes, _numRows, 
+		return new ColGroupRLE(_colIndexes, _numRows, loff.length<_numRows,
 				rvalues, rbitmaps, rbitmapOffs);
 	}
 	
@@ -437,15 +439,33 @@ public class ColGroupRLE extends ColGroupBitmap
 	public void unaryAggregateOperations(AggregateUnaryOperator op, MatrixBlock result) 
 		throws DMLRuntimeException 
 	{
-		KahanFunction kplus = (op.aggOp.increOp.fn instanceof KahanPlus) ?
-				KahanPlus.getKahanPlusFnObject() : KahanPlusSq.getKahanPlusSqFnObject();
-		
-		if( op.indexFn instanceof ReduceAll )
-			computeSum(result, kplus);
-		else if( op.indexFn instanceof ReduceCol )
-			computeRowSums(result, kplus);
-		else if( op.indexFn instanceof ReduceRow )
-			computeColSums(result, kplus);
+		//sum and sumsq (reduceall/reducerow over tuples and counts)
+		if( op.aggOp.increOp.fn instanceof KahanPlus || op.aggOp.increOp.fn instanceof KahanPlusSq ) 
+		{
+			KahanFunction kplus = (op.aggOp.increOp.fn instanceof KahanPlus) ?
+					KahanPlus.getKahanPlusFnObject() : KahanPlusSq.getKahanPlusSqFnObject();
+			
+			if( op.indexFn instanceof ReduceAll )
+				computeSum(result, kplus);
+			else if( op.indexFn instanceof ReduceCol )
+				computeRowSums(result, kplus);
+			else if( op.indexFn instanceof ReduceRow )
+				computeColSums(result, kplus);
+		}
+		//min and max (reduceall/reducerow over tuples only)
+		else if(op.aggOp.increOp.fn instanceof Builtin 
+				&& (((Builtin)op.aggOp.increOp.fn).getBuiltinCode()==BuiltinCode.MAX 
+				|| ((Builtin)op.aggOp.increOp.fn).getBuiltinCode()==BuiltinCode.MIN)) 
+		{		
+			Builtin builtin = (Builtin) op.aggOp.increOp.fn;
+
+			if( op.indexFn instanceof ReduceAll )
+				computeMxx(result, builtin);
+			else if( op.indexFn instanceof ReduceCol )
+				computeRowMxx(result, builtin);
+			else if( op.indexFn instanceof ReduceRow )
+				computeColMxx(result, builtin);
+		}
 	}
 	
 	/**
@@ -544,6 +564,37 @@ public class ColGroupRLE extends ColGroupBitmap
 		}
 	}
 	
+
+	/**
+	 * 
+	 * @param result
+	 */
+	private void computeRowMxx(MatrixBlock result, Builtin builtin)
+	{
+		//NOTE: zeros handled once for all column groups outside
+		
+		final int numVals = getNumValues();
+		
+		for (int k = 0; k < numVals; k++) {
+			int boff = _ptr[k];
+			int blen = len(k);
+			double val = mxxValues(k, builtin);
+					
+			if (val != 0.0) {
+				int curRunStartOff = 0;
+				int curRunEnd = 0;
+				for (int bix = 0; bix < blen; bix+=2) {
+					curRunStartOff = curRunEnd + _data[boff+bix];
+					curRunEnd = curRunStartOff + _data[boff+bix+1];
+					for (int rix = curRunStartOff; rix < curRunEnd; rix++) {
+						result.quickSetValue(rix, 0, 
+								builtin.execute2(result.quickGetValue(rix, 0), val));
+					}
+				}
+			}
+		}
+	}
+	
 	public boolean[] computeZeroIndicatorVector()
 		throws DMLRuntimeException 
 	{	

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/compress/CompressedMatrixBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/compress/CompressedMatrixBlock.java b/src/main/java/org/apache/sysml/runtime/compress/CompressedMatrixBlock.java
index 7ff3a8a..2b23520 100644
--- a/src/main/java/org/apache/sysml/runtime/compress/CompressedMatrixBlock.java
+++ b/src/main/java/org/apache/sysml/runtime/compress/CompressedMatrixBlock.java
@@ -54,12 +54,14 @@ import org.apache.sysml.runtime.compress.utils.LinearAlgebraUtils;
 import org.apache.sysml.runtime.controlprogram.caching.CacheBlock;
 import org.apache.sysml.runtime.controlprogram.caching.MatrixObject.UpdateType;
 import org.apache.sysml.runtime.controlprogram.parfor.stat.Timing;
+import org.apache.sysml.runtime.functionobjects.Builtin;
+import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinCode;
 import org.apache.sysml.runtime.functionobjects.KahanPlus;
 import org.apache.sysml.runtime.functionobjects.KahanPlusSq;
 import org.apache.sysml.runtime.functionobjects.Multiply;
+import org.apache.sysml.runtime.functionobjects.ReduceCol;
 import org.apache.sysml.runtime.functionobjects.ReduceRow;
 import org.apache.sysml.runtime.instructions.cp.CM_COV_Object;
-import org.apache.sysml.runtime.instructions.cp.KahanObject;
 import org.apache.sysml.runtime.instructions.cp.ScalarObject;
 import org.apache.sysml.runtime.matrix.data.CTableMap;
 import org.apache.sysml.runtime.matrix.data.LibMatrixBincell;
@@ -1011,8 +1013,11 @@ public class CompressedMatrixBlock extends MatrixBlock implements Externalizable
 		}
 		
 		//check for supported operations
-		if( !(op.aggOp.increOp.fn instanceof KahanPlus || op.aggOp.increOp.fn instanceof KahanPlusSq) ){
-			throw new DMLRuntimeException("Unary aggregates other than sums not supported yet.");
+		if( !(op.aggOp.increOp.fn instanceof KahanPlus || op.aggOp.increOp.fn instanceof KahanPlusSq
+			 || (op.aggOp.increOp.fn instanceof Builtin && 
+				(((Builtin)op.aggOp.increOp.fn).getBuiltinCode()==BuiltinCode.MIN 
+				||((Builtin)op.aggOp.increOp.fn).getBuiltinCode()==BuiltinCode.MAX))) ){
+			throw new DMLRuntimeException("Unary aggregates other than sum/sumsq/min/max not supported yet.");
 		}
 		
 		//prepare output dimensions
@@ -1030,20 +1035,24 @@ public class CompressedMatrixBlock extends MatrixBlock implements Externalizable
 			}
 		}
 		
-		//prepare output
+		// initialize and allocate the result
 		if(result==null)
 			result=new MatrixBlock(tempCellIndex.row, tempCellIndex.column, false);
 		else
 			result.reset(tempCellIndex.row, tempCellIndex.column, false);
-		
 		MatrixBlock ret = (MatrixBlock) result;
+		ret.allocateDenseBlock();
+		
+		//special handling init value for rowmins/rowmax
+		if( op.indexFn instanceof ReduceCol && op.aggOp.increOp.fn instanceof Builtin ) {
+			double val = Double.MAX_VALUE * ((((Builtin)op.aggOp.increOp.fn).getBuiltinCode()==BuiltinCode.MAX)?-1:1);
+			Arrays.fill(ret.getDenseBlock(), val);
+		}
 		
 		//core unary aggregate
 		if(    op.getNumThreads() > 1 
 			&& getExactSizeOnDisk() > MIN_PAR_AGG_THRESHOLD ) 
 		{
-			// initialize and allocate the result
-			ret.allocateDenseBlock();
 			
 			//multi-threaded execution of all groups 
 			ArrayList<ColGroup>[] grpParts = createStaticTaskPartitioning(op.getNumThreads(), false);
@@ -1059,16 +1068,15 @@ public class CompressedMatrixBlock extends MatrixBlock implements Externalizable
 					tasks.add(new UnaryAggregateTask(grp, ret, op));
 				pool.invokeAll(tasks);	
 				pool.shutdown();
+				
 				//aggregate partial results
-				if( !(op.indexFn instanceof ReduceRow) ){
-					KahanObject kbuff = new KahanObject(0,0);
-					KahanPlus kplus = KahanPlus.getKahanPlusFnObject();
+				if( !(op.indexFn instanceof ReduceRow) ) {
 					for( int i=0; i<ret.getNumRows(); i++ ) {
-						kbuff.set(ret.quickGetValue(i, 0), ret.quickGetValue(i, 0));
+						double val = ret.quickGetValue(i, 0);
 						for( UnaryAggregateTask task : tasks )
-							kplus.execute2(kbuff, task.getResult().quickGetValue(i, 0));
-						ret.quickSetValue(i, 0, kbuff._sum);
-						ret.quickSetValue(i, 1, kbuff._correction);
+							val = op.aggOp.increOp.fn.execute(val,
+									task.getResult().quickGetValue(i, 0));
+						ret.quickSetValue(i, 0, val);
 					}
 				}		
 			}
@@ -1086,7 +1094,17 @@ public class CompressedMatrixBlock extends MatrixBlock implements Externalizable
 			for (ColGroup grp : _colGroups)
 				if( !(grp instanceof ColGroupUncompressed) )
 					grp.unaryAggregateOperations(op, ret);
-			
+		}
+		
+		//special handling zeros for rowmins/rowmax
+		if( op.indexFn instanceof ReduceCol && op.aggOp.increOp.fn instanceof Builtin ) {
+			int[] rnnz = new int[rlen];
+			for( ColGroup grp : _colGroups )
+				grp.countNonZerosPerRow(rnnz, 0, rlen);
+			Builtin builtin = (Builtin)op.aggOp.increOp.fn;
+			for( int i=0; i<rlen; i++ )
+				if( rnnz[i] < clen )
+					ret.quickSetValue(i, 0, builtin.execute2(ret.quickGetValue(i, 0), 0));
 		}
 		
 		//drop correction if necessary
@@ -1520,10 +1538,13 @@ public class CompressedMatrixBlock extends MatrixBlock implements Externalizable
 			if( !(_op.indexFn instanceof ReduceRow) ) { //sum/rowSums
 				_ret = new MatrixBlock(ret.getNumRows(), ret.getNumColumns(), false);
 				_ret.allocateDenseBlock();
+				if( _op.aggOp.increOp.fn instanceof Builtin )
+					System.arraycopy(ret.getDenseBlock(), 0, _ret.getDenseBlock(), 0, ret.getNumRows()*ret.getNumColumns());
 			}
 			else { //colSums
 				_ret = ret;
 			}
+			System.out.println(_ret.getNonZeros());
 		}
 		
 		@Override

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/compress/UncompressedBitmap.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/compress/UncompressedBitmap.java b/src/main/java/org/apache/sysml/runtime/compress/UncompressedBitmap.java
index 84a2c6f..04137ae 100644
--- a/src/main/java/org/apache/sysml/runtime/compress/UncompressedBitmap.java
+++ b/src/main/java/org/apache/sysml/runtime/compress/UncompressedBitmap.java
@@ -73,7 +73,7 @@ public final class UncompressedBitmap
 	public int getNumColumns() {
 		return _numCols;
 	}
-
+	
 	/**
 	 * @param ix   index of a particular distinct value
 	 * @return the tuple of column values associated with the specified index
@@ -98,4 +98,15 @@ public final class UncompressedBitmap
 	public int[] getOffsetsList(int ix) {
 		return _offsetsLists[ix];
 	}
+	
+	/**
+	 * 
+	 * @return
+	 */
+	public int getNumOffsets() {
+		int ret = 0;
+		for( int[] offlist : _offsetsLists )
+			ret += offlist.length;
+		return ret;
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/compress/utils/ConverterUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/compress/utils/ConverterUtils.java b/src/main/java/org/apache/sysml/runtime/compress/utils/ConverterUtils.java
index e87ac29..68c60ba 100644
--- a/src/main/java/org/apache/sysml/runtime/compress/utils/ConverterUtils.java
+++ b/src/main/java/org/apache/sysml/runtime/compress/utils/ConverterUtils.java
@@ -52,13 +52,13 @@ public class ConverterUtils
 		}
 		else if( group instanceof ColGroupRLE ) {
 			ColGroupRLE in = (ColGroupRLE)group;
-			ret = new ColGroupRLE(colIndices, in.getNumRows(), in.getValues(), 
-					in.getBitmaps(), in.getBitmapOffsets());
+			ret = new ColGroupRLE(colIndices, in.getNumRows(), in.hasZeros(), 
+					in.getValues(), in.getBitmaps(), in.getBitmapOffsets());
 		}
 		else if( group instanceof ColGroupOLE ) {
 			ColGroupOLE in = (ColGroupOLE) group;
-			ret = new ColGroupOLE(colIndices, in.getNumRows(), in.getValues(), 
-					in.getBitmaps(), in.getBitmapOffsets());
+			ret = new ColGroupOLE(colIndices, in.getNumRows(), in.hasZeros(),
+					in.getValues(), in.getBitmaps(), in.getBitmapOffsets());
 		}
 		
 		return ret;

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java b/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
index 20299e9..a1d305f 100644
--- a/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
+++ b/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
@@ -49,48 +49,48 @@ public class Builtin extends ValueFunction
 
 	private static final long serialVersionUID = 3836744687789840574L;
 	
-	public enum BuiltinFunctionCode { INVALID, SIN, COS, TAN, ASIN, ACOS, ATAN, LOG, LOG_NZ, MIN, MAX, ABS, SIGN, SQRT, EXP, PLOGP, PRINT, NROW, NCOL, LENGTH, ROUND, MAXINDEX, MININDEX, STOP, CEIL, FLOOR, CUMSUM, CUMPROD, CUMMIN, CUMMAX, INVERSE, SPROP, SIGMOID, SELP };
-	public BuiltinFunctionCode bFunc;
+	public enum BuiltinCode { INVALID, SIN, COS, TAN, ASIN, ACOS, ATAN, LOG, LOG_NZ, MIN, MAX, ABS, SIGN, SQRT, EXP, PLOGP, PRINT, NROW, NCOL, LENGTH, ROUND, MAXINDEX, MININDEX, STOP, CEIL, FLOOR, CUMSUM, CUMPROD, CUMMIN, CUMMAX, INVERSE, SPROP, SIGMOID, SELP };
+	public BuiltinCode bFunc;
 	
 	private static final boolean FASTMATH = true;
 	
-	static public HashMap<String, BuiltinFunctionCode> String2BuiltinFunctionCode;
+	static public HashMap<String, BuiltinCode> String2BuiltinCode;
 	static {
-		String2BuiltinFunctionCode = new HashMap<String, BuiltinFunctionCode>();
+		String2BuiltinCode = new HashMap<String, BuiltinCode>();
 		
-		String2BuiltinFunctionCode.put( "sin"    , BuiltinFunctionCode.SIN);
-		String2BuiltinFunctionCode.put( "cos"    , BuiltinFunctionCode.COS);
-		String2BuiltinFunctionCode.put( "tan"    , BuiltinFunctionCode.TAN);
-		String2BuiltinFunctionCode.put( "asin"   , BuiltinFunctionCode.ASIN);
-		String2BuiltinFunctionCode.put( "acos"   , BuiltinFunctionCode.ACOS);
-		String2BuiltinFunctionCode.put( "atan"   , BuiltinFunctionCode.ATAN);
-		String2BuiltinFunctionCode.put( "log"    , BuiltinFunctionCode.LOG);
-		String2BuiltinFunctionCode.put( "log_nz"    , BuiltinFunctionCode.LOG_NZ);
-		String2BuiltinFunctionCode.put( "min"    , BuiltinFunctionCode.MIN);
-		String2BuiltinFunctionCode.put( "max"    , BuiltinFunctionCode.MAX);
-		String2BuiltinFunctionCode.put( "maxindex"    , BuiltinFunctionCode.MAXINDEX);
-		String2BuiltinFunctionCode.put( "minindex"    , BuiltinFunctionCode.MININDEX);
-		String2BuiltinFunctionCode.put( "abs"    , BuiltinFunctionCode.ABS);
-		String2BuiltinFunctionCode.put( "sign"   , BuiltinFunctionCode.SIGN);
-		String2BuiltinFunctionCode.put( "sqrt"   , BuiltinFunctionCode.SQRT);
-		String2BuiltinFunctionCode.put( "exp"    , BuiltinFunctionCode.EXP);
-		String2BuiltinFunctionCode.put( "plogp"  , BuiltinFunctionCode.PLOGP);
-		String2BuiltinFunctionCode.put( "print"  , BuiltinFunctionCode.PRINT);
-		String2BuiltinFunctionCode.put( "nrow"   , BuiltinFunctionCode.NROW);
-		String2BuiltinFunctionCode.put( "ncol"   , BuiltinFunctionCode.NCOL);
-		String2BuiltinFunctionCode.put( "length" , BuiltinFunctionCode.LENGTH);
-		String2BuiltinFunctionCode.put( "round"  , BuiltinFunctionCode.ROUND);
-		String2BuiltinFunctionCode.put( "stop"   , BuiltinFunctionCode.STOP);
-		String2BuiltinFunctionCode.put( "ceil"   , BuiltinFunctionCode.CEIL);
-		String2BuiltinFunctionCode.put( "floor"  , BuiltinFunctionCode.FLOOR);
-		String2BuiltinFunctionCode.put( "ucumk+" , BuiltinFunctionCode.CUMSUM);
-		String2BuiltinFunctionCode.put( "ucum*"  , BuiltinFunctionCode.CUMPROD);
-		String2BuiltinFunctionCode.put( "ucummin", BuiltinFunctionCode.CUMMIN);
-		String2BuiltinFunctionCode.put( "ucummax", BuiltinFunctionCode.CUMMAX);
-		String2BuiltinFunctionCode.put( "inverse", BuiltinFunctionCode.INVERSE);
-		String2BuiltinFunctionCode.put( "sprop",   BuiltinFunctionCode.SPROP);
-		String2BuiltinFunctionCode.put( "sigmoid",   BuiltinFunctionCode.SIGMOID);
-		String2BuiltinFunctionCode.put( "sel+",   BuiltinFunctionCode.SELP);
+		String2BuiltinCode.put( "sin"    , BuiltinCode.SIN);
+		String2BuiltinCode.put( "cos"    , BuiltinCode.COS);
+		String2BuiltinCode.put( "tan"    , BuiltinCode.TAN);
+		String2BuiltinCode.put( "asin"   , BuiltinCode.ASIN);
+		String2BuiltinCode.put( "acos"   , BuiltinCode.ACOS);
+		String2BuiltinCode.put( "atan"   , BuiltinCode.ATAN);
+		String2BuiltinCode.put( "log"    , BuiltinCode.LOG);
+		String2BuiltinCode.put( "log_nz" , BuiltinCode.LOG_NZ);
+		String2BuiltinCode.put( "min"    , BuiltinCode.MIN);
+		String2BuiltinCode.put( "max"    , BuiltinCode.MAX);
+		String2BuiltinCode.put( "maxindex", BuiltinCode.MAXINDEX);
+		String2BuiltinCode.put( "minindex", BuiltinCode.MININDEX);
+		String2BuiltinCode.put( "abs"    , BuiltinCode.ABS);
+		String2BuiltinCode.put( "sign"   , BuiltinCode.SIGN);
+		String2BuiltinCode.put( "sqrt"   , BuiltinCode.SQRT);
+		String2BuiltinCode.put( "exp"    , BuiltinCode.EXP);
+		String2BuiltinCode.put( "plogp"  , BuiltinCode.PLOGP);
+		String2BuiltinCode.put( "print"  , BuiltinCode.PRINT);
+		String2BuiltinCode.put( "nrow"   , BuiltinCode.NROW);
+		String2BuiltinCode.put( "ncol"   , BuiltinCode.NCOL);
+		String2BuiltinCode.put( "length" , BuiltinCode.LENGTH);
+		String2BuiltinCode.put( "round"  , BuiltinCode.ROUND);
+		String2BuiltinCode.put( "stop"   , BuiltinCode.STOP);
+		String2BuiltinCode.put( "ceil"   , BuiltinCode.CEIL);
+		String2BuiltinCode.put( "floor"  , BuiltinCode.FLOOR);
+		String2BuiltinCode.put( "ucumk+" , BuiltinCode.CUMSUM);
+		String2BuiltinCode.put( "ucum*"  , BuiltinCode.CUMPROD);
+		String2BuiltinCode.put( "ucummin", BuiltinCode.CUMMIN);
+		String2BuiltinCode.put( "ucummax", BuiltinCode.CUMMAX);
+		String2BuiltinCode.put( "inverse", BuiltinCode.INVERSE);
+		String2BuiltinCode.put( "sprop",   BuiltinCode.SPROP);
+		String2BuiltinCode.put( "sigmoid", BuiltinCode.SIGMOID);
+		String2BuiltinCode.put( "sel+",    BuiltinCode.SELP);
 	}
 	
 	// We should create one object for every builtin function that we support
@@ -101,11 +101,11 @@ public class Builtin extends ValueFunction
 	private static Builtin inverseObj=null, cumsumObj=null, cumprodObj=null, cumminObj=null, cummaxObj=null;
 	private static Builtin stopObj = null, spropObj = null, sigmoidObj = null, selpObj = null;
 	
-	private Builtin(BuiltinFunctionCode bf) {
+	private Builtin(BuiltinCode bf) {
 		bFunc = bf;
 	}
 	
-	public BuiltinFunctionCode getBuiltinFunctionCode() {
+	public BuiltinCode getBuiltinCode() {
 		return bFunc;
 	}
 	
@@ -116,7 +116,7 @@ public class Builtin extends ValueFunction
 	 */
 	public static Builtin getBuiltinFnObject (String str) 
 	{
-		BuiltinFunctionCode code = String2BuiltinFunctionCode.get(str);
+		BuiltinCode code = String2BuiltinCode.get(str);
 		return getBuiltinFnObject( code );
 	}
 	
@@ -125,7 +125,7 @@ public class Builtin extends ValueFunction
 	 * @param code
 	 * @return
 	 */
-	public static Builtin getBuiltinFnObject(BuiltinFunctionCode code) 
+	public static Builtin getBuiltinFnObject(BuiltinCode code) 
 	{	
 		if ( code == null ) 
 			return null; 
@@ -133,140 +133,140 @@ public class Builtin extends ValueFunction
 		switch ( code ) {
 		case SIN:
 			if ( sinObj == null )
-				sinObj = new Builtin(BuiltinFunctionCode.SIN);
+				sinObj = new Builtin(BuiltinCode.SIN);
 			return sinObj;
 		
 		case COS:
 			if ( cosObj == null )
-				cosObj = new Builtin(BuiltinFunctionCode.COS);
+				cosObj = new Builtin(BuiltinCode.COS);
 			return cosObj;
 		case TAN:
 			if ( tanObj == null )
-				tanObj = new Builtin(BuiltinFunctionCode.TAN);
+				tanObj = new Builtin(BuiltinCode.TAN);
 			return tanObj;
 		case ASIN:
 			if ( asinObj == null )
-				asinObj = new Builtin(BuiltinFunctionCode.ASIN);
+				asinObj = new Builtin(BuiltinCode.ASIN);
 			return asinObj;
 		
 		case ACOS:
 			if ( acosObj == null )
-				acosObj = new Builtin(BuiltinFunctionCode.ACOS);
+				acosObj = new Builtin(BuiltinCode.ACOS);
 			return acosObj;
 		case ATAN:
 			if ( atanObj == null )
-				atanObj = new Builtin(BuiltinFunctionCode.ATAN);
+				atanObj = new Builtin(BuiltinCode.ATAN);
 			return atanObj;
 		case LOG:
 			if ( logObj == null )
-				logObj = new Builtin(BuiltinFunctionCode.LOG);
+				logObj = new Builtin(BuiltinCode.LOG);
 			return logObj;
 		case LOG_NZ:
 			if ( lognzObj == null )
-				lognzObj = new Builtin(BuiltinFunctionCode.LOG_NZ);
+				lognzObj = new Builtin(BuiltinCode.LOG_NZ);
 			return lognzObj;
 		case MAX:
 			if ( maxObj == null )
-				maxObj = new Builtin(BuiltinFunctionCode.MAX);
+				maxObj = new Builtin(BuiltinCode.MAX);
 			return maxObj;
 		case MAXINDEX:
 			if ( maxindexObj == null )
-				maxindexObj = new Builtin(BuiltinFunctionCode.MAXINDEX);
+				maxindexObj = new Builtin(BuiltinCode.MAXINDEX);
 			return maxindexObj;
 		case MIN:
 			if ( minObj == null )
-				minObj = new Builtin(BuiltinFunctionCode.MIN);
+				minObj = new Builtin(BuiltinCode.MIN);
 			return minObj;
 		case MININDEX:
 			if ( minindexObj == null )
-				minindexObj = new Builtin(BuiltinFunctionCode.MININDEX);
+				minindexObj = new Builtin(BuiltinCode.MININDEX);
 			return minindexObj;
 		case ABS:
 			if ( absObj == null )
-				absObj = new Builtin(BuiltinFunctionCode.ABS);
+				absObj = new Builtin(BuiltinCode.ABS);
 			return absObj;
 		case SIGN:
 			if ( signObj == null )
-				signObj = new Builtin(BuiltinFunctionCode.SIGN);
+				signObj = new Builtin(BuiltinCode.SIGN);
 			return signObj;
 		case SQRT:
 			if ( sqrtObj == null )
-				sqrtObj = new Builtin(BuiltinFunctionCode.SQRT);
+				sqrtObj = new Builtin(BuiltinCode.SQRT);
 			return sqrtObj;
 		case EXP:
 			if ( expObj == null )
-				expObj = new Builtin(BuiltinFunctionCode.EXP);
+				expObj = new Builtin(BuiltinCode.EXP);
 			return expObj;
 		case PLOGP:
 			if ( plogpObj == null )
-				plogpObj = new Builtin(BuiltinFunctionCode.PLOGP);
+				plogpObj = new Builtin(BuiltinCode.PLOGP);
 			return plogpObj;
 		case PRINT:
 			if ( printObj == null )
-				printObj = new Builtin(BuiltinFunctionCode.PRINT);
+				printObj = new Builtin(BuiltinCode.PRINT);
 			return printObj;
 		case NROW:
 			if ( nrowObj == null )
-				nrowObj = new Builtin(BuiltinFunctionCode.NROW);
+				nrowObj = new Builtin(BuiltinCode.NROW);
 			return nrowObj;
 		case NCOL:
 			if ( ncolObj == null )
-				ncolObj = new Builtin(BuiltinFunctionCode.NCOL);
+				ncolObj = new Builtin(BuiltinCode.NCOL);
 			return ncolObj;
 		case LENGTH:
 			if ( lengthObj == null )
-				lengthObj = new Builtin(BuiltinFunctionCode.LENGTH);
+				lengthObj = new Builtin(BuiltinCode.LENGTH);
 			return lengthObj;
 		case ROUND:
 			if ( roundObj == null )
-				roundObj = new Builtin(BuiltinFunctionCode.ROUND);
+				roundObj = new Builtin(BuiltinCode.ROUND);
 			return roundObj;
 		case CEIL:
 			if ( ceilObj == null )
-				ceilObj = new Builtin(BuiltinFunctionCode.CEIL);
+				ceilObj = new Builtin(BuiltinCode.CEIL);
 			return ceilObj;
 		case FLOOR:
 			if ( floorObj == null )
-				floorObj = new Builtin(BuiltinFunctionCode.FLOOR);
+				floorObj = new Builtin(BuiltinCode.FLOOR);
 			return floorObj;
 		case CUMSUM:
 			if ( cumsumObj == null )
-				cumsumObj = new Builtin(BuiltinFunctionCode.CUMSUM);
+				cumsumObj = new Builtin(BuiltinCode.CUMSUM);
 			return cumsumObj;	
 		case CUMPROD:
 			if ( cumprodObj == null )
-				cumprodObj = new Builtin(BuiltinFunctionCode.CUMPROD);
+				cumprodObj = new Builtin(BuiltinCode.CUMPROD);
 			return cumprodObj;	
 		case CUMMIN:
 			if ( cumminObj == null )
-				cumminObj = new Builtin(BuiltinFunctionCode.CUMMIN);
+				cumminObj = new Builtin(BuiltinCode.CUMMIN);
 			return cumminObj;	
 		case CUMMAX:
 			if ( cummaxObj == null )
-				cummaxObj = new Builtin(BuiltinFunctionCode.CUMMAX);
+				cummaxObj = new Builtin(BuiltinCode.CUMMAX);
 			return cummaxObj;	
 		case INVERSE:
 			if ( inverseObj == null )
-				inverseObj = new Builtin(BuiltinFunctionCode.INVERSE);
+				inverseObj = new Builtin(BuiltinCode.INVERSE);
 			return inverseObj;	
 		case STOP:
 			if ( stopObj == null )
-				stopObj = new Builtin(BuiltinFunctionCode.STOP);
+				stopObj = new Builtin(BuiltinCode.STOP);
 			return stopObj;
 
 		case SPROP:
 			if ( spropObj == null )
-				spropObj = new Builtin(BuiltinFunctionCode.SPROP);
+				spropObj = new Builtin(BuiltinCode.SPROP);
 			return spropObj;
 			
 		case SIGMOID:
 			if ( sigmoidObj == null )
-				sigmoidObj = new Builtin(BuiltinFunctionCode.SIGMOID);
+				sigmoidObj = new Builtin(BuiltinCode.SIGMOID);
 			return sigmoidObj;
 		
 		case SELP:
 			if ( selpObj == null )
-				selpObj = new Builtin(BuiltinFunctionCode.SELP);
+				selpObj = new Builtin(BuiltinCode.SELP);
 			return selpObj;
 			
 		default:

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/instructions/InstructionUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/instructions/InstructionUtils.java b/src/main/java/org/apache/sysml/runtime/instructions/InstructionUtils.java
index 1e40b93..5dc66af 100644
--- a/src/main/java/org/apache/sysml/runtime/instructions/InstructionUtils.java
+++ b/src/main/java/org/apache/sysml/runtime/instructions/InstructionUtils.java
@@ -42,7 +42,7 @@ import org.apache.sysml.lops.WeightedUnaryMMR;
 import org.apache.sysml.runtime.DMLRuntimeException;
 import org.apache.sysml.runtime.functionobjects.And;
 import org.apache.sysml.runtime.functionobjects.Builtin;
-import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinFunctionCode;
+import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinCode;
 import org.apache.sysml.runtime.functionobjects.CM;
 import org.apache.sysml.runtime.functionobjects.Divide;
 import org.apache.sysml.runtime.functionobjects.Equals;
@@ -279,7 +279,7 @@ public class InstructionUtils
 	 * @return
 	 */
 	public static boolean isBuiltinFunction( String opcode ) {
-		Builtin.BuiltinFunctionCode bfc = Builtin.String2BuiltinFunctionCode.get(opcode);
+		Builtin.BuiltinCode bfc = Builtin.String2BuiltinCode.get(opcode);
 		return (bfc != null);
 	}
 	
@@ -518,16 +518,16 @@ public class InstructionUtils
 	{
 		Builtin f = (Builtin)uop.fn;
 		
-		if( f.getBuiltinFunctionCode()==BuiltinFunctionCode.CUMSUM ) 
+		if( f.getBuiltinCode()==BuiltinCode.CUMSUM ) 
 			return parseCumulativeAggregateUnaryOperator("ucumack+") ;
-		else if( f.getBuiltinFunctionCode()==BuiltinFunctionCode.CUMPROD ) 
+		else if( f.getBuiltinCode()==BuiltinCode.CUMPROD ) 
 			return parseCumulativeAggregateUnaryOperator("ucumac*") ;
-		else if( f.getBuiltinFunctionCode()==BuiltinFunctionCode.CUMMIN ) 
+		else if( f.getBuiltinCode()==BuiltinCode.CUMMIN ) 
 			return parseCumulativeAggregateUnaryOperator("ucumacmin") ;
-		else if( f.getBuiltinFunctionCode()==BuiltinFunctionCode.CUMMAX ) 
+		else if( f.getBuiltinCode()==BuiltinCode.CUMMAX ) 
 			return parseCumulativeAggregateUnaryOperator("ucumacmax" ) ;
 		
-		throw new RuntimeException("Unsupported cumulative aggregate unary operator: "+f.getBuiltinFunctionCode());
+		throw new RuntimeException("Unsupported cumulative aggregate unary operator: "+f.getBuiltinCode());
 	}
 	
 	/**
@@ -539,16 +539,16 @@ public class InstructionUtils
 	{
 		Builtin f = (Builtin)uop.fn;
 		
-		if( f.getBuiltinFunctionCode()==BuiltinFunctionCode.CUMSUM ) 
+		if( f.getBuiltinCode()==BuiltinCode.CUMSUM ) 
 			return parseBasicAggregateUnaryOperator("uack+") ;
-		else if( f.getBuiltinFunctionCode()==BuiltinFunctionCode.CUMPROD ) 
+		else if( f.getBuiltinCode()==BuiltinCode.CUMPROD ) 
 			return parseBasicAggregateUnaryOperator("uac*") ;
-		else if( f.getBuiltinFunctionCode()==BuiltinFunctionCode.CUMMIN ) 
+		else if( f.getBuiltinCode()==BuiltinCode.CUMMIN ) 
 			return parseBasicAggregateUnaryOperator("uacmin") ;
-		else if( f.getBuiltinFunctionCode()==BuiltinFunctionCode.CUMMAX ) 
+		else if( f.getBuiltinCode()==BuiltinCode.CUMMAX ) 
 			return parseBasicAggregateUnaryOperator("uacmax" ) ;
 		
-		throw new RuntimeException("Unsupported cumulative aggregate unary operator: "+f.getBuiltinFunctionCode());
+		throw new RuntimeException("Unsupported cumulative aggregate unary operator: "+f.getBuiltinCode());
 	}
 	
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixAgg.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixAgg.java b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixAgg.java
index 3357dee..8709e2a 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixAgg.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixAgg.java
@@ -31,7 +31,7 @@ import org.apache.sysml.lops.PartialAggregate.CorrectionLocationType;
 import org.apache.sysml.runtime.DMLRuntimeException;
 import org.apache.sysml.runtime.controlprogram.caching.MatrixObject.UpdateType;
 import org.apache.sysml.runtime.functionobjects.Builtin;
-import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinFunctionCode;
+import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinCode;
 import org.apache.sysml.runtime.functionobjects.CM;
 import org.apache.sysml.runtime.functionobjects.IndexFunction;
 import org.apache.sysml.runtime.functionobjects.KahanFunction;
@@ -666,7 +666,7 @@ public class LibMatrixAgg
 		if( vfn instanceof Builtin &&
 		    (ifn instanceof ReduceAll || ifn instanceof ReduceCol || ifn instanceof ReduceRow) )
 		{
-			BuiltinFunctionCode bfcode = ((Builtin)vfn).bFunc;
+			BuiltinCode bfcode = ((Builtin)vfn).bFunc;
 			switch( bfcode ){
 				case MAX: return AggType.MAX;
 				case MIN: return AggType.MIN;
@@ -690,7 +690,7 @@ public class LibMatrixAgg
 
 		//cumsum/cumprod/cummin/cummax
 		if( vfn instanceof Builtin ) {
-			BuiltinFunctionCode bfunc = ((Builtin) vfn).bFunc;
+			BuiltinCode bfunc = ((Builtin) vfn).bFunc;
 			switch( bfunc )
 			{
 				case CUMSUM: 	return AggType.CUM_KAHAN_SUM;

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixOuterAgg.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixOuterAgg.java b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixOuterAgg.java
index 25d3067..ab080a1 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixOuterAgg.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixOuterAgg.java
@@ -64,7 +64,7 @@ public class LibMatrixOuterAgg
 	public static boolean isRowIndexMax(AggregateUnaryOperator uaggOp)
 	{
 		return 	(uaggOp.aggOp.increOp.fn instanceof Builtin														
-			    && (((Builtin)(uaggOp.aggOp.increOp.fn)).bFunc == Builtin.BuiltinFunctionCode.MAXINDEX));						
+			    && (((Builtin)(uaggOp.aggOp.increOp.fn)).bFunc == Builtin.BuiltinCode.MAXINDEX));						
 	}
 	
 	/**
@@ -76,7 +76,7 @@ public class LibMatrixOuterAgg
 	public static boolean isRowIndexMin(AggregateUnaryOperator uaggOp)
 	{
 		return 	(uaggOp.aggOp.increOp.fn instanceof Builtin									
-			    && (((Builtin)(uaggOp.aggOp.increOp.fn)).bFunc == Builtin.BuiltinFunctionCode.MININDEX));						
+			    && (((Builtin)(uaggOp.aggOp.increOp.fn)).bFunc == Builtin.BuiltinCode.MININDEX));						
 	}
 	
 	
@@ -192,7 +192,7 @@ public class LibMatrixOuterAgg
 			
 			MatrixBlock mbix = DataConverter.convertToMatrixBlock(dvix, true);
 			
-			UnaryOperator u_op = new UnaryOperator(Builtin.getBuiltinFnObject(Builtin.BuiltinFunctionCode.CUMMAX));
+			UnaryOperator u_op = new UnaryOperator(Builtin.getBuiltinFnObject(Builtin.BuiltinCode.CUMMAX));
 			MatrixBlock mbResult = (MatrixBlock) mbix.unaryOperations(u_op, new MatrixBlock());
 			
 			vixCumSum = DataConverter.convertToIntVector(mbResult);  
@@ -272,7 +272,7 @@ public class LibMatrixOuterAgg
 			
 			MatrixBlock mbix = DataConverter.convertToMatrixBlock(dvix, true);
 			
-			UnaryOperator u_op = new UnaryOperator(Builtin.getBuiltinFnObject(Builtin.BuiltinFunctionCode.CUMMIN));
+			UnaryOperator u_op = new UnaryOperator(Builtin.getBuiltinFnObject(Builtin.BuiltinCode.CUMMIN));
 			MatrixBlock mbResult = (MatrixBlock) mbix.unaryOperations(u_op, new MatrixBlock());
 			
 			vixCumSum = DataConverter.convertToIntVector(mbResult);  

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java b/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
index da17207..14a409b 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
@@ -3115,8 +3115,8 @@ public class MatrixBlock extends MatrixValue implements CacheBlock, Externalizab
 		}else if(aggOp.correctionLocation==CorrectionLocationType.LASTCOLUMN)
 		{
 			if(aggOp.increOp.fn instanceof Builtin 
-			   && ( ((Builtin)(aggOp.increOp.fn)).bFunc == Builtin.BuiltinFunctionCode.MAXINDEX
-			         || ((Builtin)(aggOp.increOp.fn)).bFunc == Builtin.BuiltinFunctionCode.MININDEX )
+			   && ( ((Builtin)(aggOp.increOp.fn)).bFunc == Builtin.BuiltinCode.MAXINDEX
+			         || ((Builtin)(aggOp.increOp.fn)).bFunc == Builtin.BuiltinCode.MININDEX )
 			         ){
 					// *** HACK ALERT *** HACK ALERT *** HACK ALERT ***
 					// rowIndexMax() and its siblings don't fit very well into the standard
@@ -3364,8 +3364,8 @@ public class MatrixBlock extends MatrixValue implements CacheBlock, Externalizab
 		else if(aggOp.correctionLocation==CorrectionLocationType.LASTCOLUMN)
 		{
 			if(aggOp.increOp.fn instanceof Builtin 
-			   && ( ((Builtin)(aggOp.increOp.fn)).bFunc == Builtin.BuiltinFunctionCode.MAXINDEX 
-			        || ((Builtin)(aggOp.increOp.fn)).bFunc == Builtin.BuiltinFunctionCode.MININDEX) 
+			   && ( ((Builtin)(aggOp.increOp.fn)).bFunc == Builtin.BuiltinCode.MAXINDEX 
+			        || ((Builtin)(aggOp.increOp.fn)).bFunc == Builtin.BuiltinCode.MININDEX) 
 			        ){
 				// *** HACK ALERT *** HACK ALERT *** HACK ALERT ***
 				// rowIndexMax() and its siblings don't fit very well into the standard
@@ -4540,8 +4540,8 @@ public class MatrixBlock extends MatrixValue implements CacheBlock, Externalizab
 				if(op.aggOp.correctionExists
 				   && op.aggOp.correctionLocation == CorrectionLocationType.LASTCOLUMN
 				   && op.aggOp.increOp.fn instanceof Builtin 
-				   && ( ((Builtin)(op.aggOp.increOp.fn)).bFunc == Builtin.BuiltinFunctionCode.MAXINDEX
-				        || ((Builtin)(op.aggOp.increOp.fn)).bFunc == Builtin.BuiltinFunctionCode.MININDEX) 
+				   && ( ((Builtin)(op.aggOp.increOp.fn)).bFunc == Builtin.BuiltinCode.MAXINDEX
+				        || ((Builtin)(op.aggOp.increOp.fn)).bFunc == Builtin.BuiltinCode.MININDEX) 
 				        ){
 					double currMaxValue = result.quickGetValue(i, 1);
 					long newMaxIndex = UtilFunctions.computeCellIndex(indexesIn.getColumnIndex(), blockingFactorCol, j);

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/matrix/data/OperationsOnMatrixValues.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/matrix/data/OperationsOnMatrixValues.java b/src/main/java/org/apache/sysml/runtime/matrix/data/OperationsOnMatrixValues.java
index a467cfc..f2c7ecb 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/OperationsOnMatrixValues.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/OperationsOnMatrixValues.java
@@ -183,8 +183,8 @@ public class OperationsOnMatrixValues
 					break;
 				case LASTCOLUMN:
 					if(op.increOp.fn instanceof Builtin 
-					   && ( ((Builtin)(op.increOp.fn)).bFunc == Builtin.BuiltinFunctionCode.MAXINDEX 
-					        || ((Builtin)(op.increOp.fn)).bFunc == Builtin.BuiltinFunctionCode.MININDEX) )
+					   && ( ((Builtin)(op.increOp.fn)).bFunc == Builtin.BuiltinCode.MAXINDEX 
+					        || ((Builtin)(op.increOp.fn)).bFunc == Builtin.BuiltinCode.MININDEX) )
 					{
 						outRow = rlen;
 						outCol = 1;

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/matrix/operators/BinaryOperator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/matrix/operators/BinaryOperator.java b/src/main/java/org/apache/sysml/runtime/matrix/operators/BinaryOperator.java
index 69b3e5f..9fe3ae8 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/operators/BinaryOperator.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/operators/BinaryOperator.java
@@ -43,7 +43,7 @@ import org.apache.sysml.runtime.functionobjects.Plus;
 import org.apache.sysml.runtime.functionobjects.PlusMultiply;
 import org.apache.sysml.runtime.functionobjects.Power;
 import org.apache.sysml.runtime.functionobjects.ValueFunction;
-import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinFunctionCode;
+import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinCode;
 
 public class BinaryOperator  extends Operator implements Serializable
 {
@@ -87,11 +87,11 @@ public class BinaryOperator  extends Operator implements Serializable
 		else if( fn instanceof Power )			return OpOp2.POW;
 		else if( fn instanceof MinusNz )		return OpOp2.MINUS_NZ;
 		else if( fn instanceof Builtin ) {
-			BuiltinFunctionCode bfc = ((Builtin) fn).getBuiltinFunctionCode();
-			if( bfc == BuiltinFunctionCode.MIN ) 		return OpOp2.MIN;
-			else if( bfc == BuiltinFunctionCode.MAX ) 	return OpOp2.MAX;
-			else if( bfc == BuiltinFunctionCode.LOG ) 	return OpOp2.LOG;
-			else if( bfc == BuiltinFunctionCode.LOG_NZ ) return OpOp2.LOG_NZ;
+			BuiltinCode bfc = ((Builtin) fn).getBuiltinCode();
+			if( bfc == BuiltinCode.MIN ) 		return OpOp2.MIN;
+			else if( bfc == BuiltinCode.MAX ) 	return OpOp2.MAX;
+			else if( bfc == BuiltinCode.LOG ) 	return OpOp2.LOG;
+			else if( bfc == BuiltinCode.LOG_NZ ) return OpOp2.LOG_NZ;
 		}
 		
 		//non-supported ops (not required for sparsity estimates):

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/matrix/operators/ScalarOperator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/matrix/operators/ScalarOperator.java b/src/main/java/org/apache/sysml/runtime/matrix/operators/ScalarOperator.java
index 75891d3..19aaa29 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/operators/ScalarOperator.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/operators/ScalarOperator.java
@@ -23,7 +23,7 @@ package org.apache.sysml.runtime.matrix.operators;
 import org.apache.sysml.runtime.DMLRuntimeException;
 import org.apache.sysml.runtime.functionobjects.And;
 import org.apache.sysml.runtime.functionobjects.Builtin;
-import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinFunctionCode;
+import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinCode;
 import org.apache.sysml.runtime.functionobjects.Equals;
 import org.apache.sysml.runtime.functionobjects.GreaterThan;
 import org.apache.sysml.runtime.functionobjects.LessThan;
@@ -55,7 +55,7 @@ public class ScalarOperator  extends Operator
 		sparseSafe = (fn instanceof Multiply || fn instanceof Multiply2 
 				|| fn instanceof Power || fn instanceof Power2 
 				|| fn instanceof And || fn instanceof MinusNz
-				|| (fn instanceof Builtin && ((Builtin)fn).getBuiltinFunctionCode()==BuiltinFunctionCode.LOG_NZ));
+				|| (fn instanceof Builtin && ((Builtin)fn).getBuiltinCode()==BuiltinCode.LOG_NZ));
 	}
 	
 	public double getConstant() {
@@ -71,15 +71,15 @@ public class ScalarOperator  extends Operator
 		sparseSafe = ( fn instanceof Multiply || fn instanceof Multiply2 
 			|| fn instanceof Power || fn instanceof Power2 
 			|| fn instanceof And || fn instanceof MinusNz
-			|| fn instanceof Builtin && ((Builtin)fn).getBuiltinFunctionCode()==BuiltinFunctionCode.LOG_NZ
+			|| fn instanceof Builtin && ((Builtin)fn).getBuiltinCode()==BuiltinCode.LOG_NZ
 			|| (fn instanceof GreaterThan && _constant==0) 
 			|| (fn instanceof LessThan && _constant==0)
 			|| (fn instanceof NotEquals && _constant==0)
 			|| (fn instanceof Equals && _constant!=0)
 			|| (fn instanceof Minus && _constant==0)
 			|| (fn instanceof Minus && _constant==0)
-			|| (fn instanceof Builtin && ((Builtin)fn).getBuiltinFunctionCode()==BuiltinFunctionCode.MAX && _constant<=0)
-			|| (fn instanceof Builtin && ((Builtin)fn).getBuiltinFunctionCode()==BuiltinFunctionCode.MIN && _constant>=0));
+			|| (fn instanceof Builtin && ((Builtin)fn).getBuiltinCode()==BuiltinCode.MAX && _constant<=0)
+			|| (fn instanceof Builtin && ((Builtin)fn).getBuiltinCode()==BuiltinCode.MIN && _constant>=0));
 	}
 	
 	public double executeScalar(double in) throws DMLRuntimeException {

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/main/java/org/apache/sysml/runtime/matrix/operators/UnaryOperator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/matrix/operators/UnaryOperator.java b/src/main/java/org/apache/sysml/runtime/matrix/operators/UnaryOperator.java
index a736c8b..9b4f34f 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/operators/UnaryOperator.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/operators/UnaryOperator.java
@@ -42,11 +42,11 @@ public class UnaryOperator extends Operator
 		
 		if( fn instanceof Builtin ) {
 			Builtin f=(Builtin)fn;
-			sparseSafe = (f.bFunc==Builtin.BuiltinFunctionCode.SIN || f.bFunc==Builtin.BuiltinFunctionCode.TAN 
-					|| f.bFunc==Builtin.BuiltinFunctionCode.ROUND || f.bFunc==Builtin.BuiltinFunctionCode.ABS
-					|| f.bFunc==Builtin.BuiltinFunctionCode.SQRT || f.bFunc==Builtin.BuiltinFunctionCode.SPROP
-					|| f.bFunc==Builtin.BuiltinFunctionCode.SELP || f.bFunc==Builtin.BuiltinFunctionCode.LOG_NZ
-					|| f.bFunc==Builtin.BuiltinFunctionCode.SIGN );
+			sparseSafe = (f.bFunc==Builtin.BuiltinCode.SIN || f.bFunc==Builtin.BuiltinCode.TAN 
+					|| f.bFunc==Builtin.BuiltinCode.ROUND || f.bFunc==Builtin.BuiltinCode.ABS
+					|| f.bFunc==Builtin.BuiltinCode.SQRT || f.bFunc==Builtin.BuiltinCode.SPROP
+					|| f.bFunc==Builtin.BuiltinCode.SELP || f.bFunc==Builtin.BuiltinCode.LOG_NZ
+					|| f.bFunc==Builtin.BuiltinCode.SIGN );
 		}
 	}
 	

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/bf466923/src/test/java/org/apache/sysml/test/integration/functions/compress/BasicUnaryAggregateTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/sysml/test/integration/functions/compress/BasicUnaryAggregateTest.java b/src/test/java/org/apache/sysml/test/integration/functions/compress/BasicUnaryAggregateTest.java
index 767ca03..aca54aa 100644
--- a/src/test/java/org/apache/sysml/test/integration/functions/compress/BasicUnaryAggregateTest.java
+++ b/src/test/java/org/apache/sysml/test/integration/functions/compress/BasicUnaryAggregateTest.java
@@ -57,7 +57,13 @@ public class BasicUnaryAggregateTest extends AutomatedTestBase
 		SUM,
 		ROWSUMSSQ,
 		COLSUMSSQ,
-		SUMSQ
+		SUMSQ,
+		ROWMAXS,
+		COLMAXS,
+		MAX,
+		ROWMINS,
+		COLMINS,
+		MIN,
 	}
 	
 	@Override
@@ -485,6 +491,426 @@ public class BasicUnaryAggregateTest extends AutomatedTestBase
 		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.SUMSQ, false);
 	}
 	
+	@Test
+	public void testRowMaxsDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.ROWMAXS, true);
+	}
+	
+	@Test
+	public void testRowMaxsDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testRowMaxsSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.ROWMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.COLMAXS, true);
+	}
+	
+	@Test
+	public void testColMaxsDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.COLMAXS, false);
+	}
+	
+	@Test
+	public void testColMaxsSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.COLMAXS, false);
+	}
+
+	@Test
+	public void testMaxDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.MAX, true);
+	}
+	
+	@Test
+	public void testMaxDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testMaxSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.MAX, false);
+	}
+	
+	@Test
+	public void testRowMinsDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.ROWMINS, true);
+	}
+	
+	@Test
+	public void testRowMinsDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testRowMinsSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.ROWMINS, false);
+	}
+	
+	@Test
+	public void testColMinsDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.COLMINS, true);
+	}
+	
+	@Test
+	public void testColMinsDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.COLMINS, false);
+	}
+	
+	@Test
+	public void testColMinsSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.COLMINS, false);
+	}
+
+	@Test
+	public void testMinDenseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinSparseRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinEmptyCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinDenseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinSparseRoundRandDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinDenseConstantDataCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinSparseConstDataCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.MIN, true);
+	}
+	
+	@Test
+	public void testMinDenseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinSparseRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinEmptyNoCompression() {
+		runUnaryAggregateTest(SparsityType.EMPTY, ValueType.RAND, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinDenseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.RAND_ROUND, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinSparseRoundRandDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.RAND_ROUND, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinDenseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.DENSE, ValueType.CONST, AggType.MIN, false);
+	}
+	
+	@Test
+	public void testMinSparseConstDataNoCompression() {
+		runUnaryAggregateTest(SparsityType.SPARSE, ValueType.CONST, AggType.MIN, false);
+	}
+	
 	/**
 	 * 
 	 * @param mb
@@ -518,6 +944,12 @@ public class BasicUnaryAggregateTest extends AutomatedTestBase
 				case SUMSQ: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uasqk+"); break;
 				case ROWSUMSSQ: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uarsqk+"); break;
 				case COLSUMSSQ: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uacsqk+"); break;
+				case MAX: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uamax"); break;
+				case ROWMAXS: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uarmax"); break;
+				case COLMAXS: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uacmax"); break;
+				case MIN: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uamin"); break;
+				case ROWMINS: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uarmin"); break;
+				case COLMINS: auop = InstructionUtils.parseBasicAggregateUnaryOperator("uacmin"); break;
 			}
 			
 			//compress given matrix block
@@ -534,8 +966,10 @@ public class BasicUnaryAggregateTest extends AutomatedTestBase
 			//compare result with input
 			double[][] d1 = DataConverter.convertToDoubleMatrix(ret1);
 			double[][] d2 = DataConverter.convertToDoubleMatrix(ret2);
-			int dim1 = (aggtype == AggType.ROWSUMS)?rows:1;
-			int dim2 = (aggtype == AggType.COLSUMS)?cols1:1;
+			int dim1 = (aggtype == AggType.ROWSUMS || aggtype == AggType.ROWSUMSSQ 
+					|| aggtype == AggType.ROWMINS || aggtype == AggType.ROWMINS)?rows:1;
+			int dim2 = (aggtype == AggType.COLSUMS || aggtype == AggType.COLSUMSSQ 
+					|| aggtype == AggType.COLMAXS || aggtype == AggType.COLMINS)?cols1:1;
 			TestUtils.compareMatrices(d1, d2, dim1, dim2, 0.00000000001);
 		}
 		catch(Exception ex) {