Repository: systemml
Updated Branches:
  refs/heads/master eb182010b -> bfd495289


[SYSTEMML-2208] Functions with default scalar/matrix/frame parameters

This patch introduces support for default function arguments that are
used whenever the related argument is not provided by a function call.
To this end, this patch modified the parser to allow assignment
expressions in function signatures. Furthermore, we use a simple
compiler approach of adding these default expressions to all function
calls that do not provide certain arguments. Non-provided arguments
without defaults consistently result in compilation (not runtime)
errors.


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

Branch: refs/heads/master
Commit: bfd4952891a92af869965f8d16631c6e9aa156db
Parents: eb18201
Author: Matthias Boehm <mboe...@gmail.com>
Authored: Thu Jul 26 18:33:57 2018 -0700
Committer: Matthias Boehm <mboe...@gmail.com>
Committed: Thu Jul 26 18:34:22 2018 -0700

----------------------------------------------------------------------
 .../org/apache/sysml/parser/DMLTranslator.java  | 62 +++++++++++++++-----
 .../sysml/parser/FunctionCallIdentifier.java    |  8 ++-
 .../apache/sysml/parser/FunctionStatement.java  | 23 +++++++-
 .../java/org/apache/sysml/parser/dml/Dml.g4     |  4 +-
 .../sysml/parser/dml/DmlPreprocessor.java       |  7 +++
 .../sysml/parser/dml/DmlSyntacticValidator.java | 62 +++++++++++++-------
 .../functions/misc/FunctionPotpourriTest.java   | 30 +++++++++-
 .../misc/FunPotpourriDefaultArgMatrix.dml       | 31 ++++++++++
 .../misc/FunPotpourriDefaultArgScalar.dml       | 39 ++++++++++++
 .../FunPotpourriDefaultArgScalarMatrix1.dml     | 39 ++++++++++++
 .../FunPotpourriDefaultArgScalarMatrix2.dml     | 43 ++++++++++++++
 11 files changed, 303 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/systemml/blob/bfd49528/src/main/java/org/apache/sysml/parser/DMLTranslator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/parser/DMLTranslator.java 
b/src/main/java/org/apache/sysml/parser/DMLTranslator.java
index d8698a7..22d152d 100644
--- a/src/main/java/org/apache/sysml/parser/DMLTranslator.java
+++ b/src/main/java/org/apache/sysml/parser/DMLTranslator.java
@@ -21,8 +21,8 @@ package org.apache.sysml.parser;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -1331,21 +1331,25 @@ public class DMLTranslator
                                        }
                                        
                                        //prepare function input names and 
inputs
-                                       String[] inputNames = 
fci.getParamExprs().stream()
-                                               .map(e -> 
e.getName()).toArray(String[]::new);
-                                       List<Hop> finputs = 
fci.getParamExprs().stream()
-                                               .map(e -> 
processExpression(e.getExpr(), null, ids)).collect(Collectors.toList());
+                                       List<String> inputNames = new 
ArrayList<>(fci.getParamExprs().stream()
+                                               .map(e -> 
e.getName()).collect(Collectors.toList()));
+                                       List<Hop> finputs = new 
ArrayList<>(fci.getParamExprs().stream()
+                                               .map(e -> 
processExpression(e.getExpr(), null, ids)).collect(Collectors.toList()));
+                                       
+                                       //append default expression for missing 
arguments
+                                       appendDefaultArguments(fstmt, 
inputNames, finputs, ids);
                                        
                                        //use function signature to obtain 
names for unnamed args
                                        //(note: consistent parameters already 
checked for functions in general)
-                                       if( 
Arrays.stream(inputNames).allMatch(n -> n==null) )
-                                               inputNames = 
fstmt._inputParams.stream().map(d -> d.getName()).toArray(String[]::new);
+                                       if( inputNames.stream().allMatch(n -> 
n==null) )
+                                               inputNames = 
fstmt._inputParams.stream().map(d -> d.getName()).collect(Collectors.toList());
                                        
                                        //create function op
+                                       String[] inputNames2 = 
inputNames.toArray(new String[0]);
                                        FunctionType ftype = 
fsb.getFunctionOpType();
                                        FunctionOp fcall = (target == null) ?
-                                               new FunctionOp(ftype, 
fci.getNamespace(), fci.getName(), inputNames, finputs, new String[]{}, false) :
-                                               new FunctionOp(ftype, 
fci.getNamespace(), fci.getName(), inputNames, finputs, new 
String[]{target.getName()}, false);
+                                               new FunctionOp(ftype, 
fci.getNamespace(), fci.getName(), inputNames2, finputs, new String[]{}, false) 
:
+                                               new FunctionOp(ftype, 
fci.getNamespace(), fci.getName(), inputNames2, finputs, new 
String[]{target.getName()}, false);
                                        fcall.setParseInfo(fci);
                                        output.add(fcall);
                                }
@@ -1367,21 +1371,25 @@ public class DMLTranslator
                                        FunctionStatement fstmt = 
(FunctionStatement)fsb.getStatement(0);
                                        
                                        //prepare function input names and 
inputs
-                                       String[] inputNames = 
fci.getParamExprs().stream()
-                                               .map(e -> 
e.getName()).toArray(String[]::new);
-                                       List<Hop> finputs = 
fci.getParamExprs().stream()
-                                               .map(e -> 
processExpression(e.getExpr(), null, ids)).collect(Collectors.toList());
+                                       List<String> inputNames = new 
ArrayList<>(fci.getParamExprs().stream()
+                                               .map(e -> 
e.getName()).collect(Collectors.toList()));
+                                       List<Hop> finputs = new 
ArrayList<>(fci.getParamExprs().stream()
+                                               .map(e -> 
processExpression(e.getExpr(), null, ids)).collect(Collectors.toList()));
                                        
                                        //use function signature to obtain 
names for unnamed args
                                        //(note: consistent parameters already 
checked for functions in general)
-                                       if( 
Arrays.stream(inputNames).allMatch(n -> n==null) )
-                                               inputNames = 
fstmt._inputParams.stream().map(d -> d.getName()).toArray(String[]::new);
+                                       if( inputNames.stream().allMatch(n -> 
n==null) )
+                                               inputNames = 
fstmt._inputParams.stream().map(d -> d.getName()).collect(Collectors.toList());
+                                       
+                                       //append default expression for missing 
arguments
+                                       appendDefaultArguments(fstmt, 
inputNames, finputs, ids);
                                        
                                        //create function op
                                        String[] foutputs = 
mas.getTargetList().stream()
                                                .map(d -> 
d.getName()).toArray(String[]::new);
                                        FunctionType ftype = 
fsb.getFunctionOpType();
-                                       FunctionOp fcall = new 
FunctionOp(ftype, fci.getNamespace(), fci.getName(), inputNames, finputs, 
foutputs, false);
+                                       FunctionOp fcall = new 
FunctionOp(ftype, fci.getNamespace(), fci.getName(),
+                                               inputNames.toArray(new 
String[0]), finputs, foutputs, false);
                                        fcall.setParseInfo(fci);
                                        output.add(fcall);
                                }
@@ -1405,6 +1413,28 @@ public class DMLTranslator
 
        }
        
+       private void appendDefaultArguments(FunctionStatement fstmt, 
List<String> inputNames, List<Hop> inputs, HashMap<String, Hop> ids) {
+               //NOTE: For default expressions of unspecified function 
arguments, we have two choices:
+               //either (a) compile ifelse(exist(argName),default, argName) 
into the function, or
+               //simply (b) add the default to the argument list of function 
calls when needed.
+               //We decided for (b) because it simplifies IPA and dynamic 
recompilation.
+               
+               if( fstmt.getInputParams().size() == inputs.size() )
+                       return;
+               HashSet<String> probeNames = new HashSet<String>(inputNames);
+               for( DataIdentifier di : fstmt.getInputParams() ) {
+                       if( probeNames.contains(di.getName()) ) continue;
+                       Expression exp = fstmt.getInputDefault(di.getName());
+                       if( exp == null ) {
+                               throw new LanguageException("Missing default 
expression for unspecified "
+                                       + "function argument '"+di.getName()+"' 
in call to function '"+fstmt.getName()+"'.");
+                       }
+                       //compile and add default expression
+                       inputNames.add(di.getName());
+                       inputs.add(processExpression(exp, null, ids));
+               }
+       }
+       
        public void constructHopsForIfControlBlock(IfStatementBlock sb) {
                IfStatement ifsb = (IfStatement) sb.getStatement(0);
                ArrayList<StatementBlock> ifBody = ifsb.getIfBody();

http://git-wip-us.apache.org/repos/asf/systemml/blob/bfd49528/src/main/java/org/apache/sysml/parser/FunctionCallIdentifier.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/parser/FunctionCallIdentifier.java 
b/src/main/java/org/apache/sysml/parser/FunctionCallIdentifier.java
index 4ffe582..419bc81 100644
--- a/src/main/java/org/apache/sysml/parser/FunctionCallIdentifier.java
+++ b/src/main/java/org/apache/sysml/parser/FunctionCallIdentifier.java
@@ -120,13 +120,18 @@ public class FunctionCallIdentifier extends DataIdentifier
                                        _name + " has both parameter types.", 
conditional);
                }
                
-               // Step 4: validate expressions for each passed parameter
+               // Step 4: validate expressions for each passed parameter and 
defaults
                for( ParameterExpression paramExpr : _paramExprs ) {
                        if (paramExpr.getExpr() instanceof 
FunctionCallIdentifier) {
                                raiseValidateError("UDF function call not 
supported as parameter to function call", false);
                        }
                        paramExpr.getExpr().validateExpression(ids, constVars, 
conditional);
                }
+               FunctionStatement fstmt = 
(FunctionStatement)fblock.getStatement(0);
+               for( Expression expDef : fstmt.getInputDefaults() ) {
+                       if( expDef != null )
+                               expDef.validateExpression(ids, constVars, 
conditional);
+               }
                
                // Step 5: constant propagation into function call statement
                if( !conditional ) {
@@ -142,7 +147,6 @@ public class FunctionCallIdentifier extends DataIdentifier
                }
        
                // Step 6: check correctness of number of arguments and their 
types 
-               FunctionStatement fstmt = 
(FunctionStatement)fblock.getStatement(0);
                if (fstmt.getInputParams().size() < _paramExprs.size()) { 
                        raiseValidateError("function " + _name 
                                        + " has incorrect number of parameters. 
Function requires " 

http://git-wip-us.apache.org/repos/asf/systemml/blob/bfd49528/src/main/java/org/apache/sysml/parser/FunctionStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/parser/FunctionStatement.java 
b/src/main/java/org/apache/sysml/parser/FunctionStatement.java
index 50bb2d3..a24cb1a 100644
--- a/src/main/java/org/apache/sysml/parser/FunctionStatement.java
+++ b/src/main/java/org/apache/sysml/parser/FunctionStatement.java
@@ -26,8 +26,9 @@ public class FunctionStatement extends Statement
 {
        private ArrayList<StatementBlock> _body;
        protected String _name;
-       protected ArrayList <DataIdentifier> _inputParams;
-       protected ArrayList <DataIdentifier> _outputParams;
+       protected ArrayList<DataIdentifier> _inputParams;
+       protected ArrayList<Expression> _inputDefaults;
+       protected ArrayList<DataIdentifier> _outputParams;
        
        @Override
        public Statement rewriteStatement(String prefix) {
@@ -38,6 +39,7 @@ public class FunctionStatement extends Statement
                _body = new ArrayList<>();
                _name = null;
                _inputParams = new ArrayList<>();
+               _inputDefaults = new ArrayList<>();
                _outputParams = new ArrayList<>();
        }
        
@@ -51,14 +53,29 @@ public class FunctionStatement extends Statement
                        .findFirst().orElse(null);
        }
        
+       public ArrayList<Expression> getInputDefaults() {
+               return _inputDefaults;
+       }
+       
+       public Expression getInputDefault(String name) {
+               for(int i=0; i<_inputParams.size(); i++)
+                       if( _inputParams.get(i).getName().equals(name) )
+                               return _inputDefaults.get(i);
+               return null;
+       }
+       
        public ArrayList<DataIdentifier> getOutputParams(){
                return _outputParams;
        }
        
-       public void setInputParams(ArrayList<DataIdentifier> inputParams){
+       public void setInputParams(ArrayList<DataIdentifier> inputParams) {
                _inputParams = inputParams;
        }
        
+       public void setInputDefaults(ArrayList<Expression> inputDefaults) {
+               _inputDefaults = inputDefaults;
+       }
+       
        public void setOutputParams(ArrayList<DataIdentifier> outputParams){
                _outputParams = outputParams;
        }

http://git-wip-us.apache.org/repos/asf/systemml/blob/bfd49528/src/main/java/org/apache/sysml/parser/dml/Dml.g4
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/parser/dml/Dml.g4 
b/src/main/java/org/apache/sysml/parser/dml/Dml.g4
index e5c1f2c..46ee178 100644
--- a/src/main/java/org/apache/sysml/parser/dml/Dml.g4
+++ b/src/main/java/org/apache/sysml/parser/dml/Dml.g4
@@ -99,7 +99,7 @@ functionStatement returns [ 
org.apache.sysml.parser.common.StatementInfo info ]
     // ------------------------------------------
     // FunctionStatement & ExternalFunctionStatement
     // small change: only allow typed arguments here ... instead of data 
identifier
-    name=ID ('<-'|'=') 'function' '(' ( inputParams+=typedArgNoAssign (',' 
inputParams+=typedArgNoAssign)* )? ')'  ( 'return' '(' ( 
outputParams+=typedArgNoAssign (',' outputParams+=typedArgNoAssign)* )? ')' )? 
'{' (body+=statement ';'*)* '}' ';'* # InternalFunctionDefExpression
+    name=ID ('<-'|'=') 'function' '(' ( inputParams+=typedArgAssign (',' 
inputParams+=typedArgAssign)* )? ')'  ( 'return' '(' ( 
outputParams+=typedArgNoAssign (',' outputParams+=typedArgNoAssign)* )? ')' )? 
'{' (body+=statement ';'*)* '}' ';'* # InternalFunctionDefExpression
     | name=ID ('<-'|'=') 'externalFunction' '(' ( 
inputParams+=typedArgNoAssign (',' inputParams+=typedArgNoAssign)* )? ')'  ( 
'return' '(' ( outputParams+=typedArgNoAssign (',' 
outputParams+=typedArgNoAssign)* )? ')' )?   'implemented' 'in' '(' ( 
otherParams+=strictParameterizedKeyValueString (',' 
otherParams+=strictParameterizedKeyValueString)* )? ')' ';'*    # 
ExternalFunctionDefExpression
     // ------------------------------------------
 ;
@@ -176,6 +176,8 @@ expression returns [ 
org.apache.sysml.parser.common.ExpressionInfo info ]
 ;
 
 typedArgNoAssign : paramType=ml_type paramName=ID;
+typedArgAssign : paramType=ml_type (paramName=ID | (paramName=ID '=')? 
paramVal=expression);
+
 parameterizedExpression : (paramName=ID '=')? paramVal=expression;
 strictParameterizedExpression : paramName=ID '=' paramVal=expression ;
 strictParameterizedKeyValueString : paramName=ID '=' paramVal=STRING ;

http://git-wip-us.apache.org/repos/asf/systemml/blob/bfd49528/src/main/java/org/apache/sysml/parser/dml/DmlPreprocessor.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/parser/dml/DmlPreprocessor.java 
b/src/main/java/org/apache/sysml/parser/dml/DmlPreprocessor.java
index 00473c0..56eb8ca 100644
--- a/src/main/java/org/apache/sysml/parser/dml/DmlPreprocessor.java
+++ b/src/main/java/org/apache/sysml/parser/dml/DmlPreprocessor.java
@@ -69,6 +69,7 @@ import 
org.apache.sysml.parser.dml.DmlParser.RelationalExpressionContext;
 import 
org.apache.sysml.parser.dml.DmlParser.SimpleDataIdentifierExpressionContext;
 import 
org.apache.sysml.parser.dml.DmlParser.StrictParameterizedExpressionContext;
 import 
org.apache.sysml.parser.dml.DmlParser.StrictParameterizedKeyValueStringContext;
+import org.apache.sysml.parser.dml.DmlParser.TypedArgAssignContext;
 import org.apache.sysml.parser.dml.DmlParser.TypedArgNoAssignContext;
 import org.apache.sysml.parser.dml.DmlParser.UnaryExpressionContext;
 import org.apache.sysml.parser.dml.DmlParser.ValueTypeContext;
@@ -177,6 +178,12 @@ public class DmlPreprocessor implements DmlListener {
        public void exitTypedArgNoAssign(TypedArgNoAssignContext ctx) {}
 
        @Override
+       public void enterTypedArgAssign(TypedArgAssignContext ctx) {}
+
+       @Override
+       public void exitTypedArgAssign(TypedArgAssignContext ctx) {}
+       
+       @Override
        public void enterWhileStatement(WhileStatementContext ctx) {}
 
        @Override

http://git-wip-us.apache.org/repos/asf/systemml/blob/bfd49528/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java 
b/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java
index 5624f2a..d87ccbb 100644
--- a/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java
+++ b/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java
@@ -25,6 +25,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.Token;
@@ -104,6 +105,7 @@ import 
org.apache.sysml.parser.dml.DmlParser.SimpleDataIdentifierExpressionConte
 import org.apache.sysml.parser.dml.DmlParser.StatementContext;
 import 
org.apache.sysml.parser.dml.DmlParser.StrictParameterizedExpressionContext;
 import 
org.apache.sysml.parser.dml.DmlParser.StrictParameterizedKeyValueStringContext;
+import org.apache.sysml.parser.dml.DmlParser.TypedArgAssignContext;
 import org.apache.sysml.parser.dml.DmlParser.TypedArgNoAssignContext;
 import org.apache.sysml.parser.dml.DmlParser.UnaryExpressionContext;
 import org.apache.sysml.parser.dml.DmlParser.ValueTypeContext;
@@ -667,8 +669,8 @@ public class DmlSyntacticValidator extends 
CommonSyntacticValidator implements D
                ctx.info.stmt = parForStmt;
        }
 
-       private ArrayList<DataIdentifier> 
getFunctionParameters(List<TypedArgNoAssignContext> ctx) {
-               ArrayList<DataIdentifier> retVal = new ArrayList<>();
+       private ArrayList<DataIdentifier> 
getFunctionParametersNoAssign(List<TypedArgNoAssignContext> ctx) {
+               ArrayList<DataIdentifier> retVal = new ArrayList<>(ctx.size());
                for(TypedArgNoAssignContext paramCtx : ctx) {
                        DataIdentifier dataId = new 
DataIdentifier(paramCtx.paramName.getText());
                        String dataType = (paramCtx.paramType == null || 
paramCtx.paramType.dataType() == null
@@ -684,6 +686,29 @@ public class DmlSyntacticValidator extends 
CommonSyntacticValidator implements D
                }
                return retVal;
        }
+       
+       private ArrayList<DataIdentifier> 
getFunctionParametersAssign(List<TypedArgAssignContext> ctx) {
+               ArrayList<DataIdentifier> retVal = new ArrayList<>(ctx.size());
+               for(TypedArgAssignContext paramCtx : ctx) {
+                       DataIdentifier dataId = new 
DataIdentifier(paramCtx.paramName.getText());
+                       String dataType = (paramCtx.paramType == null || 
paramCtx.paramType.dataType() == null
+                               || paramCtx.paramType.dataType().getText() == 
null || paramCtx.paramType.dataType().getText().isEmpty()) ?
+                               "scalar" : 
paramCtx.paramType.dataType().getText();
+                       String valueType = 
paramCtx.paramType.valueType().getText();
+                       
+                       //check and assign data type
+                       checkValidDataType(dataType, paramCtx.start);
+                       if( !setDataAndValueType(dataId, dataType, valueType, 
paramCtx.start, false, true) )
+                               return null;
+                       retVal.add(dataId);
+               }
+               return retVal;
+       }
+       
+       private ArrayList<Expression> 
getFunctionDefaults(List<TypedArgAssignContext> ctx) {
+               return new ArrayList<>(ctx.stream().map(arg -> 
+                       
(arg.paramVal!=null)?arg.paramVal.info.expr:null).collect(Collectors.toList()));
+       }
 
        @Override
        public void 
exitIterablePredicateColonExpression(IterablePredicateColonExpressionContext 
ctx) {
@@ -706,23 +731,18 @@ public class DmlSyntacticValidator extends 
CommonSyntacticValidator implements D
 
 
        // -----------------------------------------------------------------
-       //                              Internal & External Functions 
Definitions
+       //            Internal & External Functions Definitions
        // -----------------------------------------------------------------
 
        @Override
        public void 
exitInternalFunctionDefExpression(InternalFunctionDefExpressionContext ctx) {
+               //populate function statement
                FunctionStatement functionStmt = new FunctionStatement();
-
-               ArrayList<DataIdentifier> functionInputs  = 
getFunctionParameters(ctx.inputParams);
-               functionStmt.setInputParams(functionInputs);
-
-               // set function outputs
-               ArrayList<DataIdentifier> functionOutputs = 
getFunctionParameters(ctx.outputParams);
-               functionStmt.setOutputParams(functionOutputs);
-
-               // set function name
                functionStmt.setName(ctx.name.getText());
-
+               
functionStmt.setInputParams(getFunctionParametersAssign(ctx.inputParams));
+               
functionStmt.setInputDefaults(getFunctionDefaults(ctx.inputParams));
+               
functionStmt.setOutputParams(getFunctionParametersNoAssign(ctx.outputParams));
+               
                if(ctx.body.size() > 0) {
                        // handle function body
                        // Create arraylist of one statement block
@@ -745,17 +765,11 @@ public class DmlSyntacticValidator extends 
CommonSyntacticValidator implements D
 
        @Override
        public void 
exitExternalFunctionDefExpression(ExternalFunctionDefExpressionContext ctx) {
+               //populate function statement
                ExternalFunctionStatement functionStmt = new 
ExternalFunctionStatement();
-
-               ArrayList<DataIdentifier> functionInputs  = 
getFunctionParameters(ctx.inputParams);
-               functionStmt.setInputParams(functionInputs);
-
-               // set function outputs
-               ArrayList<DataIdentifier> functionOutputs = 
getFunctionParameters(ctx.outputParams);
-               functionStmt.setOutputParams(functionOutputs);
-
-               // set function name
                functionStmt.setName(ctx.name.getText());
+               
functionStmt.setInputParams(getFunctionParametersNoAssign(ctx.inputParams));
+               
functionStmt.setOutputParams(getFunctionParametersNoAssign(ctx.outputParams));
 
                // set other parameters
                HashMap<String, String> otherParams = new HashMap<>();
@@ -949,6 +963,10 @@ public class DmlSyntacticValidator extends 
CommonSyntacticValidator implements D
 
        @Override public void exitTypedArgNoAssign(TypedArgNoAssignContext ctx) 
{}
 
+       @Override public void enterTypedArgAssign(TypedArgAssignContext ctx) {}
+
+       @Override public void exitTypedArgAssign(TypedArgAssignContext ctx) {}
+
        @Override public void 
enterStrictParameterizedExpression(StrictParameterizedExpressionContext ctx) {}
 
        @Override public void 
exitStrictParameterizedExpression(StrictParameterizedExpressionContext ctx) {}

http://git-wip-us.apache.org/repos/asf/systemml/blob/bfd49528/src/test/java/org/apache/sysml/test/integration/functions/misc/FunctionPotpourriTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/sysml/test/integration/functions/misc/FunctionPotpourriTest.java
 
b/src/test/java/org/apache/sysml/test/integration/functions/misc/FunctionPotpourriTest.java
index f1d2493..36ce70a 100644
--- 
a/src/test/java/org/apache/sysml/test/integration/functions/misc/FunctionPotpourriTest.java
+++ 
b/src/test/java/org/apache/sysml/test/integration/functions/misc/FunctionPotpourriTest.java
@@ -40,6 +40,10 @@ public class FunctionPotpourriTest extends AutomatedTestBase
        private final static String TEST_NAME10 = 
"FunPotpourriNamedArgsUnknown1";
        private final static String TEST_NAME11 = 
"FunPotpourriNamedArgsUnknown2";
        private final static String TEST_NAME12 = "FunPotpourriNamedArgsIPA";
+       private final static String TEST_NAME13 = 
"FunPotpourriDefaultArgScalar";
+       private final static String TEST_NAME14 = 
"FunPotpourriDefaultArgMatrix";
+       private final static String TEST_NAME15 = 
"FunPotpourriDefaultArgScalarMatrix1";
+       private final static String TEST_NAME16 = 
"FunPotpourriDefaultArgScalarMatrix2";
        
        private final static String TEST_DIR = "functions/misc/";
        private final static String TEST_CLASS_DIR = TEST_DIR + 
FunctionPotpourriTest.class.getSimpleName() + "/";
@@ -59,6 +63,10 @@ public class FunctionPotpourriTest extends AutomatedTestBase
                addTestConfiguration( TEST_NAME10, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME10, new String[] { "R" }) );
                addTestConfiguration( TEST_NAME11, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME11, new String[] { "R" }) );
                addTestConfiguration( TEST_NAME12, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME12, new String[] { "R" }) );
+               addTestConfiguration( TEST_NAME13, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME13, new String[] { "R" }) );
+               addTestConfiguration( TEST_NAME14, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME14, new String[] { "R" }) );
+               addTestConfiguration( TEST_NAME15, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME15, new String[] { "R" }) );
+               addTestConfiguration( TEST_NAME16, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME16, new String[] { "R" }) );
        }
 
        @Test
@@ -131,6 +139,26 @@ public class FunctionPotpourriTest extends 
AutomatedTestBase
                runFunctionTest( TEST_NAME12, false );
        }
        
+       @Test
+       public void testFunctionDefaultArgsScalar() {
+               runFunctionTest( TEST_NAME13, false );
+       }
+       
+       @Test
+       public void testFunctionDefaultArgsMatrix() {
+               runFunctionTest( TEST_NAME14, false );
+       }
+       
+       @Test
+       public void testFunctionDefaultArgsScalarMatrix1() {
+               runFunctionTest( TEST_NAME15, false );
+       }
+       
+       @Test
+       public void testFunctionDefaultArgsScalarMatrix2() {
+               runFunctionTest( TEST_NAME16, false );
+       }
+       
        private void runFunctionTest(String testName, boolean error) {
                TestConfiguration config = getTestConfiguration(testName);
                loadTestConfiguration(config);
@@ -141,6 +169,6 @@ public class FunctionPotpourriTest extends AutomatedTestBase
                        "-args", String.valueOf(error).toUpperCase()};
 
                //run script and compare output
-               runTest(true, error, DMLException.class, -1); 
+               runTest(true, error, DMLException.class, -1);
        }
 }

http://git-wip-us.apache.org/repos/asf/systemml/blob/bfd49528/src/test/scripts/functions/misc/FunPotpourriDefaultArgMatrix.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/misc/FunPotpourriDefaultArgMatrix.dml 
b/src/test/scripts/functions/misc/FunPotpourriDefaultArgMatrix.dml
new file mode 100644
index 0000000..cadef10
--- /dev/null
+++ b/src/test/scripts/functions/misc/FunPotpourriDefaultArgMatrix.dml
@@ -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.
+#
+#-------------------------------------------------------------
+
+foo1 = function(Matrix[Double] A = matrix(1,300,500), Matrix[Double] B) return 
(Matrix[Double] C) {
+  while(FALSE){} # no inlining
+  C = A %*% B + 7;
+}
+
+X2 = matrix(2, 500, 200)
+
+C = foo1(B=X2);
+
+print("out:  " + sum(C))

http://git-wip-us.apache.org/repos/asf/systemml/blob/bfd49528/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalar.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalar.dml 
b/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalar.dml
new file mode 100644
index 0000000..6bb6ad3
--- /dev/null
+++ b/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalar.dml
@@ -0,0 +1,39 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+foo1 = function(Matrix[Double] A, Matrix[Double] B, Double s = 7) return 
(Matrix[Double] C) {
+  while(FALSE){} # no inlining
+  C = A %*% B + s;
+}
+
+foo2 = function(Matrix[Double] A, Matrix[Double] B) return (Matrix[Double] C) {
+  while(FALSE){} # no inlining
+  C = A %*% B + 7;
+}
+
+X1 = matrix(1, 300, 500)
+X2 = matrix(2, 500, 200)
+
+C = foo1(B=X2, A=X1);
+D = foo2(X1, X2);
+
+if( sum(C!=D) > 0 )
+  print("ERROR: "+sum(C!=D)+" differences.")

http://git-wip-us.apache.org/repos/asf/systemml/blob/bfd49528/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalarMatrix1.dml
----------------------------------------------------------------------
diff --git 
a/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalarMatrix1.dml 
b/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalarMatrix1.dml
new file mode 100644
index 0000000..c44f3ef
--- /dev/null
+++ b/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalarMatrix1.dml
@@ -0,0 +1,39 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+foo1 = function(Matrix[Double] A=matrix(1, 300, 500), Matrix[Double] B, Double 
s = 7) return (Matrix[Double] C) {
+  while(FALSE){} # no inlining
+  C = A %*% B + s;
+}
+
+foo2 = function(Matrix[Double] A, Matrix[Double] B) return (Matrix[Double] C) {
+  while(FALSE}{) # no inlining
+  C = A %*% B + 7;
+}
+
+X1 = matrix(1, 300, 500)
+X2 = matrix(2, 500, 200)
+
+C = foo1(B=X2);
+D = foo2(X1, X2);
+
+if( sum(C!=D) > 0 )
+  print("ERROR: "+sum(C!=D)+" differences.")

http://git-wip-us.apache.org/repos/asf/systemml/blob/bfd49528/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalarMatrix2.dml
----------------------------------------------------------------------
diff --git 
a/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalarMatrix2.dml 
b/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalarMatrix2.dml
new file mode 100644
index 0000000..d565a97
--- /dev/null
+++ b/src/test/scripts/functions/misc/FunPotpourriDefaultArgScalarMatrix2.dml
@@ -0,0 +1,43 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+foo1 = function(Matrix[Double] A=matrix(1, 300, 500), Matrix[Double] B, Double 
s = 7) return (Matrix[Double] C, Matrix[Double] D) {
+  while(FALSE){} # no inlining
+  C = A %*% B + s;
+  D = C + 7;
+}
+
+foo2 = function(Matrix[Double] A, Matrix[Double] B) return (Matrix[Double] C, 
Matrix[Double] D) {
+  while(FALSE}{) # no inlining
+  C = A %*% B + 7;
+  D = C + 7;
+}
+
+X1 = matrix(1, 300, 500)
+X2 = matrix(2, 500, 200)
+
+[C1,C2] = foo1(B=X2);
+[D1,D2] = foo2(X1, X2);
+
+if( sum(C1!=D1) > 0 )
+  print("ERROR1: "+sum(C1!=D1)+" differences.")
+if( sum(C2!=D2) > 0 )
+  print("ERROR2: "+sum(C2!=D2)+" differences.")

Reply via email to