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/01/29 18:15:28 UTC
[2/2] incubator-systemml git commit: New static simplification
rewrite 'pushdown unary-aggregate transpose'
New static simplification rewrite 'pushdown unary-aggregate transpose'
This new static (size-independent) rewrite allows to push row/column
aggregates below a transpose operation. Examples are colSums(t(X)) ->
t(rowSums(X)) and rowSums(t(X)) -> t(colSums(X)), where we support the
following aggregate functions: sum, sum_sq, min, max, mean, var. The
benefits are (1) likely reduced input size to transpose, and (2)
potentially noops for vector transpose. This patch also includes the
relevant tests for a subset of aggregate functions.
Project: http://git-wip-us.apache.org/repos/asf/incubator-systemml/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-systemml/commit/5956a612
Tree: http://git-wip-us.apache.org/repos/asf/incubator-systemml/tree/5956a612
Diff: http://git-wip-us.apache.org/repos/asf/incubator-systemml/diff/5956a612
Branch: refs/heads/master
Commit: 5956a61255ca4f0ffc1f3b1943dbb2f3fff969bc
Parents: 0a2b587
Author: Matthias Boehm <mb...@us.ibm.com>
Authored: Thu Jan 28 21:03:25 2016 -0800
Committer: Matthias Boehm <mb...@us.ibm.com>
Committed: Fri Jan 29 09:13:39 2016 -0800
----------------------------------------------------------------------
.../RewriteAlgebraicSimplificationStatic.java | 55 ++++++-
.../functions/misc/RewritePushdownUaggTest.java | 157 +++++++++++++++++++
.../functions/misc/RewritePushdownColmins.R | 31 ++++
.../functions/misc/RewritePushdownColmins.dml | 26 +++
.../functions/misc/RewritePushdownColsums.R | 30 ++++
.../functions/misc/RewritePushdownColsums.dml | 26 +++
.../functions/misc/RewritePushdownRowmins.R | 31 ++++
.../functions/misc/RewritePushdownRowmins.dml | 26 +++
.../functions/misc/RewritePushdownRowsums.R | 30 ++++
.../functions/misc/RewritePushdownRowsums.dml | 26 +++
10 files changed, 435 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/5956a612/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationStatic.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationStatic.java b/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationStatic.java
index 3aea9f0..2368153 100644
--- a/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationStatic.java
+++ b/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationStatic.java
@@ -59,13 +59,16 @@ import org.apache.sysml.parser.Expression.ValueType;
*
*/
public class RewriteAlgebraicSimplificationStatic extends HopRewriteRule
-{
-
+{
private static final Log LOG = LogFactory.getLog(RewriteAlgebraicSimplificationStatic.class.getName());
+ //valid aggregation operation types for rowOp to colOp conversions and vice versa
+ private static AggOp[] LOOKUP_VALID_ROW_COL_AGGREGATE = new AggOp[]{AggOp.SUM, AggOp.SUM_SQ, AggOp.MIN, AggOp.MAX, AggOp.MEAN, AggOp.VAR};
+
+ //valid binary operations for distributive and associate reorderings
private static OpOp2[] LOOKUP_VALID_DISTRIBUTIVE_BINARY = new OpOp2[]{OpOp2.PLUS, OpOp2.MINUS};
private static OpOp2[] LOOKUP_VALID_ASSOCIATIVE_BINARY = new OpOp2[]{OpOp2.PLUS, OpOp2.MULT};
-
+
@Override
public ArrayList<Hop> rewriteHopDAGs(ArrayList<Hop> roots, ProgramRewriteStatus state)
throws HopsException
@@ -139,6 +142,7 @@ public class RewriteAlgebraicSimplificationStatic extends HopRewriteRule
hi = simplifyDistributiveBinaryOperation(hop, hi, i);//e.g., (X-Y*X) -> (1-Y)*X
hi = simplifyBushyBinaryOperation(hop, hi, i); //e.g., (X*(Y*(Z%*%v))) -> (X*Y)*(Z%*%v)
hi = simplifyUnaryAggReorgOperation(hop, hi, i); //e.g., sum(t(X)) -> sum(X)
+ hi = pushdownUnaryAggTransposeOperation(hop, hi, i); //e.g., colSums(t(X)) -> t(rowSums(X))
hi = simplifyUnaryPPredOperation(hop, hi, i); //e.g., abs(ppred()) -> ppred(), others: round, ceil, floor
hi = simplifyTransposedAppend(hop, hi, i); //e.g., t(cbind(t(A),t(B))) -> rbind(A,B);
hi = fuseBinarySubDAGToUnaryOperation(hop, hi, i); //e.g., X*(1-X)-> sprop(X) || 1/(1+exp(-X)) -> sigmoid(X) || X*(X>0) -> selp(X)
@@ -819,6 +823,51 @@ public class RewriteAlgebraicSimplificationStatic extends HopRewriteRule
* @param pos
* @return
*/
+ private Hop pushdownUnaryAggTransposeOperation( Hop parent, Hop hi, int pos )
+ {
+ if( hi instanceof AggUnaryOp && hi.getParent().size()==1
+ && (((AggUnaryOp) hi).getDirection()==Direction.Row || ((AggUnaryOp) hi).getDirection()==Direction.Col)
+ && hi.getInput().get(0) instanceof ReorgOp && hi.getInput().get(0).getParent().size()==1
+ && ((ReorgOp)hi.getInput().get(0)).getOp()==ReOrgOp.TRANSPOSE
+ && HopRewriteUtils.isValidOp(((AggUnaryOp) hi).getOp(), LOOKUP_VALID_ROW_COL_AGGREGATE) )
+ {
+ AggUnaryOp uagg = (AggUnaryOp) hi;
+
+ //get input rewire existing operators (remove inner transpose)
+ Hop input = uagg.getInput().get(0).getInput().get(0);
+ HopRewriteUtils.removeAllChildReferences(hi.getInput().get(0));
+ HopRewriteUtils.removeAllChildReferences(hi);
+ HopRewriteUtils.removeChildReferenceByPos(parent, hi, pos);
+
+ //pattern 1: row-aggregate to col aggregate, e.g., rowSums(t(X))->t(colSums(X))
+ if( uagg.getDirection()==Direction.Row ) {
+ uagg.setDirection(Direction.Col);
+ LOG.debug("Applied pushdownUnaryAggTransposeOperation1 (line "+hi.getBeginLine()+").");
+ }
+ //pattern 2: col-aggregate to row aggregate, e.g., colSums(t(X))->t(rowSums(X))
+ else if( uagg.getDirection()==Direction.Col ) {
+ uagg.setDirection(Direction.Row);
+ LOG.debug("Applied pushdownUnaryAggTransposeOperation2 (line "+hi.getBeginLine()+").");
+ }
+
+ //create outer transpose operation and rewire operators
+ HopRewriteUtils.addChildReference(uagg, input); uagg.refreshSizeInformation();
+ Hop trans = HopRewriteUtils.createTranspose(uagg); //incl refresh size
+ HopRewriteUtils.addChildReference(parent, trans, pos); //by def, same size
+
+ hi = trans;
+ }
+
+ return hi;
+ }
+
+ /**
+ *
+ * @param parent
+ * @param hi
+ * @param pos
+ * @return
+ */
private Hop simplifyUnaryPPredOperation( Hop parent, Hop hi, int pos )
{
if( hi instanceof UnaryOp && hi.getDataType()==DataType.MATRIX //unaryop
http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/5956a612/src/test/java/org/apache/sysml/test/integration/functions/misc/RewritePushdownUaggTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/sysml/test/integration/functions/misc/RewritePushdownUaggTest.java b/src/test/java/org/apache/sysml/test/integration/functions/misc/RewritePushdownUaggTest.java
new file mode 100644
index 0000000..348cfbb
--- /dev/null
+++ b/src/test/java/org/apache/sysml/test/integration/functions/misc/RewritePushdownUaggTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.misc;
+
+import java.util.HashMap;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.sysml.hops.OptimizerUtils;
+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;
+import org.apache.sysml.utils.Statistics;
+
+/**
+ * Regression test for function recompile-once issue with literal replacement.
+ *
+ */
+public class RewritePushdownUaggTest extends AutomatedTestBase
+{
+ //two aggregation functions as examples
+ private static final String TEST_NAME1 = "RewritePushdownColsums";
+ private static final String TEST_NAME2 = "RewritePushdownRowsums";
+ private static final String TEST_NAME3 = "RewritePushdownColmins";
+ private static final String TEST_NAME4 = "RewritePushdownRowmins";
+
+ private static final String TEST_DIR = "functions/misc/";
+ private static final String TEST_CLASS_DIR = TEST_DIR + RewritePushdownUaggTest.class.getSimpleName() + "/";
+
+ private static final int rows = 192;
+ private static final int cols = 293;
+ private static final double eps = Math.pow(10, -10);
+
+ @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" }) );
+ addTestConfiguration( TEST_NAME3, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME3, new String[] { "R" }) );
+ addTestConfiguration( TEST_NAME4, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME4, new String[] { "R" }) );
+ }
+
+ @Test
+ public void testRewriteColSumsNoRewrite() {
+ testRewritePushdownUagg( TEST_NAME1, false );
+ }
+
+ @Test
+ public void testRewriteRowSumsNoRewrite() {
+ testRewritePushdownUagg( TEST_NAME2, false );
+ }
+
+ @Test
+ public void testRewriteColMinsNoRewrite() {
+ testRewritePushdownUagg( TEST_NAME3, false );
+ }
+
+ @Test
+ public void testRewriteRowMinsNoRewrite() {
+ testRewritePushdownUagg( TEST_NAME4, false );
+ }
+
+ @Test
+ public void testRewriteColSums() {
+ testRewritePushdownUagg( TEST_NAME1, true );
+ }
+
+ @Test
+ public void testRewriteRowSums() {
+ testRewritePushdownUagg( TEST_NAME2, true );
+ }
+
+ @Test
+ public void testRewriteColMins() {
+ testRewritePushdownUagg( TEST_NAME3, true );
+ }
+
+ @Test
+ public void testRewriteRowMins() {
+ testRewritePushdownUagg( TEST_NAME4, true );
+ }
+
+
+ /**
+ *
+ * @param condition
+ * @param branchRemoval
+ * @param IPA
+ */
+ private void testRewritePushdownUagg( String testname, boolean rewrites )
+ {
+ boolean oldFlag = OptimizerUtils.ALLOW_ALGEBRAIC_SIMPLIFICATION;
+
+ try
+ {
+ TestConfiguration config = getTestConfiguration(testname);
+ loadTestConfiguration(config);
+
+ String HOME = SCRIPT_DIR + TEST_DIR;
+ fullDMLScriptName = HOME + testname + ".dml";
+ programArgs = new String[]{ "-stats","-args", input("X"), output("R") };
+
+ fullRScriptName = HOME + testname + ".R";
+ rCmd = getRCmd(inputDir(), expectedDir());
+
+ OptimizerUtils.ALLOW_ALGEBRAIC_SIMPLIFICATION = rewrites;
+
+ double[][] X = getRandomMatrix(rows, cols, -1, 1, 0.56d, 7);
+ writeInputMatrixWithMTD("X", X, true);
+
+ 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");
+
+ //check matrix mult existence
+ String check = null;
+ if( testname.equals(TEST_NAME1) ) //colsums
+ check = rewrites ? "uark+" : "uack+";
+ else if( testname.equals(TEST_NAME2) ) //rowsums
+ check = rewrites ? "uack+" : "uark+";
+ else if( testname.equals(TEST_NAME3) ) //colmins
+ check = rewrites ? "uarmin" : "uacmin";
+ else if( testname.equals(TEST_NAME4) ) //rowmins
+ check = rewrites ? "uacmin" : "uarmin";
+
+ Assert.assertTrue( "Missing opcode: "+check, Statistics.getCPHeavyHitterOpCodes().contains(check) );
+ }
+ finally
+ {
+ OptimizerUtils.ALLOW_ALGEBRAIC_SIMPLIFICATION = oldFlag;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/5956a612/src/test/scripts/functions/misc/RewritePushdownColmins.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/misc/RewritePushdownColmins.R b/src/test/scripts/functions/misc/RewritePushdownColmins.R
new file mode 100644
index 0000000..4459646
--- /dev/null
+++ b/src/test/scripts/functions/misc/RewritePushdownColmins.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)
+options(digits=22)
+library("Matrix")
+library("matrixStats")
+
+X = as.matrix(readMM(paste(args[1], "X.mtx", sep="")))
+R = t(as.matrix(colMins(t(X))));
+
+writeMM(as(R, "CsparseMatrix"), paste(args[2], "R", sep=""));
http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/5956a612/src/test/scripts/functions/misc/RewritePushdownColmins.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/misc/RewritePushdownColmins.dml b/src/test/scripts/functions/misc/RewritePushdownColmins.dml
new file mode 100644
index 0000000..90d2668
--- /dev/null
+++ b/src/test/scripts/functions/misc/RewritePushdownColmins.dml
@@ -0,0 +1,26 @@
+#-------------------------------------------------------------
+#
+# 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);
+R = colMins(t(X));
+
+write(R, $2);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/5956a612/src/test/scripts/functions/misc/RewritePushdownColsums.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/misc/RewritePushdownColsums.R b/src/test/scripts/functions/misc/RewritePushdownColsums.R
new file mode 100644
index 0000000..baafefe
--- /dev/null
+++ b/src/test/scripts/functions/misc/RewritePushdownColsums.R
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#-------------------------------------------------------------
+
+
+args <- commandArgs(TRUE)
+options(digits=22)
+library("Matrix")
+
+X = as.matrix(readMM(paste(args[1], "X.mtx", sep="")))
+R = t(as.matrix(colSums(t(X))));
+
+writeMM(as(R, "CsparseMatrix"), paste(args[2], "R", sep=""));
http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/5956a612/src/test/scripts/functions/misc/RewritePushdownColsums.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/misc/RewritePushdownColsums.dml b/src/test/scripts/functions/misc/RewritePushdownColsums.dml
new file mode 100644
index 0000000..2528da9
--- /dev/null
+++ b/src/test/scripts/functions/misc/RewritePushdownColsums.dml
@@ -0,0 +1,26 @@
+#-------------------------------------------------------------
+#
+# 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);
+R = colSums(t(X));
+
+write(R, $2);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/5956a612/src/test/scripts/functions/misc/RewritePushdownRowmins.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/misc/RewritePushdownRowmins.R b/src/test/scripts/functions/misc/RewritePushdownRowmins.R
new file mode 100644
index 0000000..0c01834
--- /dev/null
+++ b/src/test/scripts/functions/misc/RewritePushdownRowmins.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)
+options(digits=22)
+library("Matrix")
+library("matrixStats")
+
+X = as.matrix(readMM(paste(args[1], "X.mtx", sep="")))
+R = rowMins(t(X));
+
+writeMM(as(R, "CsparseMatrix"), paste(args[2], "R", sep=""));
http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/5956a612/src/test/scripts/functions/misc/RewritePushdownRowmins.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/misc/RewritePushdownRowmins.dml b/src/test/scripts/functions/misc/RewritePushdownRowmins.dml
new file mode 100644
index 0000000..c5f80e5
--- /dev/null
+++ b/src/test/scripts/functions/misc/RewritePushdownRowmins.dml
@@ -0,0 +1,26 @@
+#-------------------------------------------------------------
+#
+# 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);
+R = rowMins(t(X));
+
+write(R, $2);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/5956a612/src/test/scripts/functions/misc/RewritePushdownRowsums.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/misc/RewritePushdownRowsums.R b/src/test/scripts/functions/misc/RewritePushdownRowsums.R
new file mode 100644
index 0000000..2de9a23
--- /dev/null
+++ b/src/test/scripts/functions/misc/RewritePushdownRowsums.R
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#-------------------------------------------------------------
+
+
+args <- commandArgs(TRUE)
+options(digits=22)
+library("Matrix")
+
+X = as.matrix(readMM(paste(args[1], "X.mtx", sep="")))
+R = rowSums(t(X));
+
+writeMM(as(R, "CsparseMatrix"), paste(args[2], "R", sep=""));
http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/5956a612/src/test/scripts/functions/misc/RewritePushdownRowsums.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/misc/RewritePushdownRowsums.dml b/src/test/scripts/functions/misc/RewritePushdownRowsums.dml
new file mode 100644
index 0000000..945763e
--- /dev/null
+++ b/src/test/scripts/functions/misc/RewritePushdownRowsums.dml
@@ -0,0 +1,26 @@
+#-------------------------------------------------------------
+#
+# 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);
+R = rowSums(t(X));
+
+write(R, $2);
\ No newline at end of file