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 2017/05/28 21:15:36 UTC

incubator-systemml git commit: [SYSTEMML-1289] Codegen multi-aggregates over compressed matrices

Repository: incubator-systemml
Updated Branches:
  refs/heads/master 5174fbc00 -> b4dd2c1bf


[SYSTEMML-1289] Codegen multi-aggregates over compressed matrices

This patch extends the codegen support for compressed matrices to
multi-aggregate operations including tests. 

Furthermore, this also includes a fix of javadocs regarding recently
removed classes.


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

Branch: refs/heads/master
Commit: b4dd2c1bf66a642cc622c57bb690e4f599de723c
Parents: 5174fbc
Author: Matthias Boehm <mb...@gmail.com>
Authored: Sun May 28 13:55:11 2017 -0700
Committer: Matthias Boehm <mb...@gmail.com>
Committed: Sun May 28 13:55:11 2017 -0700

----------------------------------------------------------------------
 .../runtime/codegen/SpoofMultiAggregate.java    |  20 +-
 .../sysml/runtime/compress/BitmapEncoder.java   |   3 -
 .../codegen/CompressedMultiAggregateTest.java   | 331 +++++++++++++++++++
 .../codegen/CompressedMultiAggregateMain.R      |  31 ++
 .../codegen/CompressedMultiAggregateMain.dml    |  27 ++
 .../codegen/CompressedMultiAggregateSide.R      |  33 ++
 .../codegen/CompressedMultiAggregateSide.dml    |  29 ++
 7 files changed, 469 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/b4dd2c1b/src/main/java/org/apache/sysml/runtime/codegen/SpoofMultiAggregate.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/codegen/SpoofMultiAggregate.java b/src/main/java/org/apache/sysml/runtime/codegen/SpoofMultiAggregate.java
index faecd8c..e7e3b54 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/SpoofMultiAggregate.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/SpoofMultiAggregate.java
@@ -22,6 +22,7 @@ package org.apache.sysml.runtime.codegen;
 import java.io.Serializable;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
@@ -30,6 +31,7 @@ import java.util.concurrent.Future;
 
 import org.apache.sysml.runtime.DMLRuntimeException;
 import org.apache.sysml.runtime.codegen.SpoofCellwise.AggOp;
+import org.apache.sysml.runtime.compress.CompressedMatrixBlock;
 import org.apache.sysml.runtime.functionobjects.Builtin;
 import org.apache.sysml.runtime.functionobjects.Builtin.BuiltinCode;
 import org.apache.sysml.runtime.functionobjects.KahanFunction;
@@ -38,6 +40,7 @@ import org.apache.sysml.runtime.functionobjects.KahanPlusSq;
 import org.apache.sysml.runtime.functionobjects.ValueFunction;
 import org.apache.sysml.runtime.instructions.cp.KahanObject;
 import org.apache.sysml.runtime.instructions.cp.ScalarObject;
+import org.apache.sysml.runtime.matrix.data.IJV;
 import org.apache.sysml.runtime.matrix.data.MatrixBlock;
 import org.apache.sysml.runtime.matrix.data.SparseBlock;
 import org.apache.sysml.runtime.util.UtilFunctions;
@@ -95,7 +98,9 @@ public abstract class SpoofMultiAggregate extends SpoofOperator implements Seria
 		
 		if( k <= 1 ) //SINGLE-THREADED
 		{
-			if( !inputs.get(0).isInSparseFormat() )
+			if( inputs.get(0) instanceof CompressedMatrixBlock )
+				executeCompressed((CompressedMatrixBlock)inputs.get(0), b, scalars, c, m, n, 0, m);
+			else if( !inputs.get(0).isInSparseFormat() )
 				executeDense(inputs.get(0).getDenseBlock(), b, scalars, c, m, n, 0, m);
 			else	
 				executeSparse(inputs.get(0).getSparseBlock(), b, scalars, c, m, n, 0, m);
@@ -151,6 +156,15 @@ public abstract class SpoofMultiAggregate extends SpoofOperator implements Seria
 			}
 	}
 
+	private void executeCompressed(CompressedMatrixBlock a, SideInput[] b, double[] scalars, double[] c, int m, int n, int rl, int ru) throws DMLRuntimeException 
+	{
+		//core compressed aggregation operation
+		Iterator<IJV> iter = a.getIterator(rl, ru, true);
+		while( iter.hasNext() ) {
+			IJV cell = iter.next();
+			genexec(cell.getV(), b, scalars, c, m, n, cell.getI(), cell.getJ());
+		}
+	}
 	
 	protected abstract void genexec( double a, SideInput[] b, double[] scalars, double[] c, int m, int n, int rowIndex, int colIndex);
 	
@@ -251,7 +265,9 @@ public abstract class SpoofMultiAggregate extends SpoofOperator implements Seria
 		public double[] call() throws DMLRuntimeException {
 			double[] c = new double[_aggOps.length];
 			setInitialOutputValues(c);
-			if( !_a.isInSparseFormat() )
+			if( _a instanceof CompressedMatrixBlock )
+				executeCompressed((CompressedMatrixBlock)_a, _b, _scalars, c, _rlen, _clen, _rl, _ru);
+			else if( !_a.isInSparseFormat() )
 				executeDense(_a.getDenseBlock(), _b, _scalars, c, _rlen, _clen, _rl, _ru);
 			else	
 				executeSparse(_a.getSparseBlock(), _b, _scalars, c, _rlen, _clen, _rl, _ru);

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/b4dd2c1b/src/main/java/org/apache/sysml/runtime/compress/BitmapEncoder.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/compress/BitmapEncoder.java b/src/main/java/org/apache/sysml/runtime/compress/BitmapEncoder.java
index 2def9f6..a1f7454 100644
--- a/src/main/java/org/apache/sysml/runtime/compress/BitmapEncoder.java
+++ b/src/main/java/org/apache/sysml/runtime/compress/BitmapEncoder.java
@@ -90,9 +90,6 @@ public class BitmapEncoder
 
 	/**
 	 * Encodes the bitmap as a series of run lengths and offsets.
-	 * <p>
-	 * <b>NOTE: This method must be kept in sync with {@link BitmapDecoderRLE}
-	 * !</b>
 	 * 
 	 * @param offsets  uncompressed offset list
 	 * @param len  logical length of the given offset list

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/b4dd2c1b/src/test/java/org/apache/sysml/test/integration/functions/codegen/CompressedMultiAggregateTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/sysml/test/integration/functions/codegen/CompressedMultiAggregateTest.java b/src/test/java/org/apache/sysml/test/integration/functions/codegen/CompressedMultiAggregateTest.java
new file mode 100644
index 0000000..77b1294
--- /dev/null
+++ b/src/test/java/org/apache/sysml/test/integration/functions/codegen/CompressedMultiAggregateTest.java
@@ -0,0 +1,331 @@
+/*
+ * 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.
+ */
+
+package org.apache.sysml.test.integration.functions.codegen;
+
+import java.io.File;
+import java.util.HashMap;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.apache.sysml.api.DMLScript;
+import org.apache.sysml.api.DMLScript.RUNTIME_PLATFORM;
+import org.apache.sysml.hops.OptimizerUtils;
+import org.apache.sysml.lops.LopProperties.ExecType;
+import org.apache.sysml.runtime.compress.CompressedMatrixBlock;
+import org.apache.sysml.runtime.matrix.data.MatrixValue.CellIndex;
+import org.apache.sysml.test.integration.AutomatedTestBase;
+import org.apache.sysml.test.integration.TestConfiguration;
+import org.apache.sysml.test.utils.TestUtils;
+
+public class CompressedMultiAggregateTest extends AutomatedTestBase 
+{	
+	private static final String TEST_NAME1 = "CompressedMultiAggregateMain";
+	private static final String TEST_NAME2 = "CompressedMultiAggregateSide";
+	private static final String TEST_DIR = "functions/codegen/";
+	private static final String TEST_CLASS_DIR = TEST_DIR + CompressedMultiAggregateTest.class.getSimpleName() + "/";
+	private final static String TEST_CONF = "SystemML-config-codegen-compress.xml";
+	private final static File   TEST_CONF_FILE = new File(SCRIPT_DIR + TEST_DIR, TEST_CONF);
+	
+	private static final int rows = 2023;
+	private static final int cols = 20;
+	private static final double sparsity1 = 0.9;
+	private static final double sparsity2 = 0.1;
+	private static final double sparsity3 = 0.0;
+	private static final double eps = Math.pow(10, -6);
+	
+	public enum SparsityType {
+		DENSE,
+		SPARSE,
+		EMPTY,
+	}
+	
+	public enum ValueType {
+		RAND, //UC
+		CONST, //RLE
+		RAND_ROUND_OLE, //OLE
+		RAND_ROUND_DDC, //RLE
+	}
+	
+	@Override
+	public void setUp() {
+		TestUtils.clearAssertionInformation();
+		addTestConfiguration( TEST_NAME1, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME1, new String[] { "R" }) );
+		addTestConfiguration( TEST_NAME2, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME2, new String[] { "R" }) );
+	}
+		
+	@Test
+	public void testCompressedMultiAggregateMainDenseConstCP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.DENSE, ValueType.CONST, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainDenseRandCP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.DENSE, ValueType.RAND, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainDenseRand2CP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.DENSE, ValueType.RAND_ROUND_DDC, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainDenseRand3CP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.DENSE, ValueType.RAND_ROUND_OLE, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainSparseConstCP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.SPARSE, ValueType.CONST, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainSparseRandCP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.SPARSE, ValueType.RAND, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainSparseRand2CP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.SPARSE, ValueType.RAND_ROUND_DDC, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainSparseRand3CP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.SPARSE, ValueType.RAND_ROUND_OLE, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainEmptyConstCP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.EMPTY, ValueType.CONST, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainEmptyRandCP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.EMPTY, ValueType.RAND, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainEmptyRand2CP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.EMPTY, ValueType.RAND_ROUND_DDC, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainEmptyRand3CP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.EMPTY, ValueType.RAND_ROUND_OLE, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideDenseConstCP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.DENSE, ValueType.CONST, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideDenseRandCP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.DENSE, ValueType.RAND, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideDenseRand2CP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.DENSE, ValueType.RAND_ROUND_DDC, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideDenseRand3CP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.DENSE, ValueType.RAND_ROUND_OLE, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideSparseConstCP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.SPARSE, ValueType.CONST, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideSparseRandCP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.SPARSE, ValueType.RAND, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideSparseRand2CP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.SPARSE, ValueType.RAND_ROUND_DDC, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideSparseRand3CP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.SPARSE, ValueType.RAND_ROUND_OLE, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideEmptyConstCP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.EMPTY, ValueType.CONST, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideEmptyRandCP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.EMPTY, ValueType.RAND, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideEmptyRand2CP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.EMPTY, ValueType.RAND_ROUND_DDC, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateSideEmptyRand3CP() {
+		testCompressedMultiAggregate( TEST_NAME2, SparsityType.EMPTY, ValueType.RAND_ROUND_OLE, ExecType.CP );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainDenseConstSP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.DENSE, ValueType.CONST, ExecType.SPARK );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainDenseRandSP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.DENSE, ValueType.RAND, ExecType.SPARK );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainDenseRand2SP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.DENSE, ValueType.RAND_ROUND_DDC, ExecType.SPARK );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainDenseRand3SP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.DENSE, ValueType.RAND_ROUND_OLE, ExecType.SPARK );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainSparseConstSP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.SPARSE, ValueType.CONST, ExecType.SPARK );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainSparseRandSP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.SPARSE, ValueType.RAND, ExecType.SPARK );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainSparseRand2SP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.SPARSE, ValueType.RAND_ROUND_DDC, ExecType.SPARK );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainSparseRand3SP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.SPARSE, ValueType.RAND_ROUND_OLE, ExecType.SPARK );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainEmptyConstSP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.EMPTY, ValueType.CONST, ExecType.SPARK );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainEmptyRandSP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.EMPTY, ValueType.RAND, ExecType.SPARK );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainEmptyRand2SP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.EMPTY, ValueType.RAND_ROUND_DDC, ExecType.SPARK );
+	}
+	
+	@Test
+	public void testCompressedMultiAggregateMainEmptyRand3SP() {
+		testCompressedMultiAggregate( TEST_NAME1, SparsityType.EMPTY, ValueType.RAND_ROUND_OLE, ExecType.SPARK );
+	}
+	
+	//TODO compressed side inputs in spark
+	
+	
+	private void testCompressedMultiAggregate(String testname, SparsityType stype, ValueType vtype, ExecType et)
+	{	
+		boolean oldRewrites = OptimizerUtils.ALLOW_ALGEBRAIC_SIMPLIFICATION;
+		RUNTIME_PLATFORM platformOld = rtplatform;
+		switch( et ){
+			case MR: rtplatform = RUNTIME_PLATFORM.HADOOP; break;
+			case SPARK: rtplatform = RUNTIME_PLATFORM.SPARK; break;
+			default: rtplatform = RUNTIME_PLATFORM.HYBRID_SPARK; break;
+		}
+	
+		boolean sparkConfigOld = DMLScript.USE_LOCAL_SPARK_CONFIG;
+		if( rtplatform == RUNTIME_PLATFORM.SPARK || rtplatform == RUNTIME_PLATFORM.HYBRID_SPARK )
+			DMLScript.USE_LOCAL_SPARK_CONFIG = true;
+		
+		try
+		{
+			OptimizerUtils.ALLOW_ALGEBRAIC_SIMPLIFICATION = true;
+			TestConfiguration config = getTestConfiguration(testname);
+			loadTestConfiguration(config);
+			
+			String HOME = SCRIPT_DIR + TEST_DIR;
+			fullDMLScriptName = HOME + testname + ".dml";
+			programArgs = new String[]{"-explain", "-stats", 
+					"-args", input("X"), output("R") };
+			
+			fullRScriptName = HOME + testname + ".R";
+			rCmd = getRCmd(inputDir(), expectedDir());			
+
+			//generate input data
+			double sparsity = -1;
+			switch( stype ){
+				case DENSE: sparsity = sparsity1; break;
+				case SPARSE: sparsity = sparsity2; break;
+				case EMPTY: sparsity = sparsity3; break;
+			}
+			
+			//generate input data
+			double min = (vtype==ValueType.CONST)? 10 : -10;
+			double[][] X = TestUtils.generateTestMatrix(rows, cols, min, 10, sparsity, 7);
+			if( vtype==ValueType.RAND_ROUND_OLE || vtype==ValueType.RAND_ROUND_DDC ) {
+				CompressedMatrixBlock.ALLOW_DDC_ENCODING = (vtype==ValueType.RAND_ROUND_DDC);
+				X = TestUtils.round(X);
+			}
+			writeInputMatrixWithMTD("X", X, true);
+			
+			//run tests
+			runTest(true, false, null, -1); 
+			runRScript(true); 
+			
+			//compare matrices 
+			HashMap<CellIndex, Double> dmlfile = readDMLMatrixFromHDFS("R");
+			HashMap<CellIndex, Double> rfile  = readRMatrixFromFS("R");	
+			TestUtils.compareMatrices(dmlfile, rfile, eps, "Stat-DML", "Stat-R");
+			Assert.assertTrue(heavyHittersContainsSubString("spoofMA") 
+				|| heavyHittersContainsSubString("sp_spoofMA"));
+		}
+		finally {
+			rtplatform = platformOld;
+			DMLScript.USE_LOCAL_SPARK_CONFIG = sparkConfigOld;
+			OptimizerUtils.ALLOW_ALGEBRAIC_SIMPLIFICATION = oldRewrites;
+			OptimizerUtils.ALLOW_AUTO_VECTORIZATION = true;
+			OptimizerUtils.ALLOW_OPERATOR_FUSION = true;
+		}
+	}	
+
+	/**
+	 * Override default configuration with custom test configuration to ensure
+	 * scratch space and local temporary directory locations are also updated.
+	 */
+	@Override
+	protected File getConfigTemplateFile() {
+		// Instrumentation in this test's output log to show custom configuration file used for template.
+		System.out.println("This test case overrides default configuration with " + TEST_CONF_FILE.getPath());
+		return TEST_CONF_FILE;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/b4dd2c1b/src/test/scripts/functions/codegen/CompressedMultiAggregateMain.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/CompressedMultiAggregateMain.R b/src/test/scripts/functions/codegen/CompressedMultiAggregateMain.R
new file mode 100644
index 0000000..0b49722
--- /dev/null
+++ b/src/test/scripts/functions/codegen/CompressedMultiAggregateMain.R
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------
+#
+# 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)
+library("Matrix")
+library("matrixStats")
+
+X = readMM(paste(args[1], "X.mtx", sep=""));
+
+# two fused with and without aggregation
+R = as.matrix(sum(X/3 * X/4 * X/5) - sum(X * X/2))
+
+writeMM(as(R,"CsparseMatrix"), paste(args[2], "R", sep=""));

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/b4dd2c1b/src/test/scripts/functions/codegen/CompressedMultiAggregateMain.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/CompressedMultiAggregateMain.dml b/src/test/scripts/functions/codegen/CompressedMultiAggregateMain.dml
new file mode 100644
index 0000000..9e1a75f
--- /dev/null
+++ b/src/test/scripts/functions/codegen/CompressedMultiAggregateMain.dml
@@ -0,0 +1,27 @@
+#-------------------------------------------------------------
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#-------------------------------------------------------------
+
+X = read($1)
+
+# two fused with and without aggregation
+R = as.matrix(sum(X/3 * X/4 * X/5) - sum(X * X/2))
+
+write(R, $2)

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/b4dd2c1b/src/test/scripts/functions/codegen/CompressedMultiAggregateSide.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/CompressedMultiAggregateSide.R b/src/test/scripts/functions/codegen/CompressedMultiAggregateSide.R
new file mode 100644
index 0000000..e48e1ce
--- /dev/null
+++ b/src/test/scripts/functions/codegen/CompressedMultiAggregateSide.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)
+library("Matrix")
+library("matrixStats")
+
+X = readMM(paste(args[1], "X.mtx", sep=""));
+M = matrix(0, nrow(X), ncol(X));
+M[7,7] = 7;
+
+# two fused with and without aggregation
+R = as.matrix(sum(M/3 * M/4 * X) - sum(M * M/2 * X))
+
+writeMM(as(R,"CsparseMatrix"), paste(args[2], "R", sep=""));

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/b4dd2c1b/src/test/scripts/functions/codegen/CompressedMultiAggregateSide.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/CompressedMultiAggregateSide.dml b/src/test/scripts/functions/codegen/CompressedMultiAggregateSide.dml
new file mode 100644
index 0000000..671ff40
--- /dev/null
+++ b/src/test/scripts/functions/codegen/CompressedMultiAggregateSide.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 = read($1)
+M = matrix(0, nrow(X), ncol(X));
+M[7,7] = 7;
+
+# two fused with and without aggregation
+R = as.matrix(sum(M/3 * M/4 * X) - sum(M * M/2 * X))
+
+write(R, $2)