[SYSTEMML-675] Fix missing support negative for/parfor increments, tests Project: http://git-wip-us.apache.org/repos/asf/incubator-systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-systemml/commit/9b7f8b62 Tree: http://git-wip-us.apache.org/repos/asf/incubator-systemml/tree/9b7f8b62 Diff: http://git-wip-us.apache.org/repos/asf/incubator-systemml/diff/9b7f8b62
Branch: refs/heads/master Commit: 9b7f8b621c9a57e107f43171776b807791f65f59 Parents: d7dedce Author: Matthias Boehm <[email protected]> Authored: Mon May 9 23:32:49 2016 -0700 Committer: Matthias Boehm <[email protected]> Committed: Tue May 10 11:39:22 2016 -0700 ---------------------------------------------------------------------- .../sysml/hops/rewrite/ProgramRewriter.java | 3 + .../rewrite/RewriteForLoopVectorization.java | 7 +- .../org/apache/sysml/parser/DMLTranslator.java | 4 +- .../apache/sysml/parser/ForStatementBlock.java | 2 +- .../apache/sysml/parser/IterablePredicate.java | 26 ++-- .../sysml/parser/ParForStatementBlock.java | 7 +- .../parser/common/CommonSyntacticValidator.java | 1 - .../sysml/parser/dml/DmlSyntacticValidator.java | 6 +- .../parser/pydml/PydmlSyntacticValidator.java | 5 +- .../runtime/controlprogram/ForProgramBlock.java | 81 ++++++++---- .../controlprogram/ParForProgramBlock.java | 8 +- .../controlprogram/parfor/TaskPartitioner.java | 36 ++++-- .../parfor/opt/OptTreeConverter.java | 12 +- .../misc/NegativeLoopIncrementsTest.java | 129 +++++++++++++++++++ .../functions/misc/NegativeForIncrTest.R | 43 +++++++ .../functions/misc/NegativeForIncrTest.dml | 35 +++++ .../functions/misc/NegativeParForIncrTest.R | 43 +++++++ .../functions/misc/NegativeParForIncrTest.dml | 36 ++++++ .../functions/misc/conditionalValidate3.dml | 2 +- .../functions/misc/ZPackageSuite.java | 1 + 20 files changed, 419 insertions(+), 68 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/main/java/org/apache/sysml/hops/rewrite/ProgramRewriter.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/rewrite/ProgramRewriter.java b/src/main/java/org/apache/sysml/hops/rewrite/ProgramRewriter.java index cfc5855..9837a62 100644 --- a/src/main/java/org/apache/sysml/hops/rewrite/ProgramRewriter.java +++ b/src/main/java/org/apache/sysml/hops/rewrite/ProgramRewriter.java @@ -296,6 +296,9 @@ public class ProgramRewriter public Hop rewriteHopDAG(Hop root, ProgramRewriteStatus state) throws HopsException { + if( root == null ) + return root; + for( HopRewriteRule r : _dagRuleSet ) { root.resetVisitStatus(); //reset for each rule http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/main/java/org/apache/sysml/hops/rewrite/RewriteForLoopVectorization.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/rewrite/RewriteForLoopVectorization.java b/src/main/java/org/apache/sysml/hops/rewrite/RewriteForLoopVectorization.java index 31bd306..c773319 100644 --- a/src/main/java/org/apache/sysml/hops/rewrite/RewriteForLoopVectorization.java +++ b/src/main/java/org/apache/sysml/hops/rewrite/RewriteForLoopVectorization.java @@ -77,7 +77,7 @@ public class RewriteForLoopVectorization extends StatementBlockRewriteRule || csb instanceof IfStatementBlock || csb instanceof ForStatementBlock ) ) { - //auto vectorzation pattern + //auto vectorization pattern sb = vectorizeScalarAggregate(sb, csb, from, to, incr, iterVar); //e.g., for(i){s = s + as.scalar(X[i,2])} sb = vectorizeElementwiseBinary(sb, csb, from, to, incr, iterVar); sb = vectorizeElementwiseUnary(sb, csb, from, to, incr, iterVar); @@ -110,8 +110,9 @@ public class RewriteForLoopVectorization extends StatementBlockRewriteRule { StatementBlock ret = sb; - //check supported increment values - if( !(increment instanceof LiteralOp && ((LiteralOp)increment).getDoubleValue()==1.0) ){ + //check missing and supported increment values + if( !(increment!=null && increment instanceof LiteralOp + && ((LiteralOp)increment).getDoubleValue()==1.0) ) { return ret; } http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/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 b2b91c9..9e710e3 100644 --- a/src/main/java/org/apache/sysml/parser/DMLTranslator.java +++ b/src/main/java/org/apache/sysml/parser/DMLTranslator.java @@ -1377,7 +1377,7 @@ public class DMLTranslator varsRead = ip.getFromExpr().variablesRead(); else if (i==1) varsRead = ip.getToExpr().variablesRead(); - else + else if( ip.getIncrementExpr() != null ) varsRead = ip.getIncrementExpr().variablesRead(); if(varsRead != null) { @@ -1405,7 +1405,7 @@ public class DMLTranslator fsb.setFromHops( processTempIntExpression( ip.getFromExpr(), _ids )); else if(i==1) fsb.setToHops( processTempIntExpression( ip.getToExpr(), _ids )); - else + else if( ip.getIncrementExpr() != null ) fsb.setIncrementHops( processTempIntExpression( ip.getIncrementExpr(), _ids )); } http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/main/java/org/apache/sysml/parser/ForStatementBlock.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/parser/ForStatementBlock.java b/src/main/java/org/apache/sysml/parser/ForStatementBlock.java index a13db39..782b682 100644 --- a/src/main/java/org/apache/sysml/parser/ForStatementBlock.java +++ b/src/main/java/org/apache/sysml/parser/ForStatementBlock.java @@ -358,7 +358,7 @@ public class ForStatementBlock extends StatementBlock if (replacementExpr != null) ip.setFromExpr(replacementExpr); - // handle replacment in to expression + // handle replacement in to expression replacementExpr = replaceConstantVar(ip.getToExpr(), currConstVars); if (replacementExpr != null) ip.setToExpr(replacementExpr); http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/main/java/org/apache/sysml/parser/IterablePredicate.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/parser/IterablePredicate.java b/src/main/java/org/apache/sysml/parser/IterablePredicate.java index 5c86350..e145eb7 100644 --- a/src/main/java/org/apache/sysml/parser/IterablePredicate.java +++ b/src/main/java/org/apache/sysml/parser/IterablePredicate.java @@ -73,19 +73,18 @@ public class IterablePredicate extends Expression } - public VariableSet variablesRead() - { + public VariableSet variablesRead() { VariableSet result = new VariableSet(); result.addVariables( _fromExpr.variablesRead() ); result.addVariables( _toExpr.variablesRead() ); - result.addVariables( _incrementExpr.variablesRead() ); + if( _incrementExpr != null ) + result.addVariables( _incrementExpr.variablesRead() ); return result; } - public VariableSet variablesUpdated() - { + public VariableSet variablesUpdated() { VariableSet result = new VariableSet(); result.addVariable(_iterVar.getName(), _iterVar); @@ -105,7 +104,6 @@ public class IterablePredicate extends Expression public void validateExpression(HashMap<String, DataIdentifier> ids, HashMap<String, ConstIdentifier> constVars, boolean conditional) throws LanguageException { - //recursive validate if (_iterVar instanceof FunctionCallIdentifier || _fromExpr instanceof FunctionCallIdentifier @@ -115,8 +113,6 @@ public class IterablePredicate extends Expression false, LanguageException.LanguageErrorCodes.UNSUPPORTED_EXPRESSION); } - - //1) VALIDATE ITERATION VARIABLE (index) // check the variable has either 1) not been defined already OR 2) defined as integer scalar if (ids.containsKey(_iterVar.getName())){ @@ -134,10 +130,20 @@ public class IterablePredicate extends Expression //2) VALIDATE FOR PREDICATE in (from, to, increment) + // handle default increment if unspecified + if( _incrementExpr == null && _fromExpr instanceof ConstIdentifier + && _toExpr instanceof ConstIdentifier ) { + ConstIdentifier cFrom = (ConstIdentifier) _fromExpr; + ConstIdentifier cTo = (ConstIdentifier) _toExpr; + _incrementExpr = new IntIdentifier( (cFrom.getLongValue() <= cTo.getLongValue()) ? 1 : -1, + getFilename(), getBeginLine(), getBeginColumn(), getEndLine(), getEndColumn()); + } + //recursively validate the individual expression _fromExpr.validateExpression(ids, constVars, conditional); _toExpr.validateExpression(ids, constVars, conditional); - _incrementExpr.validateExpression(ids, constVars, conditional); + if( _incrementExpr != null ) + _incrementExpr.validateExpression(ids, constVars, conditional); //check for scalar expression output checkNumericScalarOutput( _fromExpr ); @@ -195,7 +201,7 @@ public class IterablePredicate extends Expression ret[1] = from.getOutputParameters().getLabel(); if( to.getType()==Lop.Type.Data ) ret[2] = to.getOutputParameters().getLabel(); - if( incr.getType()==Lop.Type.Data ) + if( incr != null && incr.getType()==Lop.Type.Data ) ret[3] = incr.getOutputParameters().getLabel(); return ret; http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/main/java/org/apache/sysml/parser/ParForStatementBlock.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/parser/ParForStatementBlock.java b/src/main/java/org/apache/sysml/parser/ParForStatementBlock.java index 64cffec..fb5a8eb 100644 --- a/src/main/java/org/apache/sysml/parser/ParForStatementBlock.java +++ b/src/main/java/org/apache/sysml/parser/ParForStatementBlock.java @@ -1050,10 +1050,9 @@ public class ParForStatementBlock extends ForStatementBlock //NOTE: conservative approach: include all index variables (also from for) if( ip.getIncrementExpr() instanceof IntIdentifier ) incr = ((IntIdentifier)ip.getIncrementExpr()).getValue(); - else - throw new LanguageException("PARFOR loop dependency analysis: cannot check for dependencies " + - "because increment expression '"+ip.getIncrementExpr().toString()+"' cannot be normalized."); - + else + incr = ( low <= up ) ? 1 : -1; + _bounds._lower.put(ip.getIterVar()._name, low); _bounds._upper.put(ip.getIterVar()._name, up); _bounds._increment.put(ip.getIterVar()._name, incr); http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/main/java/org/apache/sysml/parser/common/CommonSyntacticValidator.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/parser/common/CommonSyntacticValidator.java b/src/main/java/org/apache/sysml/parser/common/CommonSyntacticValidator.java index e75c31d..78ba3d6 100644 --- a/src/main/java/org/apache/sysml/parser/common/CommonSyntacticValidator.java +++ b/src/main/java/org/apache/sysml/parser/common/CommonSyntacticValidator.java @@ -40,7 +40,6 @@ import org.apache.sysml.parser.DoubleIdentifier; import org.apache.sysml.parser.Expression; import org.apache.sysml.parser.Expression.DataOp; import org.apache.sysml.parser.FunctionCallIdentifier; -import org.apache.sysml.parser.IndexedIdentifier; import org.apache.sysml.parser.IntIdentifier; import org.apache.sysml.parser.LanguageException; import org.apache.sysml.parser.MultiAssignmentStatement; http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/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 5f5b2f3..81538bc 100644 --- a/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java +++ b/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java @@ -47,7 +47,6 @@ import org.apache.sysml.parser.FunctionStatement; import org.apache.sysml.parser.IfStatement; import org.apache.sysml.parser.ImportStatement; import org.apache.sysml.parser.IndexedIdentifier; -import org.apache.sysml.parser.IntIdentifier; import org.apache.sysml.parser.IterablePredicate; import org.apache.sysml.parser.LanguageException; import org.apache.sysml.parser.ParForStatement; @@ -651,7 +650,7 @@ public class DmlSyntacticValidator extends CommonSyntacticValidator implements D DataIdentifier iterVar = new DataIdentifier(ctx.iterVar.getText()); HashMap<String, String> parForParamValues = null; - Expression incrementExpr = new IntIdentifier(1, currentFile, line, col, line, col); + Expression incrementExpr = null; //1/-1 if(ctx.iterPred.info.increment != null) { incrementExpr = ctx.iterPred.info.increment; } @@ -682,8 +681,7 @@ public class DmlSyntacticValidator extends CommonSyntacticValidator implements D } } - Expression incrementExpr = new IntIdentifier(1, currentFile, line, col, line, col); - + Expression incrementExpr = null; //1/-1 if( ctx.iterPred.info.increment != null ) { incrementExpr = ctx.iterPred.info.increment; } http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/main/java/org/apache/sysml/parser/pydml/PydmlSyntacticValidator.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/parser/pydml/PydmlSyntacticValidator.java b/src/main/java/org/apache/sysml/parser/pydml/PydmlSyntacticValidator.java index aa09e0d..3e2215c 100644 --- a/src/main/java/org/apache/sysml/parser/pydml/PydmlSyntacticValidator.java +++ b/src/main/java/org/apache/sysml/parser/pydml/PydmlSyntacticValidator.java @@ -1210,7 +1210,7 @@ public class PydmlSyntacticValidator extends CommonSyntacticValidator implements DataIdentifier iterVar = new DataIdentifier(ctx.iterVar.getText()); HashMap<String, String> parForParamValues = null; - Expression incrementExpr = new IntIdentifier(1, currentFile, line, col, line, col); + Expression incrementExpr = null; //1/-1 if(ctx.iterPred.info.increment != null) { incrementExpr = ctx.iterPred.info.increment; } @@ -1241,8 +1241,7 @@ public class PydmlSyntacticValidator extends CommonSyntacticValidator implements } } - Expression incrementExpr = new IntIdentifier(1, currentFile, line, col, line, col); - + Expression incrementExpr = null; //1/-1 if( ctx.iterPred.info.increment != null ) { incrementExpr = ctx.iterPred.info.increment; } http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/main/java/org/apache/sysml/runtime/controlprogram/ForProgramBlock.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/controlprogram/ForProgramBlock.java b/src/main/java/org/apache/sysml/runtime/controlprogram/ForProgramBlock.java index db853f6..535f318 100644 --- a/src/main/java/org/apache/sysml/runtime/controlprogram/ForProgramBlock.java +++ b/src/main/java/org/apache/sysml/runtime/controlprogram/ForProgramBlock.java @@ -20,6 +20,7 @@ package org.apache.sysml.runtime.controlprogram; import java.util.ArrayList; +import java.util.Iterator; import org.apache.sysml.api.DMLScript; import org.apache.sysml.hops.Hop; @@ -162,43 +163,35 @@ public class ForProgramBlock extends ProgramBlock // evaluate from, to, incr only once (assumption: known at for entry) IntObject from = executePredicateInstructions( 1, _fromInstructions, ec ); IntObject to = executePredicateInstructions( 2, _toInstructions, ec ); - IntObject incr = executePredicateInstructions( 3, _incrementInstructions, ec ); + IntObject incr = (_incrementInstructions == null || _incrementInstructions.isEmpty()) && _iterablePredicateVars[3]==null ? + new IntObject((from.getLongValue()<=to.getLongValue()) ? 1 : -1) : + executePredicateInstructions( 3, _incrementInstructions, ec ); - if ( incr.getLongValue() <= 0 ) //would produce infinite loop - throw new DMLRuntimeException(this.printBlockErrorLocation() + "Expression for increment of variable '" + iterVarName + "' must evaluate to a positive value."); - - // initialize iter var to from value - IntObject iterVar = new IntObject(iterVarName, from.getLongValue() ); + if ( incr.getLongValue() == 0 ) //would produce infinite loop + throw new DMLRuntimeException(this.printBlockErrorLocation() + "Expression for increment of variable '" + iterVarName + "' must evaluate to a non-zero value."); // execute for loop try { - // run for loop body as long as predicate is true - // (for supporting dynamic TO, move expression execution to end of while loop) - while( iterVar.getLongValue() <= to.getLongValue() ) + // run for loop body for each instance of predicate sequence + SequenceIterator seqIter = new SequenceIterator(iterVarName, from, to, incr); + for( IntObject iterVar : seqIter ) { + //set iteration variable ec.setVariable(iterVarName, iterVar); - //for all child blocks - for (int i=0 ; i < this._childBlocks.size() ; i++) { + //execute all child blocks + for(int i=0 ; i < this._childBlocks.size() ; i++) { ec.updateDebugState( i ); _childBlocks.get(i).execute(ec); } - - // update the iterable predicate variable - if(ec.getVariable(iterVarName) == null || !(ec.getVariable(iterVarName) instanceof IntObject)) - throw new DMLRuntimeException("Iterable predicate variable " + iterVarName + " must remain of type scalar int."); - - //increment of iterVar (changes in loop body get discarded) - iterVar = new IntObject( iterVarName, iterVar.getLongValue()+incr.getLongValue() ); } } - catch (DMLScriptException e) - { + catch (DMLScriptException e) { + //propagate stop call throw e; } - catch (Exception e) - { + catch (Exception e) { throw new DMLRuntimeException(printBlockErrorLocation() + "Error evaluating for program block", e); } @@ -286,4 +279,48 @@ public class ForProgramBlock extends ProgramBlock public String printBlockErrorLocation(){ return "ERROR: Runtime error in for program block generated from for statement block between lines " + _beginLine + " and " + _endLine + " -- "; } + + /** + * Utility class for iterating over positive or negative predicate sequences. + */ + protected class SequenceIterator implements Iterator<IntObject>, Iterable<IntObject> + { + private String _varName = null; + private long _cur = -1; + private long _to = -1; + private long _incr = -1; + private boolean _inuse = false; + + protected SequenceIterator(String varName, IntObject from, IntObject to, IntObject incr) { + _varName = varName; + _cur = from.getLongValue(); + _to = to.getLongValue(); + _incr = incr.getLongValue(); + } + + @Override + public boolean hasNext() { + return _incr > 0 ? _cur <= _to : _cur >= _to; + } + + @Override + public IntObject next() { + IntObject ret = new IntObject( _varName, _cur ); + _cur += _incr; //update current val + return ret; + } + + @Override + public Iterator<IntObject> iterator() { + if( _inuse ) + throw new RuntimeException("Unsupported reuse of iterator."); + _inuse = true; + return this; + } + + @Override + public void remove() { + throw new RuntimeException("Unsupported remove on iterator."); + } + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/main/java/org/apache/sysml/runtime/controlprogram/ParForProgramBlock.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/controlprogram/ParForProgramBlock.java b/src/main/java/org/apache/sysml/runtime/controlprogram/ParForProgramBlock.java index fd53f4d..d03d3b8 100644 --- a/src/main/java/org/apache/sysml/runtime/controlprogram/ParForProgramBlock.java +++ b/src/main/java/org/apache/sysml/runtime/controlprogram/ParForProgramBlock.java @@ -529,10 +529,12 @@ public class ParForProgramBlock extends ForProgramBlock // evaluate from, to, incr only once (assumption: known at for entry) IntObject from = executePredicateInstructions( 1, _fromInstructions, ec ); IntObject to = executePredicateInstructions( 2, _toInstructions, ec ); - IntObject incr = executePredicateInstructions( 3, _incrementInstructions, ec ); + IntObject incr = (_incrementInstructions == null || _incrementInstructions.isEmpty()) && _iterablePredicateVars[3]==null ? + new IntObject((from.getLongValue()<=to.getLongValue()) ? 1 : -1) : + executePredicateInstructions( 3, _incrementInstructions, ec ); - if ( incr.getLongValue() <= 0 ) //would produce infinite loop - throw new DMLRuntimeException(this.printBlockErrorLocation() + "Expression for increment of variable '" + iterVarName + "' must evaluate to a positive value."); + if ( incr.getLongValue() == 0 ) //would produce infinite loop + throw new DMLRuntimeException(this.printBlockErrorLocation() + "Expression for increment of variable '" + iterVarName + "' must evaluate to a non-zero value."); //early exit on num iterations = zero if( computeNumIterations(from, to, incr) <= 0 ) http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/main/java/org/apache/sysml/runtime/controlprogram/parfor/TaskPartitioner.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/controlprogram/parfor/TaskPartitioner.java b/src/main/java/org/apache/sysml/runtime/controlprogram/parfor/TaskPartitioner.java index e96e9ee..9349402 100644 --- a/src/main/java/org/apache/sysml/runtime/controlprogram/parfor/TaskPartitioner.java +++ b/src/main/java/org/apache/sysml/runtime/controlprogram/parfor/TaskPartitioner.java @@ -33,27 +33,26 @@ import org.apache.sysml.runtime.instructions.cp.IntObject; * */ public abstract class TaskPartitioner -{ - - protected long _taskSize = -1; - +{ + protected long _taskSize = -1; protected String _iterVarName = null; protected IntObject _fromVal = null; protected IntObject _toVal = null; protected IntObject _incrVal = null; - - protected long _numIter = -1; - + protected long _numIter = -1; protected TaskPartitioner( long taskSize, String iterVarName, IntObject fromVal, IntObject toVal, IntObject incrVal ) { _taskSize = taskSize; - _iterVarName = iterVarName; _fromVal = fromVal; _toVal = toVal; _incrVal = incrVal; + //normalize predicate if necessary + normalizePredicate(); + + //compute number of iterations _numIter = (long)Math.ceil(((double)(_toVal.getLongValue()-_fromVal.getLongValue()+1 )) / _incrVal.getLongValue()); } @@ -79,8 +78,25 @@ public abstract class TaskPartitioner * * @return */ - public long getNumIterations() - { + public long getNumIterations() { return _numIter; } + + /** + * Normalizes the (from, to, incr) predicate to a predicate w/ + * positive increment. + */ + private void normalizePredicate() { + //check for positive increment + if( _incrVal.getLongValue() >= 0 ) + return; + + long lfrom = _fromVal.getLongValue(); + long lto = _toVal.getLongValue(); + long lincr = _incrVal.getLongValue(); + + _fromVal = new IntObject(lfrom - ((lfrom - lto)/lincr * lincr)); + _toVal = new IntObject(lfrom); + _incrVal = new IntObject(-1 * lincr); + } } http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/main/java/org/apache/sysml/runtime/controlprogram/parfor/opt/OptTreeConverter.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/controlprogram/parfor/opt/OptTreeConverter.java b/src/main/java/org/apache/sysml/runtime/controlprogram/parfor/opt/OptTreeConverter.java index 35d8b84..c65a627 100644 --- a/src/main/java/org/apache/sysml/runtime/controlprogram/parfor/opt/OptTreeConverter.java +++ b/src/main/java/org/apache/sysml/runtime/controlprogram/parfor/opt/OptTreeConverter.java @@ -447,10 +447,12 @@ public class OptTreeConverter //handle predicate fsb.getFromHops().resetVisitStatus(); fsb.getToHops().resetVisitStatus(); - fsb.getIncrementHops().resetVisitStatus(); + if( fsb.getIncrementHops()!=null ) + fsb.getIncrementHops().resetVisitStatus(); node.addChilds( rCreateAbstractOptNodes( fsb.getFromHops(), vars, memo ) ); node.addChilds( rCreateAbstractOptNodes( fsb.getToHops(), vars, memo ) ); - node.addChilds( rCreateAbstractOptNodes( fsb.getIncrementHops(), vars, memo ) ); + if( fsb.getIncrementHops()!=null ) + node.addChilds( rCreateAbstractOptNodes( fsb.getIncrementHops(), vars, memo ) ); //process body int len = fs.getBody().size(); @@ -495,10 +497,12 @@ public class OptTreeConverter { fsb.getFromHops().resetVisitStatus(); fsb.getToHops().resetVisitStatus(); - fsb.getIncrementHops().resetVisitStatus(); + if( fsb.getIncrementHops()!=null ) + fsb.getIncrementHops().resetVisitStatus(); node.addChilds( rCreateAbstractOptNodes( fsb.getFromHops(), vars, memo ) ); node.addChilds( rCreateAbstractOptNodes( fsb.getToHops(), vars, memo ) ); - node.addChilds( rCreateAbstractOptNodes( fsb.getIncrementHops(), vars, memo ) ); + if( fsb.getIncrementHops()!=null ) + node.addChilds( rCreateAbstractOptNodes( fsb.getIncrementHops(), vars, memo ) ); } //process body http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/test/java/org/apache/sysml/test/integration/functions/misc/NegativeLoopIncrementsTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/sysml/test/integration/functions/misc/NegativeLoopIncrementsTest.java b/src/test/java/org/apache/sysml/test/integration/functions/misc/NegativeLoopIncrementsTest.java new file mode 100644 index 0000000..fde3893 --- /dev/null +++ b/src/test/java/org/apache/sysml/test/integration/functions/misc/NegativeLoopIncrementsTest.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.sysml.test.integration.functions.misc; + +import java.util.HashMap; + +import org.junit.Test; + +import org.apache.sysml.runtime.matrix.MatrixCharacteristics; +import org.apache.sysml.runtime.matrix.data.MatrixValue.CellIndex; +import org.apache.sysml.test.integration.AutomatedTestBase; +import org.apache.sysml.test.integration.TestConfiguration; +import org.apache.sysml.test.utils.TestUtils; + +/** + * + */ +public class NegativeLoopIncrementsTest extends AutomatedTestBase +{ + private final static String TEST_NAME1 = "NegativeForIncrTest"; + private final static String TEST_NAME2 = "NegativeParforIncrTest"; + + private final static String TEST_DIR = "functions/misc/"; + private static final String TEST_CLASS_DIR = TEST_DIR + NegativeLoopIncrementsTest.class.getSimpleName() + "/"; + private final static int rows = 372; + private final static int cols = 1; + private final static double eps = 1e-8; + + @Override + public void setUp() { + TestUtils.clearAssertionInformation(); + addTestConfiguration(TEST_NAME1, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME1, new String[] { "R" })); + addTestConfiguration(TEST_NAME2, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME2, new String[] { "R" })); + } + + @Test + public void testNegativeForIncrementsScalar() { + runNegativeLoopIncrementsTest(TEST_NAME1, false, false); + } + + @Test + public void testNegativeForIncrementsVector() { + runNegativeLoopIncrementsTest(TEST_NAME1, true, false); + } + + @Test + public void testNegativeParForIncrementsScalar() { + runNegativeLoopIncrementsTest(TEST_NAME2, false, false); + } + + @Test + public void testNegativeParForIncrementsVector() { + runNegativeLoopIncrementsTest(TEST_NAME2, true, false); + } + + @Test + public void testNegativeForIncrementsScalarMulti() { + runNegativeLoopIncrementsTest(TEST_NAME1, false, true); + } + + @Test + public void testNegativeForIncrementsVectorMulti() { + runNegativeLoopIncrementsTest(TEST_NAME1, true, true); + } + + @Test + public void testNegativeParForIncrementsScalarMulti() { + runNegativeLoopIncrementsTest(TEST_NAME2, false, true); + } + + @Test + public void testNegativeParForIncrementsVectorMulti() { + runNegativeLoopIncrementsTest(TEST_NAME2, true, true); + } + + /** + * + * @param sparseM1 + * @param sparseM2 + * @param instType + */ + private void runNegativeLoopIncrementsTest( String testname, boolean vect, boolean multiStep ) + { + String TEST_NAME = testname; + TestConfiguration config = getTestConfiguration(TEST_NAME); + loadTestConfiguration(config); + + double[][] A = getRandomMatrix(rows, cols, -5, 5, 0.9, 7); + writeInputMatrixWithMTD("A", A, true); + + String HOME = SCRIPT_DIR + TEST_DIR; + fullDMLScriptName = HOME + TEST_NAME + ".dml"; + programArgs = new String[]{"-args", input("A"), String.valueOf(vect?0:1), + String.valueOf(multiStep).toUpperCase(), output("R")}; + + fullRScriptName = HOME + TEST_NAME +".R"; + rCmd = getRCmd(inputDir(), String.valueOf(vect?0:1), + String.valueOf(multiStep).toUpperCase(), expectedDir()); + + //run Tests + runTest(true, false, null, -1); + runRScript(true); + + //compare matrices + HashMap<CellIndex, Double> dmlfile = readDMLMatrixFromHDFS("R"); + HashMap<CellIndex, Double> rfile = readRMatrixFromFS("R"); + TestUtils.compareMatrices(dmlfile, rfile, eps, "Stat-DML", "Stat-R"); + + //check meta data + checkDMLMetaDataFile("R", new MatrixCharacteristics(1,1,1,1)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/test/scripts/functions/misc/NegativeForIncrTest.R ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/misc/NegativeForIncrTest.R b/src/test/scripts/functions/misc/NegativeForIncrTest.R new file mode 100644 index 0000000..a084986 --- /dev/null +++ b/src/test/scripts/functions/misc/NegativeForIncrTest.R @@ -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. +# +#------------------------------------------------------------- + + +args <- commandArgs(TRUE) +options(digits=22) +library("Matrix") + +A = as.matrix(readMM(paste(args[1], "A.mtx", sep=""))) +c = as.integer(args[2]); +mStep = as.logical(args[3]); + +s = 0; +if( mStep ) { + for( i in seq(nrow(A),1,-7) ) { + s = s + A[i,1] + c; + } +} else { + for( i in nrow(A):1 ) { + s = s + A[i,1] + c; + } +} + +R = as.matrix(s); +writeMM(as(R, "CsparseMatrix"), paste(args[4], "R", sep="")); http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/test/scripts/functions/misc/NegativeForIncrTest.dml ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/misc/NegativeForIncrTest.dml b/src/test/scripts/functions/misc/NegativeForIncrTest.dml new file mode 100644 index 0000000..2a5e742 --- /dev/null +++ b/src/test/scripts/functions/misc/NegativeForIncrTest.dml @@ -0,0 +1,35 @@ +#------------------------------------------------------------- +# +# 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 = read($1); +c = as.integer($2); +mStep = as.logical($3); + +s = 0; +if( mStep ) + for( i in seq(nrow(A),1,-7) ) + s = s + as.scalar(A[i,1]) + c; +else + for( i in nrow(A):1 ) + s = s + as.scalar(A[i,1]) + c; + +R = as.matrix(s); +write(R, $4); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/test/scripts/functions/misc/NegativeParForIncrTest.R ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/misc/NegativeParForIncrTest.R b/src/test/scripts/functions/misc/NegativeParForIncrTest.R new file mode 100644 index 0000000..a084986 --- /dev/null +++ b/src/test/scripts/functions/misc/NegativeParForIncrTest.R @@ -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. +# +#------------------------------------------------------------- + + +args <- commandArgs(TRUE) +options(digits=22) +library("Matrix") + +A = as.matrix(readMM(paste(args[1], "A.mtx", sep=""))) +c = as.integer(args[2]); +mStep = as.logical(args[3]); + +s = 0; +if( mStep ) { + for( i in seq(nrow(A),1,-7) ) { + s = s + A[i,1] + c; + } +} else { + for( i in nrow(A):1 ) { + s = s + A[i,1] + c; + } +} + +R = as.matrix(s); +writeMM(as(R, "CsparseMatrix"), paste(args[4], "R", sep="")); http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/test/scripts/functions/misc/NegativeParForIncrTest.dml ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/misc/NegativeParForIncrTest.dml b/src/test/scripts/functions/misc/NegativeParForIncrTest.dml new file mode 100644 index 0000000..c53ce1c --- /dev/null +++ b/src/test/scripts/functions/misc/NegativeParForIncrTest.dml @@ -0,0 +1,36 @@ +#------------------------------------------------------------- +# +# 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 = read($1); +c = as.integer($2); +mStep = as.logical($3); + +tmp = matrix(0, rows=nrow(A), cols=1); +if( mStep ) + parfor( i in seq(nrow(A),1,-7) ) + tmp[i,1] = as.scalar(A[i,1]) + c; +else + parfor( i in nrow(A):1 ) + tmp[i,1] = as.scalar(A[i,1]) + c; +s = sum(tmp); + +R = as.matrix(s); +write(R, $4); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/test/scripts/functions/misc/conditionalValidate3.dml ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/misc/conditionalValidate3.dml b/src/test/scripts/functions/misc/conditionalValidate3.dml index 94d8cdc..3b0f2f7 100644 --- a/src/test/scripts/functions/misc/conditionalValidate3.dml +++ b/src/test/scripts/functions/misc/conditionalValidate3.dml @@ -23,7 +23,7 @@ Y = matrix(1, rows=10, cols=10); -for( i in 1:0 ) { +for( i in seq(1,0,1) ) { Y = read($1); } http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/9b7f8b62/src/test_suites/java/org/apache/sysml/test/integration/functions/misc/ZPackageSuite.java ---------------------------------------------------------------------- diff --git a/src/test_suites/java/org/apache/sysml/test/integration/functions/misc/ZPackageSuite.java b/src/test_suites/java/org/apache/sysml/test/integration/functions/misc/ZPackageSuite.java index 5fa4d3a..23d8947 100644 --- a/src/test_suites/java/org/apache/sysml/test/integration/functions/misc/ZPackageSuite.java +++ b/src/test_suites/java/org/apache/sysml/test/integration/functions/misc/ZPackageSuite.java @@ -37,6 +37,7 @@ import org.junit.runners.Suite; IPAScalarRecursionTest.class, IPAUnknownRecursionTest.class, LongOverflowTest.class, + NegativeLoopIncrementsTest.class, NrowNcolStringTest.class, NrowNcolUnknownCSVReadTest.class, OuterTableExpandTest.class,
