[SYSTEMML-2273] Codegen support for nary min/max in cell/row templates

This patch adds operator fusion and code generation support for the new
nary min/max operator in cell and row templates. For both scenarios, we
map the nary operator to binary codegen operations which are anyway
fused on a cell or row level without additional overhead and thus no
need for additional template or runtime primitives.


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

Branch: refs/heads/master
Commit: 4d370a8a6fb73329c46f12a3b6775d0b7817dad4
Parents: 8d32079
Author: Matthias Boehm <[email protected]>
Authored: Thu Jun 7 23:37:33 2018 -0700
Committer: Matthias Boehm <[email protected]>
Committed: Thu Jun 7 23:37:33 2018 -0700

----------------------------------------------------------------------
 .../hops/codegen/template/TemplateCell.java     | 19 +++++++--
 .../hops/codegen/template/TemplateRow.java      | 43 +++++++++++++-------
 .../functions/codegen/CellwiseTmplTest.java     | 24 +++++++++--
 .../functions/codegen/RowAggTmplTest.java       | 21 +++++++++-
 .../scripts/functions/codegen/cellwisetmpl23.R  | 31 ++++++++++++++
 .../functions/codegen/cellwisetmpl23.dml        | 30 ++++++++++++++
 .../scripts/functions/codegen/rowAggPattern42.R | 31 ++++++++++++++
 .../functions/codegen/rowAggPattern42.dml       | 30 ++++++++++++++
 8 files changed, 207 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/systemml/blob/4d370a8a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateCell.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateCell.java 
b/src/main/java/org/apache/sysml/hops/codegen/template/TemplateCell.java
index 0ce35c6..0106a59 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateCell.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/template/TemplateCell.java
@@ -37,9 +37,11 @@ import org.apache.sysml.hops.Hop.AggOp;
 import org.apache.sysml.hops.Hop.DataGenMethod;
 import org.apache.sysml.hops.Hop.OpOp2;
 import org.apache.sysml.hops.Hop.OpOp3;
+import org.apache.sysml.hops.Hop.OpOpN;
 import org.apache.sysml.hops.Hop.ParamBuiltinOp;
 import org.apache.sysml.hops.IndexingOp;
 import org.apache.sysml.hops.LiteralOp;
+import org.apache.sysml.hops.NaryOp;
 import org.apache.sysml.hops.ParameterizedBuiltinOp;
 import org.apache.sysml.hops.TernaryOp;
 import org.apache.sysml.hops.codegen.cplan.CNode;
@@ -82,7 +84,8 @@ public class TemplateCell extends TemplateBase
                        || (hop instanceof IndexingOp && 
hop.getInput().get(0).getDim2() >= 0
                                && (((IndexingOp)hop).isColLowerEqualsUpper() 
|| hop.getDim2()==1))
                        || (HopRewriteUtils.isDataGenOpWithLiteralInputs(hop, 
DataGenMethod.SEQ)
-                               && 
HopRewriteUtils.hasOnlyUnaryBinaryParents(hop, true));
+                               && 
HopRewriteUtils.hasOnlyUnaryBinaryParents(hop, true))
+                       || (HopRewriteUtils.isNary(hop, OpOpN.MIN, OpOpN.MAX) 
&& hop.isMatrix());
        }
 
        @Override
@@ -93,7 +96,8 @@ public class TemplateCell extends TemplateBase
                                && hop.getDim1()==1 && hop.getDim2()==1)
                                && 
HopRewriteUtils.isTransposeOperation(hop.getInput().get(0))
                        || (HopRewriteUtils.isTransposeOperation(hop) 
-                               && hop.getDim1()==1 && hop.getDim2()>1));
+                               && hop.getDim1()==1 && hop.getDim2()>1))
+                       || (HopRewriteUtils.isNary(hop, OpOpN.MIN, OpOpN.MAX) 
&& hop.isMatrix());
        }
 
        @Override
@@ -103,7 +107,8 @@ public class TemplateCell extends TemplateBase
                        || (hop instanceof AggBinaryOp && 
hop.getInput().indexOf(input)==0 
                                && 
HopRewriteUtils.isTransposeOperation(input))))
                        || (HopRewriteUtils.isDataGenOpWithLiteralInputs(input, 
DataGenMethod.SEQ)
-                               && 
HopRewriteUtils.hasOnlyUnaryBinaryParents(input, false));
+                               && 
HopRewriteUtils.hasOnlyUnaryBinaryParents(input, false))
+                       || (HopRewriteUtils.isNary(hop, OpOpN.MIN, OpOpN.MAX) 
&& hop.isMatrix());
        }
 
        @Override
@@ -221,6 +226,14 @@ public class TemplateCell extends TemplateBase
                        out = new CNodeTernary(cdata1, cdata2, cdata3, 
                                TernaryType.valueOf(top.getOp().name()));
                }
+               else if(HopRewriteUtils.isNary(hop, OpOpN.MIN, OpOpN.MAX)) {
+                       String op = ((NaryOp)hop).getOp().name();
+                       CNode[] inputs = hop.getInput().stream().map(c -> 
+                               
TemplateUtils.wrapLookupIfNecessary(tmp.get(c.getHopID()), 
c)).toArray(CNode[]::new);
+                       out = new CNodeBinary(inputs[0], inputs[1], 
BinType.valueOf(op));
+                       for( int i=2; i<hop.getInput().size(); i++ )
+                               out = new CNodeBinary(out, inputs[i], 
BinType.valueOf(op));
+               }
                else if( hop instanceof ParameterizedBuiltinOp ) {
                        CNode cdata1 = 
tmp.get(((ParameterizedBuiltinOp)hop).getTargetHop().getHopID());
                        cdata1 = TemplateUtils.wrapLookupIfNecessary(cdata1, 
hop.getInput().get(0));

http://git-wip-us.apache.org/repos/asf/systemml/blob/4d370a8a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateRow.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateRow.java 
b/src/main/java/org/apache/sysml/hops/codegen/template/TemplateRow.java
index 737b30d..55b62ba 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/template/TemplateRow.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/template/TemplateRow.java
@@ -31,6 +31,7 @@ import org.apache.sysml.hops.DataGenOp;
 import org.apache.sysml.hops.Hop;
 import org.apache.sysml.hops.IndexingOp;
 import org.apache.sysml.hops.LiteralOp;
+import org.apache.sysml.hops.NaryOp;
 import org.apache.sysml.hops.ParameterizedBuiltinOp;
 import org.apache.sysml.hops.TernaryOp;
 import org.apache.sysml.hops.UnaryOp;
@@ -92,6 +93,7 @@ public class TemplateRow extends TemplateBase
                        || (HopRewriteUtils.isBinary(hop, OpOp2.CBIND) && 
hop.getInput().get(0).isMatrix() && hop.dimsKnown())
                        || HopRewriteUtils.isTernary(hop, OpOp3.PLUS_MULT, 
OpOp3.MINUS_MULT)
                        || (HopRewriteUtils.isNary(hop, OpOpN.CBIND) && 
hop.getInput().get(0).isMatrix() && hop.dimsKnown())
+                       || (HopRewriteUtils.isNary(hop, OpOpN.MIN, OpOpN.MAX) 
&& hop.isMatrix())
                        || (hop instanceof AggBinaryOp && hop.dimsKnown() && 
hop.getDim2()==1 //MV
                                && hop.getInput().get(0).getDim1()>1 && 
hop.getInput().get(0).getDim2()>1)
                        || (hop instanceof AggBinaryOp && hop.dimsKnown() && 
LibMatrixMult.isSkinnyRightHandSide(
@@ -117,6 +119,7 @@ public class TemplateRow extends TemplateBase
                        (  (hop instanceof BinaryOp && 
isValidBinaryOperation(hop)) 
                        || (HopRewriteUtils.isBinary(hop, OpOp2.CBIND) && 
hop.getInput().get(0).isMatrix() && hop.dimsKnown())
                        || (HopRewriteUtils.isNary(hop, OpOpN.CBIND) && 
hop.getInput().get(0).isMatrix() && hop.dimsKnown())
+                       || (HopRewriteUtils.isNary(hop, OpOpN.MIN, OpOpN.MAX) 
&& hop.isMatrix())
                        || ((hop instanceof UnaryOp || hop instanceof 
ParameterizedBuiltinOp) 
                                && TemplateCell.isValidOperation(hop))
                        || HopRewriteUtils.isTernary(hop, OpOp3.PLUS_MULT, 
OpOp3.MINUS_MULT)
@@ -141,6 +144,7 @@ public class TemplateRow extends TemplateBase
                                && hop.getDim1() > 1 && input.getDim1()>1)
                        || (HopRewriteUtils.isBinary(hop, OpOp2.CBIND) && 
hop.getInput().get(0).isMatrix() && hop.dimsKnown())
                        || (HopRewriteUtils.isNary(hop, OpOpN.CBIND) && 
hop.getInput().get(0).isMatrix() && hop.dimsKnown())
+                       || (HopRewriteUtils.isNary(hop, OpOpN.MIN, OpOpN.MAX) 
&& hop.isMatrix())
                        || (HopRewriteUtils.isDataGenOpWithLiteralInputs(input, 
DataGenMethod.SEQ)
                                && 
HopRewriteUtils.hasOnlyUnaryBinaryParents(input, false))
                        || (hop instanceof AggBinaryOp
@@ -408,19 +412,11 @@ public class TemplateRow extends TemplateBase
                                        && (cdata1.getDataType().isMatrix() || 
cdata2.getDataType().isMatrix())))
                        {
                                if( HopRewriteUtils.isBinary(hop, 
SUPPORTED_VECT_BINARY) ) {
-                                       if( TemplateUtils.isMatrix(cdata1) && 
(TemplateUtils.isMatrix(cdata2) 
-                                                       || 
TemplateUtils.isRowVector(cdata2)) ) {
-                                               String opname = 
"VECT_"+((BinaryOp)hop).getOp().name();
-                                               out = new CNodeBinary(cdata1, 
cdata2, BinType.valueOf(opname));
-                                       }
-                                       else {
-                                               String opname = 
"VECT_"+((BinaryOp)hop).getOp().name()+"_SCALAR";
-                                               if( 
TemplateUtils.isColVector(cdata1) )
-                                                       cdata1 = new 
CNodeUnary(cdata1, UnaryType.LOOKUP_R);
-                                               if( 
TemplateUtils.isColVector(cdata2) )
-                                                       cdata2 = new 
CNodeUnary(cdata2, UnaryType.LOOKUP_R);
-                                               out = new CNodeBinary(cdata1, 
cdata2, BinType.valueOf(opname));
-                                       }
+                                       if( TemplateUtils.isColVector(cdata1) )
+                                               cdata1 = new CNodeUnary(cdata1, 
UnaryType.LOOKUP_R);
+                                       if( TemplateUtils.isColVector(cdata2) )
+                                               cdata2 = new CNodeUnary(cdata2, 
UnaryType.LOOKUP_R);
+                                       out = getVectorBinary(cdata1, cdata2, 
((BinaryOp)hop).getOp().name());
                                        if( cdata1 instanceof CNodeData && 
!inHops2.containsKey("X")
                                                && 
!(cdata1.getDataType()==DataType.SCALAR) ) {
                                                inHops2.put("X", 
hop.getInput().get(0));
@@ -463,7 +459,7 @@ public class TemplateRow extends TemplateBase
                                        
TernaryType.valueOf(top.getOp().name()));
                        }
                }
-               else if(HopRewriteUtils.isNary(hop, OpOpN.CBIND)) {
+               else if( hop instanceof NaryOp ) {
                        CNode[] inputs = new CNode[hop.getInput().size()];
                        for( int i=0; i<hop.getInput().size(); i++ ) {
                                Hop c = hop.getInput().get(i);
@@ -474,7 +470,14 @@ public class TemplateRow extends TemplateBase
                                if( i==0 && cdata instanceof CNodeData && 
!inHops2.containsKey("X") )
                                        inHops2.put("X", c);
                        }
-                       out = new CNodeNary(inputs, NaryType.VECT_CBIND);
+                       if( HopRewriteUtils.isNary(hop, OpOpN.CBIND) ) {
+                               out = new CNodeNary(inputs, 
NaryType.VECT_CBIND);
+                       }
+                       else if( HopRewriteUtils.isNary(hop, OpOpN.MIN, 
OpOpN.MAX) ) {
+                               out = getVectorBinary(inputs[0], inputs[1], 
((NaryOp)hop).getOp().name());
+                               for( int i=2; i<hop.getInput().size(); i++ )
+                                       out = getVectorBinary(out, inputs[i], 
((NaryOp)hop).getOp().name());
+                       }
                }
                else if( hop instanceof ParameterizedBuiltinOp ) {
                        CNode cdata1 = 
tmp.get(((ParameterizedBuiltinOp)hop).getTargetHop().getHopID());
@@ -505,6 +508,16 @@ public class TemplateRow extends TemplateBase
                tmp.put(hop.getHopID(), out);
        }
        
+       private CNodeBinary getVectorBinary(CNode cdata1, CNode cdata2, String 
name) {
+               if( TemplateUtils.isMatrix(cdata1) && 
(TemplateUtils.isMatrix(cdata2) 
+                               || TemplateUtils.isRowVector(cdata2)) ) {
+                       return new CNodeBinary(cdata1, cdata2, 
BinType.valueOf("VECT_"+name));
+               }
+               else {
+                       return new CNodeBinary(cdata1, cdata2, 
BinType.valueOf("VECT_"+name+"_SCALAR"));
+               }
+       }
+       
        /**
         * Comparator to order input hops of the row aggregate template. We try 
         * to order matrices-vectors-scalars via sorting by number of cells but 

http://git-wip-us.apache.org/repos/asf/systemml/blob/4d370a8a/src/test/java/org/apache/sysml/test/integration/functions/codegen/CellwiseTmplTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/sysml/test/integration/functions/codegen/CellwiseTmplTest.java
 
b/src/test/java/org/apache/sysml/test/integration/functions/codegen/CellwiseTmplTest.java
index 76469de..cfcabde 100644
--- 
a/src/test/java/org/apache/sysml/test/integration/functions/codegen/CellwiseTmplTest.java
+++ 
b/src/test/java/org/apache/sysml/test/integration/functions/codegen/CellwiseTmplTest.java
@@ -58,6 +58,7 @@ public class CellwiseTmplTest extends AutomatedTestBase
        private static final String TEST_NAME20 = TEST_NAME+20; //bitwAnd() 
operation
        private static final String TEST_NAME21 = TEST_NAME+21; //relu 
operation, (X>0)*dout
        private static final String TEST_NAME22 = TEST_NAME+22; //sum(X * 
seq(1,N) + t(seq(M,1)))
+       private static final String TEST_NAME23 = TEST_NAME+23; 
//sum(min(X,Y,Z))
        
        private static final String TEST_DIR = "functions/codegen/";
        private static final String TEST_CLASS_DIR = TEST_DIR + 
CellwiseTmplTest.class.getSimpleName() + "/";
@@ -70,7 +71,7 @@ public class CellwiseTmplTest extends AutomatedTestBase
        @Override
        public void setUp() {
                TestUtils.clearAssertionInformation();
-               for( int i=1; i<=22; i++ ) {
+               for( int i=1; i<=23; i++ ) {
                        addTestConfiguration( TEST_NAME+i, new 
TestConfiguration(
                                        TEST_CLASS_DIR, TEST_NAME+i, new 
String[] {String.valueOf(i)}) );
                }
@@ -382,6 +383,21 @@ public class CellwiseTmplTest extends AutomatedTestBase
        public void testCodegenCellwiseRewrite22_sp() {
                testCodegenIntegration( TEST_NAME22, true, ExecType.SPARK );
        }
+       
+       @Test
+       public void testCodegenCellwiseRewrite23() {
+               testCodegenIntegration( TEST_NAME23, true, ExecType.CP );
+       }
+
+       @Test
+       public void testCodegenCellwise23() {
+               testCodegenIntegration( TEST_NAME23, false, ExecType.CP );
+       }
+
+       @Test
+       public void testCodegenCellwiseRewrite23_sp() {
+               testCodegenIntegration( TEST_NAME23, true, ExecType.SPARK );
+       }
 
        private void testCodegenIntegration( String testname, boolean rewrites, 
ExecType instType )
        {
@@ -409,7 +425,7 @@ public class CellwiseTmplTest extends AutomatedTestBase
                        
                        String HOME = SCRIPT_DIR + TEST_DIR;
                        fullDMLScriptName = HOME + testname + ".dml";
-                       programArgs = new String[]{"-explain", "hops", 
"-stats", "-args", output("S") };
+                       programArgs = new String[]{"-explain", "-stats", 
"-args", output("S") };
                        
                        fullRScriptName = HOME + testname + ".R";
                        rCmd = getRCmd(inputDir(), expectedDir());
@@ -420,7 +436,7 @@ public class CellwiseTmplTest extends AutomatedTestBase
                        runRScript(true); 
                        
                        if(testname.equals(TEST_NAME6) || 
testname.equals(TEST_NAME7) 
-                               || testname.equals(TEST_NAME9) || 
testname.equals(TEST_NAME10) ) {
+                               || testname.equals(TEST_NAME9) || 
testname.equals(TEST_NAME10)) {
                                //compare scalars 
                                HashMap<CellIndex, Double> dmlfile = 
readDMLScalarFromHDFS("S");
                                HashMap<CellIndex, Double> rfile  = 
readRScalarFromFS("S");
@@ -451,6 +467,8 @@ public class CellwiseTmplTest extends AutomatedTestBase
                                
Assert.assertTrue(!heavyHittersContainsSubString("xor"));
                        else if( testname.equals(TEST_NAME22) )
                                
Assert.assertTrue(!heavyHittersContainsSubString("seq"));
+                       else if( testname.equals(TEST_NAME23) )
+                               
Assert.assertTrue(!heavyHittersContainsSubString("min","nmin"));
                }
                finally {
                        rtplatform = platformOld;

http://git-wip-us.apache.org/repos/asf/systemml/blob/4d370a8a/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java
 
b/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java
index e07c543..203e9b1 100644
--- 
a/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java
+++ 
b/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java
@@ -78,6 +78,7 @@ public class RowAggTmplTest extends AutomatedTestBase
        private static final String TEST_NAME39 = TEST_NAME+"39"; //BitwAnd 
operation
        private static final String TEST_NAME40 = TEST_NAME+"40"; //relu 
operation -> (X>0)* dout
        private static final String TEST_NAME41 = TEST_NAME+"41"; 
//X*rowSums(X/seq(1,N)+t(seq(M,1)))
+       private static final String TEST_NAME42 = TEST_NAME+"42"; 
//X/rowSums(min(X, Y, Z))
        
        private static final String TEST_DIR = "functions/codegen/";
        private static final String TEST_CLASS_DIR = TEST_DIR + 
RowAggTmplTest.class.getSimpleName() + "/";
@@ -89,7 +90,7 @@ public class RowAggTmplTest extends AutomatedTestBase
        @Override
        public void setUp() {
                TestUtils.clearAssertionInformation();
-               for(int i=1; i<=41; i++)
+               for(int i=1; i<=42; i++)
                        addTestConfiguration( TEST_NAME+i, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME+i, new String[] { String.valueOf(i) 
}) );
        }
        
@@ -707,6 +708,21 @@ public class RowAggTmplTest extends AutomatedTestBase
        public void testCodegenRowAgg41SP() {
                testCodegenIntegration( TEST_NAME41, false, ExecType.SPARK );
        }
+       
+       @Test
+       public void testCodegenRowAggRewrite42CP() {
+               testCodegenIntegration( TEST_NAME42, true, ExecType.CP );
+       }
+
+       @Test
+       public void testCodegenRowAgg42CP() {
+               testCodegenIntegration( TEST_NAME42, false, ExecType.CP );
+       }
+
+       @Test
+       public void testCodegenRowAgg42SP() {
+               testCodegenIntegration( TEST_NAME42, false, ExecType.SPARK );
+       }
 
        private void testCodegenIntegration( String testname, boolean rewrites, 
ExecType instType )
        {
@@ -766,6 +782,9 @@ public class RowAggTmplTest extends AutomatedTestBase
                                
Assert.assertTrue(!heavyHittersContainsSubString("xor"));
                        if( testname.equals(TEST_NAME41) )
                                
Assert.assertTrue(!heavyHittersContainsSubString("seq"));
+                       if( testname.equals(TEST_NAME42) )
+                               
Assert.assertTrue(!heavyHittersContainsSubString("min","nmin") 
+                                       && 
!heavyHittersContainsSubString("spoof", 2));
                }
                finally {
                        rtplatform = platformOld;

http://git-wip-us.apache.org/repos/asf/systemml/blob/4d370a8a/src/test/scripts/functions/codegen/cellwisetmpl23.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/cellwisetmpl23.R 
b/src/test/scripts/functions/codegen/cellwisetmpl23.R
new file mode 100644
index 0000000..9dffe0a
--- /dev/null
+++ b/src/test/scripts/functions/codegen/cellwisetmpl23.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")
+
+X = matrix(6, 500, 2);
+Y = matrix(7, 500, 2);
+Z = matrix(8, 500, 2);
+R = as.matrix(sum(pmin(X,Y,Z)));
+
+writeMM(as(R,"CsparseMatrix"), paste(args[2], "S", sep=""));

http://git-wip-us.apache.org/repos/asf/systemml/blob/4d370a8a/src/test/scripts/functions/codegen/cellwisetmpl23.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/cellwisetmpl23.dml 
b/src/test/scripts/functions/codegen/cellwisetmpl23.dml
new file mode 100644
index 0000000..8e53d27
--- /dev/null
+++ b/src/test/scripts/functions/codegen/cellwisetmpl23.dml
@@ -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.
+#
+#-------------------------------------------------------------
+
+X = matrix(6, 500, 2);
+Y = matrix(7, 500, 2);
+Z = matrix(8, 500, 2);
+
+while(FALSE){}
+
+R = as.matrix(sum(min(X,Y,Z)));
+
+write(R, $1)

http://git-wip-us.apache.org/repos/asf/systemml/blob/4d370a8a/src/test/scripts/functions/codegen/rowAggPattern42.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/rowAggPattern42.R 
b/src/test/scripts/functions/codegen/rowAggPattern42.R
new file mode 100644
index 0000000..2214a46
--- /dev/null
+++ b/src/test/scripts/functions/codegen/rowAggPattern42.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")
+
+X = matrix(6, 500, 2);
+Y = matrix(7, 500, 2);
+Z = matrix(8, 500, 2);
+R = X / (rowSums(pmin(X, Y, Z)) %*% matrix(1,1,2));
+
+writeMM(as(R,"CsparseMatrix"), paste(args[2], "S", sep=""));

http://git-wip-us.apache.org/repos/asf/systemml/blob/4d370a8a/src/test/scripts/functions/codegen/rowAggPattern42.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/rowAggPattern42.dml 
b/src/test/scripts/functions/codegen/rowAggPattern42.dml
new file mode 100644
index 0000000..78647c7
--- /dev/null
+++ b/src/test/scripts/functions/codegen/rowAggPattern42.dml
@@ -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.
+#
+#-------------------------------------------------------------
+
+X = matrix(6, 500, 2);
+Y = matrix(7, 500, 2);
+Z = matrix(8, 500, 2);
+
+while(FALSE){}
+
+R = X / rowSums(min(X, Y, Z));
+
+write(R, $1)

Reply via email to