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)