[SYSTEMML-2077] New second-order eval builtin function

Closes #740.


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

Branch: refs/heads/master
Commit: 2af84960095b2648f10b5a211ad849b3e6366fef
Parents: 2cee9bb
Author: EdgarLGB <[email protected]>
Authored: Thu Mar 8 22:49:42 2018 -0800
Committer: Matthias Boehm <[email protected]>
Committed: Thu Mar 8 23:58:08 2018 -0800

----------------------------------------------------------------------
 src/main/java/org/apache/sysml/hops/Hop.java    |  3 +-
 src/main/java/org/apache/sysml/hops/NaryOp.java |  3 +-
 .../sysml/hops/ipa/InterProceduralAnalysis.java |  2 +-
 src/main/java/org/apache/sysml/lops/Nary.java   |  3 +-
 .../sysml/parser/BuiltinFunctionExpression.java | 13 +++
 .../org/apache/sysml/parser/DMLTranslator.java  |  4 +
 .../org/apache/sysml/parser/Expression.java     |  1 +
 .../sysml/parser/dml/DmlSyntacticValidator.java |  9 +-
 .../sysml/runtime/functionobjects/Builtin.java  |  3 +-
 .../instructions/CPInstructionParser.java       |  3 +-
 .../cp/BuiltinNaryCPInstruction.java            |  3 +
 .../instructions/cp/EvalNaryCPInstruction.java  | 87 ++++++++++++++++++++
 .../cp/FunctionCallCPInstruction.java           |  2 +-
 .../integration/mlcontext/MLContextTest.java    |  8 ++
 .../apache/sysml/api/mlcontext/eval-test.dml    | 55 +++++++++++++
 15 files changed, 187 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/hops/Hop.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/Hop.java 
b/src/main/java/org/apache/sysml/hops/Hop.java
index 8b917b4..78c0687 100644
--- a/src/main/java/org/apache/sysml/hops/Hop.java
+++ b/src/main/java/org/apache/sysml/hops/Hop.java
@@ -1099,7 +1099,7 @@ public abstract class Hop implements ParseInfo
        
        // Operations that require a variable number of operands
        public enum OpOpN {
-               PRINTF, CBIND, RBIND,
+               PRINTF, CBIND, RBIND, EVAL
        }
        
        public enum AggOp {
@@ -1383,6 +1383,7 @@ public abstract class Hop implements ParseInfo
                HopsOpOpNLops.put(OpOpN.PRINTF, Nary.OperationType.PRINTF);
                HopsOpOpNLops.put(OpOpN.CBIND, Nary.OperationType.CBIND);
                HopsOpOpNLops.put(OpOpN.RBIND, Nary.OperationType.RBIND);
+               HopsOpOpNLops.put(OpOpN.EVAL, Nary.OperationType.EVAL);
        }
 
        protected static final HashMap<Hop.OpOp1, String> HopsOpOp12String;

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/hops/NaryOp.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/NaryOp.java 
b/src/main/java/org/apache/sysml/hops/NaryOp.java
index bc3b163..1a6da2e 100644
--- a/src/main/java/org/apache/sysml/hops/NaryOp.java
+++ b/src/main/java/org/apache/sysml/hops/NaryOp.java
@@ -159,7 +159,7 @@ public class NaryOp extends Hop {
                setRequiresRecompileIfNecessary();
                
                //ensure cp exec type for single-node operations
-               if ( _op == OpOpN.PRINTF )
+               if ( _op == OpOpN.PRINTF  || _op == OpOpN.EVAL)
                        _etype = ExecType.CP;
                
                return _etype;
@@ -187,6 +187,7 @@ public class NaryOp extends Hop {
                                setDim2(HopRewriteUtils.getMaxInputDim(this, 
false));
                                break;
                        case PRINTF:
+                       case EVAL:
                                //do nothing:
                }
        }

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/hops/ipa/InterProceduralAnalysis.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/hops/ipa/InterProceduralAnalysis.java 
b/src/main/java/org/apache/sysml/hops/ipa/InterProceduralAnalysis.java
index 3ec5f6a..6a5788e 100644
--- a/src/main/java/org/apache/sysml/hops/ipa/InterProceduralAnalysis.java
+++ b/src/main/java/org/apache/sysml/hops/ipa/InterProceduralAnalysis.java
@@ -89,7 +89,7 @@ public class InterProceduralAnalysis
        protected static final boolean INTRA_PROCEDURAL_ANALYSIS      = true; 
//propagate statistics across statement blocks (main/functions)   
        protected static final boolean PROPAGATE_KNOWN_UDF_STATISTICS = true; 
//propagate statistics for known external functions 
        protected static final boolean ALLOW_MULTIPLE_FUNCTION_CALLS  = true; 
//propagate consistent statistics from multiple calls 
-       protected static final boolean REMOVE_UNUSED_FUNCTIONS        = true; 
//remove unused functions (inlined or never called)
+       protected static final boolean REMOVE_UNUSED_FUNCTIONS        = false; 
//remove unused functions (inlined or never called)
        protected static final boolean FLAG_FUNCTION_RECOMPILE_ONCE   = true; 
//flag functions which require recompilation inside a loop for full function 
recompile
        protected static final boolean REMOVE_UNNECESSARY_CHECKPOINTS = true; 
//remove unnecessary checkpoints (unconditionally overwritten intermediates) 
        protected static final boolean REMOVE_CONSTANT_BINARY_OPS     = true; 
//remove constant binary operations (e.g., X*ones, where ones=matrix(1,...)) 

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/lops/Nary.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/lops/Nary.java 
b/src/main/java/org/apache/sysml/lops/Nary.java
index 90966fa..7df863a 100644
--- a/src/main/java/org/apache/sysml/lops/Nary.java
+++ b/src/main/java/org/apache/sysml/lops/Nary.java
@@ -32,7 +32,7 @@ import org.apache.sysml.parser.Expression.ValueType;
 public class Nary extends Lop {
 
        public enum OperationType {
-               PRINTF, CBIND, RBIND,
+               PRINTF, CBIND, RBIND, EVAL
        }
        
        private OperationType operationType;
@@ -119,6 +119,7 @@ public class Nary extends Lop {
                        case PRINTF:
                        case CBIND:
                        case RBIND:
+                       case EVAL:
                                return operationType.name().toLowerCase();
                        default:
                                throw new UnsupportedOperationException(

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java 
b/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java
index a79a522..880b698 100644
--- a/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java
+++ b/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 
 import org.antlr.v4.runtime.ParserRuleContext;
+import org.apache.sysml.conf.ConfigurationManager;
 import org.apache.sysml.parser.LanguageException.LanguageErrorCodes;
 import org.apache.sysml.runtime.util.ConvolutionUtils;
 import org.apache.sysml.runtime.util.UtilFunctions;
@@ -379,6 +380,15 @@ public class BuiltinFunctionExpression extends 
DataIdentifier
                this.setOutput(output);
                
                switch (this.getOpCode()) {
+               case EVAL:
+                       if (_args.length == 0)
+                               raiseValidateError("Function eval should 
provide at least one argument, i.e., the function name.", false);
+                       checkValueTypeParam(_args[0], ValueType.STRING);
+                       output.setDataType(DataType.MATRIX);
+                       output.setValueType(ValueType.DOUBLE);
+                       
output.setBlockDimensions(ConfigurationManager.getBlocksize(),
+                               ConfigurationManager.getBlocksize());
+                       break;
                case COLSUM:
                case COLMAX:
                case COLMIN:
@@ -1792,6 +1802,9 @@ public class BuiltinFunctionExpression extends 
DataIdentifier
                        bifop = Expression.BuiltinFunctionOp.BITWSHIFTR;
                else if ( functionName.equals("ifelse") )
                        bifop = Expression.BuiltinFunctionOp.IFELSE;
+               else if (functionName.equals("eval")) {
+                       bifop = Expression.BuiltinFunctionOp.EVAL;
+               }
                else
                        return null;
                

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/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 2bcdde1..220be8a 100644
--- a/src/main/java/org/apache/sysml/parser/DMLTranslator.java
+++ b/src/main/java/org/apache/sysml/parser/DMLTranslator.java
@@ -2381,6 +2381,10 @@ public class DMLTranslator
                // Construct the hop based on the type of Builtin function
                switch (source.getOpCode()) {
 
+               case EVAL:
+                       currBuiltinOp = new NaryOp(target.getName(), 
target.getDataType(), target.getValueType(), OpOpN.EVAL, 
processAllExpressions(source.getAllExpr(), hops));
+                       break;
+
                case COLSUM:
                        currBuiltinOp = new AggUnaryOp(target.getName(), 
target.getDataType(), target.getValueType(), AggOp.SUM,
                                        Direction.Col, expr);

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/parser/Expression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/parser/Expression.java 
b/src/main/java/org/apache/sysml/parser/Expression.java
index ffffb36..ac30657 100644
--- a/src/main/java/org/apache/sysml/parser/Expression.java
+++ b/src/main/java/org/apache/sysml/parser/Expression.java
@@ -86,6 +86,7 @@ public abstract class Expression implements ParseInfo
                CUMSUM,
                DIAG,
                EIGEN,
+               EVAL,
                CONV2D, CONV2D_BACKWARD_FILTER, CONV2D_BACKWARD_DATA, BIAS_ADD, 
BIAS_MULTIPLY,
                MAX_POOL, AVG_POOL, MAX_POOL_BACKWARD, AVG_POOL_BACKWARD,
                EXP,

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/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 a5169fb..c440be4 100644
--- a/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java
+++ b/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java
@@ -119,7 +119,7 @@ public class DmlSyntacticValidator extends 
CommonSyntacticValidator implements D
        public DmlSyntacticValidator(CustomErrorListener errorListener, 
Map<String,String> argVals, String sourceNamespace, Set<String> prepFunctions) {
                super(errorListener, argVals, sourceNamespace, prepFunctions);
        }
-       
+
        @Override public String namespaceResolutionOp() { return "::"; }
        @Override public String trueStringLiteral() { return "TRUE"; }
        @Override public String falseStringLiteral() { return "FALSE"; }
@@ -492,9 +492,9 @@ public class DmlSyntacticValidator extends 
CommonSyntacticValidator implements D
                String namespace = fnNames[0];
                String functionName = fnNames[1];
                ArrayList<ParameterExpression> paramExpression = 
getParameterExpressionList(ctx.paramExprs);
-               
+
                castAsScalarDeprecationCheck(functionName, ctx);
-               
+
                boolean hasLHS = ctx.targetList != null;
                functionCallAssignmentStatementHelper(ctx, printStatements, 
outputStatements, hasLHS ? ctx.targetList.dataInfo.expr : null, ctx.info, 
ctx.name,
                                hasLHS ? ctx.targetList.start : null, 
namespace, functionName, paramExpression, hasLHS);
@@ -519,7 +519,6 @@ public class DmlSyntacticValidator extends 
CommonSyntacticValidator implements D
                String functionName = names[1];
 
                ArrayList<ParameterExpression> paramExpression = 
getParameterExpressionList(ctx.paramExprs);
-
                castAsScalarDeprecationCheck(functionName, ctx);
 
                ConvertedDMLSyntax convertedSyntax = convertToDMLSyntax(ctx, 
namespace, functionName, paramExpression, ctx.name);
@@ -714,7 +713,7 @@ public class DmlSyntacticValidator extends 
CommonSyntacticValidator implements D
                                dataType = 
paramCtx.paramType.dataType().getText();
                        }
 
-                       
+
                        //check and assign data type
                        checkValidDataType(dataType, paramCtx.start);
                        if( dataType.equalsIgnoreCase("matrix") )

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java 
b/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
index 41cb709..ef0a6c0 100644
--- a/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
+++ b/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
@@ -51,7 +51,7 @@ public class Builtin extends ValueFunction
        
        public enum BuiltinCode { SIN, COS, TAN, SINH, COSH, TANH, ASIN, ACOS, 
ATAN, LOG, LOG_NZ, MIN,
                MAX, ABS, SIGN, SQRT, EXP, PLOGP, PRINT, PRINTF, NROW, NCOL, 
LENGTH, ROUND, MAXINDEX, MININDEX,
-               STOP, CEIL, FLOOR, CUMSUM, CUMPROD, CUMMIN, CUMMAX, INVERSE, 
SPROP, SIGMOID }
+               STOP, CEIL, FLOOR, CUMSUM, CUMPROD, CUMMIN, CUMMAX, INVERSE, 
SPROP, SIGMOID, EVAL }
        public BuiltinCode bFunc;
        
        private static final boolean FASTMATH = true;
@@ -81,6 +81,7 @@ public class Builtin extends ValueFunction
                String2BuiltinCode.put( "plogp"  , BuiltinCode.PLOGP);
                String2BuiltinCode.put( "print"  , BuiltinCode.PRINT);
                String2BuiltinCode.put( "printf"  , BuiltinCode.PRINTF);
+               String2BuiltinCode.put( "eval"  , BuiltinCode.EVAL);
                String2BuiltinCode.put( "nrow"   , BuiltinCode.NROW);
                String2BuiltinCode.put( "ncol"   , BuiltinCode.NCOL);
                String2BuiltinCode.put( "length" , BuiltinCode.LENGTH);

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java 
b/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java
index de8deea..43b3895 100644
--- 
a/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java
+++ 
b/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java
@@ -182,7 +182,8 @@ public class CPInstructionParser extends InstructionParser
                String2CPInstructionType.put( "printf" , CPType.BuiltinNary);
                String2CPInstructionType.put( "cbind" , CPType.BuiltinNary);
                String2CPInstructionType.put( "rbind" , CPType.BuiltinNary);
-               
+               String2CPInstructionType.put( "eval" , CPType.BuiltinNary);
+
                // Parameterized Builtin Functions
                String2CPInstructionType.put( "cdf"                     , 
CPType.ParameterizedBuiltin);
                String2CPInstructionType.put( "invcdf"          , 
CPType.ParameterizedBuiltin);

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/runtime/instructions/cp/BuiltinNaryCPInstruction.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/instructions/cp/BuiltinNaryCPInstruction.java
 
b/src/main/java/org/apache/sysml/runtime/instructions/cp/BuiltinNaryCPInstruction.java
index 1ed6055..e38fc0b 100644
--- 
a/src/main/java/org/apache/sysml/runtime/instructions/cp/BuiltinNaryCPInstruction.java
+++ 
b/src/main/java/org/apache/sysml/runtime/instructions/cp/BuiltinNaryCPInstruction.java
@@ -66,6 +66,9 @@ public abstract class BuiltinNaryCPInstruction extends 
CPInstruction
                else if( opcode.equals("cbind") || opcode.equals("rbind") ) {
                        return new MatrixBuiltinNaryCPInstruction(null, 
                                        opcode, str, outputOperand, 
inputOperands);
+               } 
+               else if 
(Nary.OperationType.EVAL.name().equalsIgnoreCase(opcode)) {
+                       return new EvalNaryCPInstruction(null, opcode, str, 
outputOperand, inputOperands);
                }
                
                throw new DMLRuntimeException("Opcode (" + opcode + ") not 
recognized in BuiltinMultipleCPInstruction");

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/runtime/instructions/cp/EvalNaryCPInstruction.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/instructions/cp/EvalNaryCPInstruction.java
 
b/src/main/java/org/apache/sysml/runtime/instructions/cp/EvalNaryCPInstruction.java
new file mode 100644
index 0000000..39f9755
--- /dev/null
+++ 
b/src/main/java/org/apache/sysml/runtime/instructions/cp/EvalNaryCPInstruction.java
@@ -0,0 +1,87 @@
+/*
+ * 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.runtime.instructions.cp;
+
+import org.apache.sysml.runtime.DMLRuntimeException;
+import org.apache.sysml.runtime.controlprogram.Program;
+import org.apache.sysml.runtime.controlprogram.caching.FrameObject;
+import org.apache.sysml.runtime.controlprogram.caching.MatrixObject;
+import org.apache.sysml.runtime.controlprogram.context.ExecutionContext;
+import org.apache.sysml.runtime.matrix.data.MatrixBlock;
+import org.apache.sysml.runtime.matrix.operators.Operator;
+import org.apache.sysml.runtime.util.DataConverter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Eval built-in function instruction
+ * Note: it supports only single matrix[double] output
+ */
+public class EvalNaryCPInstruction extends BuiltinNaryCPInstruction {
+
+       public EvalNaryCPInstruction(Operator op, String opcode, String istr, 
CPOperand output, CPOperand... inputs) {
+               super(op, opcode, istr, output, inputs);
+       }
+
+       @Override
+       public void processInstruction(ExecutionContext ec) throws 
DMLRuntimeException {
+               //1. get the namespace and func
+               String funcName = ec.getScalarInput(inputs[0]).getStringValue();
+               if( funcName.contains(Program.KEY_DELIM) )
+                       throw new DMLRuntimeException("Eval calls to 
'"+funcName+"', i.e., a function outside "
+                               + "the default "+ "namespace, are not supported 
yet. Please call the function directly.");
+               
+               // bound the inputs to avoiding being deleted after the 
function call
+               CPOperand[] boundInputs = Arrays.copyOfRange(inputs, 1, 
inputs.length);
+               ArrayList<String> boundOutputNames = new ArrayList<>();
+               boundOutputNames.add(output.getName());
+               ArrayList<String> boundInputNames = new ArrayList<>();
+               for (CPOperand input : boundInputs) {
+                       boundInputNames.add(input.getName());
+               }
+
+               //2. copy the created output matrix
+               MatrixObject outputMO = new 
MatrixObject(ec.getMatrixObject(output.getName()));
+
+               //3. call the function
+               FunctionCallCPInstruction fcpi = new FunctionCallCPInstruction(
+                       null, funcName, boundInputs, boundInputNames, 
boundOutputNames, "eval func");
+               fcpi.processInstruction(ec);
+
+               //4. convert the result to matrix
+               Data newOutput = ec.getVariable(output);
+               if (newOutput instanceof MatrixObject) {
+                       return;
+               }
+               MatrixBlock mb = null;
+               if (newOutput instanceof ScalarObject) {
+                       //convert scalar to matrix
+                       mb = new MatrixBlock(((ScalarObject) 
newOutput).getDoubleValue());
+               } else if (newOutput instanceof FrameObject) {
+                       //convert frame to matrix
+                       mb = DataConverter.convertToMatrixBlock(((FrameObject) 
newOutput).acquireRead());
+                       ec.cleanupCacheableData((FrameObject) newOutput);
+               }
+               outputMO.acquireModify(mb);
+               outputMO.release();
+               ec.setVariable(output.getName(), outputMO);
+       }
+}

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java
 
b/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java
index 953c365..eb44f81 100644
--- 
a/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java
+++ 
b/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java
@@ -45,7 +45,7 @@ public class FunctionCallCPInstruction extends CPInstruction {
        private final ArrayList<String> _boundInputNames;
        private final ArrayList<String> _boundOutputNames;
 
-       private FunctionCallCPInstruction(String namespace, String functName, 
CPOperand[] boundInputs, 
+       public FunctionCallCPInstruction(String namespace, String functName, 
CPOperand[] boundInputs,
                ArrayList<String> boundInputNames, ArrayList<String> 
boundOutputNames, String istr) {
                super(CPType.External, null, functName, istr);
                _functionName = functName;

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/test/java/org/apache/sysml/test/integration/mlcontext/MLContextTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/sysml/test/integration/mlcontext/MLContextTest.java 
b/src/test/java/org/apache/sysml/test/integration/mlcontext/MLContextTest.java
index 6dc3053..e70faa9 100644
--- 
a/src/test/java/org/apache/sysml/test/integration/mlcontext/MLContextTest.java
+++ 
b/src/test/java/org/apache/sysml/test/integration/mlcontext/MLContextTest.java
@@ -89,6 +89,14 @@ import scala.collection.Seq;
 public class MLContextTest extends MLContextTestBase {
 
        @Test
+       public void testCreateDMLScriptBasedOnFileAndExecuteEvalTest() {
+               System.out.println("MLContextTest - create DML script based on 
file and execute");
+               setExpectedStdOut("10");
+               Script script = dmlFromFile(baseDirectory + File.separator + 
"eval-test.dml");
+               ml.execute(script);
+       }
+
+       @Test
        public void testCreateDMLScriptBasedOnStringAndExecute() {
                System.out.println("MLContextTest - create DML script based on 
string and execute");
                String testString = "Create DML script based on string and 
execute";

http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/test/scripts/org/apache/sysml/api/mlcontext/eval-test.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/org/apache/sysml/api/mlcontext/eval-test.dml 
b/src/test/scripts/org/apache/sysml/api/mlcontext/eval-test.dml
new file mode 100644
index 0000000..7637c55
--- /dev/null
+++ b/src/test/scripts/org/apache/sysml/api/mlcontext/eval-test.dml
@@ -0,0 +1,55 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+# product between matrix and scalar
+f1 = function (matrix[double] M, double factor) return (double res) {
+  res = prod(M) * factor
+}
+
+# replace the matrix with a scalar and then use calculate the product
+f2 = function (matrix[double] M, double r) return (double res) {
+  R = replace(target=M, pattern=1, replacement=r)
+  res = f1(R, 10)
+}
+
+# production of two matrix
+f3 = function (matrix[double] M1, matrix[double] M2) return (matrix[double] 
res) {
+  res = M1 %*% M2
+}
+
+f4 = function (matrix[double] M1, matrix[double] M2) return (matrix[double] 
res) {
+  res = M1 %*% M2
+}
+
+# some variables
+X = matrix("1 2 3 4", rows=2, cols=2)
+y = 10
+
+R1 = eval("f1", X, y)
+R2 = eval("f2", X, y)
+R3 = eval("f3", X, X)
+for(i in 3:4)
+  R4 = eval("f"+i, X, X);
+
+print(toString(R1))
+print(toString(R2))
+print(toString(R3))
+print(toString(R4))

Reply via email to