[SYSTEMML-2308,2310] New dynamic structs via named lists, incl rix Following the introduction of list data types as a handle for arbitrary data objects, this patch now introduced dynamic structs implemented via named lists. Specifically, this allows the named compositions such as X = list(a=M1, b=M2, c=7, d=M4) and indexing operations such as X[2] or X['d'], i.e., with associative indexing by name. We also support range based indexing such as X[1:4] or X['a':'d'] where the order and thus value range is defined by the specification order on construction.
Project: http://git-wip-us.apache.org/repos/asf/systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/f9020a16 Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/f9020a16 Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/f9020a16 Branch: refs/heads/master Commit: f9020a169b6291d18b3baa29eab7f5051bd2edf5 Parents: fa6394c Author: Matthias Boehm <[email protected]> Authored: Wed May 9 23:07:47 2018 -0700 Committer: Matthias Boehm <[email protected]> Committed: Thu May 10 12:28:48 2018 -0700 ---------------------------------------------------------------------- src/main/java/org/apache/sysml/hops/Hop.java | 28 +++++++------ .../sysml/hops/ParameterizedBuiltinOp.java | 21 ++++++---- .../apache/sysml/hops/recompile/Recompiler.java | 2 +- .../sysml/hops/rewrite/HopRewriteUtils.java | 3 +- .../RewriteAlgebraicSimplificationDynamic.java | 7 ++-- .../RewriteAlgebraicSimplificationStatic.java | 7 ++-- .../apache/sysml/lops/ParameterizedBuiltin.java | 18 ++++++--- .../sysml/parser/BuiltinFunctionExpression.java | 5 ++- .../org/apache/sysml/parser/DMLTranslator.java | 10 ++++- .../org/apache/sysml/parser/Expression.java | 3 +- .../org/apache/sysml/parser/Identifier.java | 34 +++++++--------- .../ParameterizedBuiltinFunctionExpression.java | 35 +++++++++++----- .../instructions/CPInstructionParser.java | 1 + .../cp/ListIndexingCPInstruction.java | 15 +++++-- .../runtime/instructions/cp/ListObject.java | 23 ++++++++++- .../cp/ParameterizedBuiltinCPInstruction.java | 36 ++++++++++++----- .../cp/ScalarBuiltinNaryCPInstruction.java | 2 +- .../functions/misc/ListAndStructTest.java | 18 ++++----- src/test/scripts/functions/misc/ListNamed.R | 42 ++++++++++++++++++++ src/test/scripts/functions/misc/ListNamed.dml | 38 ++++++++++++++++++ 20 files changed, 254 insertions(+), 94 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/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 bd906b5..a42b7ab 100644 --- a/src/main/java/org/apache/sysml/hops/Hop.java +++ b/src/main/java/org/apache/sysml/hops/Hop.java @@ -44,6 +44,7 @@ import org.apache.sysml.lops.ReBlock; import org.apache.sysml.lops.Ternary; import org.apache.sysml.lops.Unary; import org.apache.sysml.lops.UnaryCP; +import org.apache.sysml.lops.ParameterizedBuiltin; import org.apache.sysml.parser.Expression.DataType; import org.apache.sysml.parser.Expression.ValueType; import org.apache.sysml.parser.ParseInfo; @@ -1116,7 +1117,7 @@ public abstract class Hop implements ParseInfo INVALID, CDF, INVCDF, GROUPEDAGG, RMEMPTY, REPLACE, REXPAND, LOWER_TRI, UPPER_TRI, TRANSFORMAPPLY, TRANSFORMDECODE, TRANSFORMCOLMAP, TRANSFORMMETA, - TOSTRING + TOSTRING, LIST, } public enum FileFormatTypes { @@ -1414,18 +1415,19 @@ public abstract class Hop implements ParseInfo protected static final HashMap<Hop.ParamBuiltinOp, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes> HopsParameterizedBuiltinLops; static { HopsParameterizedBuiltinLops = new HashMap<>(); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.CDF, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.CDF); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.INVCDF, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.INVCDF); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.RMEMPTY, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.RMEMPTY); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.REPLACE, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.REPLACE); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.REXPAND, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.REXPAND); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.LOWER_TRI, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.LOWER_TRI); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.UPPER_TRI, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.UPPER_TRI); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.TRANSFORMAPPLY, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.TRANSFORMAPPLY); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.TRANSFORMDECODE, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.TRANSFORMDECODE); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.TRANSFORMCOLMAP, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.TRANSFORMCOLMAP); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.TRANSFORMMETA, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.TRANSFORMMETA); - HopsParameterizedBuiltinLops.put(ParamBuiltinOp.TOSTRING, org.apache.sysml.lops.ParameterizedBuiltin.OperationTypes.TOSTRING); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.CDF, ParameterizedBuiltin.OperationTypes.CDF); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.INVCDF, ParameterizedBuiltin.OperationTypes.INVCDF); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.RMEMPTY, ParameterizedBuiltin.OperationTypes.RMEMPTY); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.REPLACE, ParameterizedBuiltin.OperationTypes.REPLACE); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.REXPAND, ParameterizedBuiltin.OperationTypes.REXPAND); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.LOWER_TRI, ParameterizedBuiltin.OperationTypes.LOWER_TRI); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.UPPER_TRI, ParameterizedBuiltin.OperationTypes.UPPER_TRI); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.TRANSFORMAPPLY, ParameterizedBuiltin.OperationTypes.TRANSFORMAPPLY); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.TRANSFORMDECODE, ParameterizedBuiltin.OperationTypes.TRANSFORMDECODE); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.TRANSFORMCOLMAP, ParameterizedBuiltin.OperationTypes.TRANSFORMCOLMAP); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.TRANSFORMMETA, ParameterizedBuiltin.OperationTypes.TRANSFORMMETA); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.TOSTRING, ParameterizedBuiltin.OperationTypes.TOSTRING); + HopsParameterizedBuiltinLops.put(ParamBuiltinOp.LIST, ParameterizedBuiltin.OperationTypes.LIST); } protected static final HashMap<Hop.OpOp2, String> HopsOpOp2String; http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/hops/ParameterizedBuiltinOp.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/ParameterizedBuiltinOp.java b/src/main/java/org/apache/sysml/hops/ParameterizedBuiltinOp.java index b94ff5c..e287b20 100644 --- a/src/main/java/org/apache/sysml/hops/ParameterizedBuiltinOp.java +++ b/src/main/java/org/apache/sysml/hops/ParameterizedBuiltinOp.java @@ -20,6 +20,7 @@ package org.apache.sysml.hops; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map.Entry; import org.apache.sysml.hops.Hop.MultiThreadedHop; @@ -87,7 +88,7 @@ public class ParameterizedBuiltinOp extends Hop implements MultiThreadedHop * @param inputParameters map of input parameters */ public ParameterizedBuiltinOp(String l, DataType dt, ValueType vt, - ParamBuiltinOp op, HashMap<String, Hop> inputParameters) { + ParamBuiltinOp op, LinkedHashMap<String, Hop> inputParameters) { super(l, dt, vt); _op = op; @@ -191,10 +192,11 @@ public class ParameterizedBuiltinOp extends Hop implements MultiThreadedHop case TRANSFORMDECODE: case TRANSFORMCOLMAP: case TRANSFORMMETA: - case TOSTRING: { + case TOSTRING: + case LIST: { ExecType et = optFindExecType(); ParameterizedBuiltin pbilop = new ParameterizedBuiltin(inputlops, - HopsParameterizedBuiltinLops.get(_op), getDataType(), getValueType(), et); + HopsParameterizedBuiltinLops.get(_op), getDataType(), getValueType(), et); setOutputDimensions(pbilop); setLineNumbers(pbilop); setLops(pbilop); @@ -1064,11 +1066,9 @@ public class ParameterizedBuiltinOp extends Hop implements MultiThreadedHop //force CP for in-memory only transform builtins if( (_op == ParamBuiltinOp.TRANSFORMAPPLY && REMOTE==ExecType.MR) || _op == ParamBuiltinOp.TRANSFORMDECODE && REMOTE==ExecType.MR - || _op == ParamBuiltinOp.TRANSFORMCOLMAP - || _op == ParamBuiltinOp.TRANSFORMMETA - || _op == ParamBuiltinOp.TOSTRING - || _op == ParamBuiltinOp.CDF - || _op == ParamBuiltinOp.INVCDF) { + || _op == ParamBuiltinOp.TRANSFORMCOLMAP || _op == ParamBuiltinOp.TRANSFORMMETA + || _op == ParamBuiltinOp.TOSTRING || _op == ParamBuiltinOp.LIST + || _op == ParamBuiltinOp.CDF || _op == ParamBuiltinOp.INVCDF) { _etype = ExecType.CP; } @@ -1176,6 +1176,11 @@ public class ParameterizedBuiltinOp extends Hop implements MultiThreadedHop setDim2( 3 ); //fixed schema break; } + case LIST: { + setDim1( getInput().size() ); + setDim2(1); + break; + } default: //do nothing break; http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java b/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java index 2cfeada..fe69b49 100644 --- a/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java +++ b/src/main/java/org/apache/sysml/hops/recompile/Recompiler.java @@ -1373,7 +1373,7 @@ public class Recompiler updatedSizeExpr = initUnknown & d.dimsKnown(); } //update size expression for indexing according to symbol table entries - else if( hop instanceof IndexingOp ) + else if( hop instanceof IndexingOp && hop.getDataType()!=DataType.LIST ) { IndexingOp iop = (IndexingOp)hop; Hop input2 = iop.getInput().get(1); //inpRowL http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/hops/rewrite/HopRewriteUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/rewrite/HopRewriteUtils.java b/src/main/java/org/apache/sysml/hops/rewrite/HopRewriteUtils.java index 3a0c3f2..6da1b7a 100644 --- a/src/main/java/org/apache/sysml/hops/rewrite/HopRewriteUtils.java +++ b/src/main/java/org/apache/sysml/hops/rewrite/HopRewriteUtils.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import org.apache.commons.lang.ArrayUtils; import org.apache.sysml.api.DMLScript; @@ -618,7 +619,7 @@ public class HopRewriteUtils return mmult; } - public static ParameterizedBuiltinOp createParameterizedBuiltinOp(Hop input, HashMap<String,Hop> args, ParamBuiltinOp op) { + public static ParameterizedBuiltinOp createParameterizedBuiltinOp(Hop input, LinkedHashMap<String,Hop> args, ParamBuiltinOp op) { ParameterizedBuiltinOp pbop = new ParameterizedBuiltinOp("tmp", DataType.MATRIX, ValueType.DOUBLE, op, args); pbop.setOutputBlocksizes(input.getRowsInBlock(), input.getColsInBlock()); copyLineNumbers(input, pbop); http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java b/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java index 545ffd8..81c20e0 100644 --- a/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java +++ b/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java @@ -21,6 +21,7 @@ package org.apache.sysml.hops.rewrite; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -2542,7 +2543,7 @@ public class RewriteAlgebraicSimplificationDynamic extends HopRewriteRule && HopRewriteUtils.isSizeExpressionOf(hi.getInput().get(3), second, true) ) { //setup input parameter hops - HashMap<String,Hop> args = new HashMap<>(); + LinkedHashMap<String,Hop> args = new LinkedHashMap<>(); args.put("target", second); args.put("max", hi.getInput().get(4)); args.put("dir", new LiteralOp("cols")); @@ -2563,7 +2564,7 @@ public class RewriteAlgebraicSimplificationDynamic extends HopRewriteRule && HopRewriteUtils.isSizeExpressionOf(hi.getInput().get(4), first, true) ) { //setup input parameter hops - HashMap<String,Hop> args = new HashMap<>(); + LinkedHashMap<String,Hop> args = new LinkedHashMap<>(); args.put("target", first); args.put("max", hi.getInput().get(3)); args.put("dir", new LiteralOp("rows")); @@ -2572,7 +2573,7 @@ public class RewriteAlgebraicSimplificationDynamic extends HopRewriteRule //create new hop ParameterizedBuiltinOp pbop = HopRewriteUtils - .createParameterizedBuiltinOp(first, args, ParamBuiltinOp.REXPAND); + .createParameterizedBuiltinOp(first, args, ParamBuiltinOp.REXPAND); HopRewriteUtils.replaceChildReference(parent, hi, pbop, pos); HopRewriteUtils.cleanupUnreferenced(hi); hi = pbop; http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationStatic.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationStatic.java b/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationStatic.java index 4eb223d..db28a18 100644 --- a/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationStatic.java +++ b/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationStatic.java @@ -21,6 +21,7 @@ package org.apache.sysml.hops.rewrite; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import org.apache.commons.logging.Log; @@ -1568,7 +1569,7 @@ public class RewriteAlgebraicSimplificationStatic extends HopRewriteRule && HopRewriteUtils.isBinaryMatrixScalar(hi.getInput().get(1).getInput().get(0), OpOp2.EQUAL, 0) && hi.getInput().get(1).getInput().get(0).getInput().contains(hi.getInput().get(0)) ) { - HashMap<String, Hop> args = new HashMap<>(); + LinkedHashMap<String, Hop> args = new LinkedHashMap<>(); args.put("target", hi.getInput().get(0)); args.put("pattern", new LiteralOp(0)); args.put("replacement", hi.getInput().get(1).getInput().get(1)); @@ -1785,7 +1786,7 @@ public class RewriteAlgebraicSimplificationStatic extends HopRewriteRule String direction = HopRewriteUtils.isBasic1NSequence(hi.getInput().get(0)) ? "rows" : "cols"; //setup input parameter hops - HashMap<String,Hop> inputargs = new HashMap<>(); + LinkedHashMap<String,Hop> inputargs = new LinkedHashMap<>(); inputargs.put("target", trgt); inputargs.put("max", HopRewriteUtils.getBasic1NSequenceMax(seq)); inputargs.put("dir", new LiteralOp(direction)); @@ -1800,7 +1801,7 @@ public class RewriteAlgebraicSimplificationStatic extends HopRewriteRule HopRewriteUtils.replaceChildReference(parent, hi, pbop, pos); hi = pbop; - LOG.debug("Applied simplifyOuterSeqExpand (line "+hi.getBeginLine()+")"); + LOG.debug("Applied simplifyOuterSeqExpand (line "+hi.getBeginLine()+")"); } } http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/lops/ParameterizedBuiltin.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/lops/ParameterizedBuiltin.java b/src/main/java/org/apache/sysml/lops/ParameterizedBuiltin.java index f011ba4..898d875 100644 --- a/src/main/java/org/apache/sysml/lops/ParameterizedBuiltin.java +++ b/src/main/java/org/apache/sysml/lops/ParameterizedBuiltin.java @@ -38,7 +38,7 @@ public class ParameterizedBuiltin extends Lop public enum OperationTypes { CDF, INVCDF, RMEMPTY, REPLACE, REXPAND, LOWER_TRI, UPPER_TRI, TRANSFORMAPPLY, TRANSFORMDECODE, TRANSFORMCOLMAP, TRANSFORMMETA, - TOSTRING + TOSTRING, LIST } private OperationTypes _operation; @@ -215,13 +215,19 @@ public class ParameterizedBuiltin extends Lop case TRANSFORMAPPLY: case TRANSFORMDECODE: case TRANSFORMCOLMAP: - case TRANSFORMMETA: { - sb.append(_operation.toString().toLowerCase()); //opcode + case TRANSFORMMETA:{ + sb.append(_operation.name().toLowerCase()); //opcode sb.append(OPERAND_DELIMITOR); sb.append(compileGenericParamMap(_inputParams)); break; - } - case TOSTRING:{ + } + case LIST: { + sb.append("nvlist"); //opcode + sb.append(OPERAND_DELIMITOR); + sb.append(compileGenericParamMap(_inputParams)); + break; + } + case TOSTRING: { sb.append("toString"); //opcode sb.append(OPERAND_DELIMITOR); sb.append(compileGenericParamMap(_inputParams)); @@ -232,7 +238,7 @@ public class ParameterizedBuiltin extends Lop throw new LopsException(this.printErrorLocation() + "In ParameterizedBuiltin Lop, Unknown operation: " + _operation); } - if (_operation == OperationTypes.RMEMPTY) { + if (_operation == OperationTypes.RMEMPTY) { sb.append("bRmEmptyBC"); sb.append(NAME_VALUE_SEPARATOR); sb.append( _bRmEmptyBC ); http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/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 6e48839..0e949d0 100644 --- a/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java +++ b/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java @@ -1655,7 +1655,8 @@ public class BuiltinFunctionExpression extends DataIdentifier bifop = Expression.BuiltinFunctionOp.MAX; else if (functionName.equals("ppred")) bifop = Expression.BuiltinFunctionOp.PPRED; - else if(functionName.equals("list")) + else if(functionName.equals("list") //unnamed list + && paramExprsPassed.stream().allMatch(p -> p.getName()==null)) bifop = Expression.BuiltinFunctionOp.LIST; else if (functionName.equals("log")) bifop = Expression.BuiltinFunctionOp.LOG; @@ -1682,7 +1683,7 @@ public class BuiltinFunctionExpression extends DataIdentifier else if (functionName.equals("t")) bifop = Expression.BuiltinFunctionOp.TRANS; else if (functionName.equals("rev")) - bifop = Expression.BuiltinFunctionOp.REV; + bifop = Expression.BuiltinFunctionOp.REV; else if (functionName.equals("cbind") || functionName.equals("append")) bifop = Expression.BuiltinFunctionOp.CBIND; else if (functionName.equals("rbind")) http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/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 9d83dde..73a3a34 100644 --- a/src/main/java/org/apache/sysml/parser/DMLTranslator.java +++ b/src/main/java/org/apache/sysml/parser/DMLTranslator.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import org.apache.commons.logging.Log; @@ -1962,7 +1963,7 @@ public class DMLTranslator } } - private static Hop constructDfHop(String name, DataType dt, ValueType vt, ParameterizedBuiltinFunctionOp op, HashMap<String,Hop> paramHops) { + private static Hop constructDfHop(String name, DataType dt, ValueType vt, ParameterizedBuiltinFunctionOp op, LinkedHashMap<String,Hop> paramHops) { // Add a hop to paramHops to store distribution information. // Distribution parameter hops would have been already present in paramHops. @@ -2055,7 +2056,7 @@ public class DMLTranslator HashMap<String, Hop> hops) { // this expression has multiple "named" parameters - HashMap<String, Hop> paramHops = new HashMap<>(); + LinkedHashMap<String, Hop> paramHops = new LinkedHashMap<>(); // -- construct hops for all input parameters // -- store them in hashmap so that their "name"s are maintained @@ -2120,6 +2121,11 @@ public class DMLTranslator HopRewriteUtils.createBinary(paramHops.get("target"), new LiteralOp(""), OpOp2.PLUS); break; + case LIST: + currBuiltinOp = new ParameterizedBuiltinOp(target.getName(), target.getDataType(), + target.getValueType(), ParamBuiltinOp.LIST, paramHops); + break; + default: throw new ParseException(source.printErrorLocation() + "processParameterizedBuiltinFunctionExpression() -- Unknown operation: " + source.getOpCode()); http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/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 f369e19..66f08c5 100644 --- a/src/main/java/org/apache/sysml/parser/Expression.java +++ b/src/main/java/org/apache/sysml/parser/Expression.java @@ -159,7 +159,8 @@ public abstract class Expression implements ParseInfo // Distribution Functions CDF, INVCDF, PNORM, QNORM, PT, QT, PF, QF, PCHISQ, QCHISQ, PEXP, QEXP, TRANSFORMAPPLY, TRANSFORMDECODE, TRANSFORMENCODE, TRANSFORMCOLMAP, TRANSFORMMETA, - TOSTRING, // The "toString" method for DML; named arguments accepted to format output + TOSTRING, // The "toString" method for DML; named arguments accepted to format output + LIST, // named argument lists; unnamed lists become builtin function INVALID } http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/parser/Identifier.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/parser/Identifier.java b/src/main/java/org/apache/sysml/parser/Identifier.java index ffb455b..bf36a2f 100644 --- a/src/main/java/org/apache/sysml/parser/Identifier.java +++ b/src/main/java/org/apache/sysml/parser/Identifier.java @@ -161,47 +161,43 @@ public abstract class Identifier extends Expression if (indexedIdentiferOut.getRowLowerBound() != null) { indexedIdentiferOut.getRowLowerBound().validateExpression(ids, constVars, conditional); - Expression tempExpr = indexedIdentiferOut.getRowLowerBound(); - if (tempExpr.getOutput().getDataType() == Expression.DataType.MATRIX){ + if (tempExpr.getOutput().getDataType() == Expression.DataType.MATRIX){ raiseValidateError("Matrix values for row lower index bound are not supported, which includes indexed identifiers.", conditional); } - } + if (indexedIdentiferOut.getRowUpperBound() != null) { indexedIdentiferOut.getRowUpperBound().validateExpression(ids, constVars, conditional); - Expression tempExpr = indexedIdentiferOut.getRowUpperBound(); - if (tempExpr.getOutput().getDataType() == Expression.DataType.MATRIX){ + if (tempExpr.getOutput().getDataType() == Expression.DataType.MATRIX){ raiseValidateError("Matrix values for row upper index bound are not supported, which includes indexed identifiers.", conditional); } - } - if (indexedIdentiferOut.getColLowerBound() != null) { - indexedIdentiferOut.getColLowerBound().validateExpression(ids,constVars, conditional); + if (indexedIdentiferOut.getColLowerBound() != null) { + indexedIdentiferOut.getColLowerBound().validateExpression(ids,constVars, conditional); Expression tempExpr = indexedIdentiferOut.getColLowerBound(); - if (tempExpr.getOutput().getDataType() == Expression.DataType.MATRIX){ + if (tempExpr.getOutput().getDataType() == Expression.DataType.MATRIX){ raiseValidateError("Matrix values for column lower index bound are not supported, which includes indexed identifiers.", conditional); } - } + if (indexedIdentiferOut.getColUpperBound() != null) { indexedIdentiferOut.getColUpperBound().validateExpression(ids, constVars, conditional); - - Expression tempExpr = indexedIdentiferOut.getColUpperBound(); - if (tempExpr.getOutput().getDataType() == Expression.DataType.MATRIX){ + Expression tempExpr = indexedIdentiferOut.getColUpperBound(); + if (tempExpr.getOutput().getDataType() == Expression.DataType.MATRIX){ raiseValidateError("Matrix values for column upper index bound are not supported, which includes indexed identifiers.", conditional); } - } - IndexPair updatedIndices = ((IndexedIdentifier)this.getOutput()).calculateIndexedDimensions(ids, constVars, conditional); - ((IndexedIdentifier)this.getOutput()).setDimensions(updatedIndices._row, updatedIndices._col); - + if( this.getOutput().getDataType() != DataType.LIST ) { + IndexPair updatedIndices = ((IndexedIdentifier)this.getOutput()).calculateIndexedDimensions(ids, constVars, conditional); + ((IndexedIdentifier)this.getOutput()).setDimensions(updatedIndices._row, updatedIndices._col); + } } - - } else { + } + else { this.getOutput().setProperties(this.getOutput()); } } http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/parser/ParameterizedBuiltinFunctionExpression.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/parser/ParameterizedBuiltinFunctionExpression.java b/src/main/java/org/apache/sysml/parser/ParameterizedBuiltinFunctionExpression.java index 6f9d6f7..ffc8bc6 100644 --- a/src/main/java/org/apache/sysml/parser/ParameterizedBuiltinFunctionExpression.java +++ b/src/main/java/org/apache/sysml/parser/ParameterizedBuiltinFunctionExpression.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.Set; import java.util.stream.Collectors; @@ -35,9 +36,10 @@ import org.apache.wink.json4j.JSONObject; public class ParameterizedBuiltinFunctionExpression extends DataIdentifier { - + //note: we use a linked hashmap to preserve the order of + //parameters if needed, such as for named lists private ParameterizedBuiltinFunctionOp _opcode; - private HashMap<String,Expression> _varParams; + private LinkedHashMap<String,Expression> _varParams; public static final String TF_FN_PARAM_DATA = "target"; public static final String TF_FN_PARAM_MTD2 = "meta"; @@ -79,6 +81,7 @@ public class ParameterizedBuiltinFunctionExpression extends DataIdentifier // toString opcodeMap.put("toString", Expression.ParameterizedBuiltinFunctionOp.TOSTRING); + opcodeMap.put("list", Expression.ParameterizedBuiltinFunctionOp.LIST); } public static HashMap<Expression.ParameterizedBuiltinFunctionOp, ParamBuiltinOp> pbHopMap; @@ -123,17 +126,17 @@ public class ParameterizedBuiltinFunctionExpression extends DataIdentifier if ( pbifop == null ) return null; - HashMap<String,Expression> varParams = new HashMap<>(); + LinkedHashMap<String,Expression> varParams = new LinkedHashMap<>(); for (ParameterExpression pexpr : paramExprsPassed) varParams.put(pexpr.getName(), pexpr.getExpr()); - ParameterizedBuiltinFunctionExpression retVal = new ParameterizedBuiltinFunctionExpression(ctx, pbifop, - varParams, fileName); + ParameterizedBuiltinFunctionExpression retVal = + new ParameterizedBuiltinFunctionExpression(ctx, pbifop,varParams, fileName); return retVal; } - public ParameterizedBuiltinFunctionExpression(ParserRuleContext ctx, ParameterizedBuiltinFunctionOp op, HashMap<String,Expression> varParams, + public ParameterizedBuiltinFunctionExpression(ParserRuleContext ctx, ParameterizedBuiltinFunctionOp op, LinkedHashMap<String,Expression> varParams, String filename) { _opcode = op; _varParams = varParams; @@ -141,7 +144,7 @@ public class ParameterizedBuiltinFunctionExpression extends DataIdentifier } public ParameterizedBuiltinFunctionExpression(ParameterizedBuiltinFunctionOp op, - HashMap<String, Expression> varParams, ParseInfo parseInfo) { + LinkedHashMap<String, Expression> varParams, ParseInfo parseInfo) { _opcode = op; _varParams = varParams; setParseInfo(parseInfo); @@ -149,7 +152,7 @@ public class ParameterizedBuiltinFunctionExpression extends DataIdentifier @Override public Expression rewriteExpression(String prefix) { - HashMap<String,Expression> newVarParams = new HashMap<>(); + LinkedHashMap<String,Expression> newVarParams = new LinkedHashMap<>(); for (String key : _varParams.keySet()){ Expression newExpr = _varParams.get(key).rewriteExpression(prefix); newVarParams.put(key, newExpr); @@ -258,7 +261,11 @@ public class ParameterizedBuiltinFunctionExpression extends DataIdentifier case TOSTRING: validateCastAsString(output, conditional); break; - + + case LIST: + validateNamedList(output, conditional); + break; + default: //always unconditional (because unsupported operation) //handle common issue of transformencode if( getOpCode()==ParameterizedBuiltinFunctionOp.TRANSFORMENCODE ) @@ -761,6 +768,16 @@ public class ParameterizedBuiltinFunctionExpression extends DataIdentifier output.setValueType(ValueType.STRING); output.setDimensions(0, 0); } + + private void validateNamedList(DataIdentifier output, boolean conditional) { + HashMap<String, Expression> varParams = getVarParams(); + + // set output characteristics + output.setDataType(DataType.LIST); + output.setValueType(ValueType.UNKNOWN); + output.setDimensions(varParams.size(), 1); + output.setBlockDimensions(-1, -1); + } private void checkDataType( String fname, String pname, DataType dt, boolean conditional ) { Expression data = getVarParam(pname); http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/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 9e81f08..16db227 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java @@ -186,6 +186,7 @@ public class CPInstructionParser extends InstructionParser String2CPInstructionType.put( "list", CPType.BuiltinNary); // Parameterized Builtin Functions + String2CPInstructionType.put( "nvlist", CPType.ParameterizedBuiltin); String2CPInstructionType.put( "cdf", CPType.ParameterizedBuiltin); String2CPInstructionType.put( "invcdf", CPType.ParameterizedBuiltin); String2CPInstructionType.put( "groupedagg", CPType.ParameterizedBuiltin); http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/runtime/instructions/cp/ListIndexingCPInstruction.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/cp/ListIndexingCPInstruction.java b/src/main/java/org/apache/sysml/runtime/instructions/cp/ListIndexingCPInstruction.java index 59b2d48..4890439 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/cp/ListIndexingCPInstruction.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/cp/ListIndexingCPInstruction.java @@ -21,9 +21,9 @@ package org.apache.sysml.runtime.instructions.cp; import org.apache.sysml.lops.LeftIndex; import org.apache.sysml.lops.RightIndex; +import org.apache.sysml.parser.Expression.ValueType; import org.apache.sysml.runtime.DMLRuntimeException; import org.apache.sysml.runtime.controlprogram.context.ExecutionContext; -import org.apache.sysml.runtime.util.IndexRange; public final class ListIndexingCPInstruction extends IndexingCPInstruction { @@ -40,15 +40,22 @@ public final class ListIndexingCPInstruction extends IndexingCPInstruction { @Override public void processInstruction(ExecutionContext ec) { String opcode = getOpcode(); - IndexRange ixrange = getIndexRange(ec); + ScalarObject rl = ec.getScalarInput(rowLower.getName(), rowLower.getValueType(), rowLower.isLiteral()); + ScalarObject ru = ec.getScalarInput(rowUpper.getName(), rowUpper.getValueType(), rowUpper.isLiteral()); //right indexing if( opcode.equalsIgnoreCase(RightIndex.OPCODE) ) { ListObject list = (ListObject) ec.getVariable(input1.getName()); //execute right indexing operation and set output - ec.setVariable(output.getName(), - list.slice((int)ixrange.rowStart, (int)ixrange.rowEnd)); + if( rl.getValueType()==ValueType.STRING || ru.getValueType()==ValueType.STRING ) { + ec.setVariable(output.getName(), + list.slice(rl.getStringValue(), ru.getStringValue())); + } + else { + ec.setVariable(output.getName(), + list.slice((int)rl.getLongValue()-1, (int)ru.getLongValue()-1)); + } } //left indexing else if ( opcode.equalsIgnoreCase(LeftIndex.OPCODE)) { http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/runtime/instructions/cp/ListObject.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/cp/ListObject.java b/src/main/java/org/apache/sysml/runtime/instructions/cp/ListObject.java index f773847..0fdb1e8 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/cp/ListObject.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/cp/ListObject.java @@ -72,17 +72,36 @@ public class ListObject extends Data public Data slice(String name) { //check for existing named list if( _names == null ) - throw new DMLRuntimeException("Invalid lookup by name in unnamed list."); + throw new DMLRuntimeException("Invalid lookup by name" + + " in unnamed list: "+name+"."); //find position and check for existing entry int pos = _names.indexOf(name); if( pos <= 0 || pos >= _data.size() ) - throw new DMLRuntimeException("List lookup return no entry for name='"+name+"'"); + throw new DMLRuntimeException("List lookup returned no entry for name='"+name+"'"); //return existing entry return slice(pos); } + public ListObject slice(String name1, String name2) { + //check for existing named list + if( _names == null ) + throw new DMLRuntimeException("Invalid lookup by name" + + " in unnamed list: "+name1+", "+name2+"."); + + //find position and check for existing entry + int pos1 = _names.indexOf(name1); + int pos2 = _names.indexOf(name2); + if( pos1 <= 0 || pos1 >= _data.size() ) + throw new DMLRuntimeException("List lookup returned no entry for name='"+name1+"'"); + if( pos2 <= 0 || pos2 >= _data.size() ) + throw new DMLRuntimeException("List lookup returned no entry for name='"+name2+"'"); + + //return list object + return slice(pos1, pos2); + } + @Override public String getDebugName() { return toString(); http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/runtime/instructions/cp/ParameterizedBuiltinCPInstruction.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/cp/ParameterizedBuiltinCPInstruction.java b/src/main/java/org/apache/sysml/runtime/instructions/cp/ParameterizedBuiltinCPInstruction.java index 06aeef3..8fac54c 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/cp/ParameterizedBuiltinCPInstruction.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/cp/ParameterizedBuiltinCPInstruction.java @@ -19,8 +19,12 @@ package org.apache.sysml.runtime.instructions.cp; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.stream.Collectors; import org.apache.sysml.lops.Lop; import org.apache.sysml.parser.ParameterizedBuiltinFunctionExpression; @@ -55,9 +59,9 @@ public class ParameterizedBuiltinCPInstruction extends ComputationCPInstruction private static final String TOSTRING_SEPARATOR = " "; private static final String TOSTRING_LINESEPARATOR = "\n"; - protected final HashMap<String, String> params; + protected final LinkedHashMap<String, String> params; - protected ParameterizedBuiltinCPInstruction(Operator op, HashMap<String, String> paramsMap, CPOperand out, + protected ParameterizedBuiltinCPInstruction(Operator op, LinkedHashMap<String, String> paramsMap, CPOperand out, String opcode, String istr) { super(CPType.ParameterizedBuiltin, op, null, null, out, opcode, istr); params = paramsMap; @@ -71,9 +75,9 @@ public class ParameterizedBuiltinCPInstruction extends ComputationCPInstruction return getParameterMap().get(key); } - public static HashMap<String, String> constructParameterMap(String[] params) { + public static LinkedHashMap<String, String> constructParameterMap(String[] params) { // process all elements in "params" except first(opcode) and last(output) - HashMap<String,String> paramMap = new HashMap<>(); + LinkedHashMap<String,String> paramMap = new LinkedHashMap<>(); // all parameters are of form <name=value> String[] parts; @@ -93,7 +97,7 @@ public class ParameterizedBuiltinCPInstruction extends ComputationCPInstruction CPOperand out = new CPOperand( parts[parts.length-1] ); // process remaining parts and build a hash map - HashMap<String,String> paramsMap = constructParameterMap(parts); + LinkedHashMap<String,String> paramsMap = constructParameterMap(parts); // determine the appropriate value function ValueFunction func = null; @@ -136,11 +140,9 @@ public class ParameterizedBuiltinCPInstruction extends ComputationCPInstruction else if ( opcode.equals("transformapply") || opcode.equals("transformdecode") || opcode.equals("transformcolmap") - || opcode.equals("transformmeta")) - { - return new ParameterizedBuiltinCPInstruction(null, paramsMap, out, opcode, str); - } - else if ( opcode.equals("toString")) + || opcode.equals("transformmeta") + || opcode.equals("toString") + || opcode.equals("nvlist") ) { return new ParameterizedBuiltinCPInstruction(null, paramsMap, out, opcode, str); } @@ -337,6 +339,20 @@ public class ParameterizedBuiltinCPInstruction extends ComputationCPInstruction ec.releaseCacheableData(getParam("target")); ec.setScalarOutput(output.getName(), new StringObject(out)); } + else if( opcode.equals("nvlist") ) { + //obtain all input data objects and names in insertion order + List<Data> data = params.values().stream().map(d -> ec.containsVariable(d) ? + ec.getVariable(d) : new StringObject(d)).collect(Collectors.toList()); + List<String> names = new ArrayList<>(params.keySet()); + + //create list object over all inputs + ListObject list = new ListObject(data, names); + + //disable cleanup of individual objects and store cleanup state + list.setStatus(ec.pinVariables(new ArrayList<>(params.values()))); + + ec.setVariable(output.getName(), list); + } else { throw new DMLRuntimeException("Unknown opcode : " + opcode); } http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/main/java/org/apache/sysml/runtime/instructions/cp/ScalarBuiltinNaryCPInstruction.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/cp/ScalarBuiltinNaryCPInstruction.java b/src/main/java/org/apache/sysml/runtime/instructions/cp/ScalarBuiltinNaryCPInstruction.java index d2ca6f5..6acef43 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/cp/ScalarBuiltinNaryCPInstruction.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/cp/ScalarBuiltinNaryCPInstruction.java @@ -94,7 +94,7 @@ public class ScalarBuiltinNaryCPInstruction extends BuiltinNaryCPInstruction { //obtain all input data objects, incl handling of literals List<Data> data = Arrays.stream(inputs) .map(in -> ec.getVariable(in)).collect(Collectors.toList()); - + //create list object over all inputs ListObject list = new ListObject(data); http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/test/java/org/apache/sysml/test/integration/functions/misc/ListAndStructTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/sysml/test/integration/functions/misc/ListAndStructTest.java b/src/test/java/org/apache/sysml/test/integration/functions/misc/ListAndStructTest.java index b831032..a282b09 100644 --- a/src/test/java/org/apache/sysml/test/integration/functions/misc/ListAndStructTest.java +++ b/src/test/java/org/apache/sysml/test/integration/functions/misc/ListAndStructTest.java @@ -55,15 +55,15 @@ public class ListAndStructTest extends AutomatedTestBase runListStructTest(TEST_NAME1, true); } -// @Test -// public void testListNamed() { -// runListStructTest(TEST_NAME2, false); -// } -// -// @Test -// public void testListNamedRewrites() { -// runListStructTest(TEST_NAME2, true); -// } + @Test + public void testListNamed() { + runListStructTest(TEST_NAME2, false); + } + + @Test + public void testListNamedRewrites() { + runListStructTest(TEST_NAME2, true); + } private void runListStructTest(String testname, boolean rewrites) { http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/test/scripts/functions/misc/ListNamed.R ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/misc/ListNamed.R b/src/test/scripts/functions/misc/ListNamed.R new file mode 100644 index 0000000..abf01be --- /dev/null +++ b/src/test/scripts/functions/misc/ListNamed.R @@ -0,0 +1,42 @@ +#------------------------------------------------------------- +# +# 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") + +A = matrix(1, 10, 10); +B = matrix(2, 10, 10); +c = 3; +D = matrix(4, 10, 10); + +X = list(a=A, b=B, c=c, d=D, e=matrix(5, 3, 3), f=6); + +for( i in 1:length(X) ) { + tmp = X[i] + if( !exists("tmp") ) + print("ERROR: non-existing entry "+i ); +} + +R = as.matrix(sum(as.matrix(X[['e']]))); + +writeMM(as(R, "CsparseMatrix"), paste(args[1], "R", sep="")); http://git-wip-us.apache.org/repos/asf/systemml/blob/f9020a16/src/test/scripts/functions/misc/ListNamed.dml ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/misc/ListNamed.dml b/src/test/scripts/functions/misc/ListNamed.dml new file mode 100644 index 0000000..5b9b4e8 --- /dev/null +++ b/src/test/scripts/functions/misc/ListNamed.dml @@ -0,0 +1,38 @@ +#------------------------------------------------------------- +# +# 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. +# +#------------------------------------------------------------- + + +A = matrix(1, 10, 10); +B = matrix(2, 10, 10); +c = 3; +D = matrix(4, 10, 10); + +X = list(a=A, b=B, c=c, d=D, e=matrix(5, 3, 3), f=6); + +for( i in 1:length(X) ) { + tmp = X[i]; + if( !exists(tmp) ) + print("ERROR: non-existing entry "+i ); +} + +R = as.matrix(sum(as.matrix(X['e']))); + +write(R, $1);
