Search in sources :

Example 6 with VariableSet

use of org.apache.sysml.parser.VariableSet in project incubator-systemml by apache.

the class RewriteMarkLoopVariablesUpdateInPlace method rewriteStatementBlock.

@Override
public List<StatementBlock> rewriteStatementBlock(StatementBlock sb, ProgramRewriteStatus status) {
    if (DMLScript.rtplatform == RUNTIME_PLATFORM.HADOOP || DMLScript.rtplatform == RUNTIME_PLATFORM.SPARK) {
        // nothing to do here, return original statement block
        return Arrays.asList(sb);
    }
    if (// incl parfor
    sb instanceof WhileStatementBlock || sb instanceof ForStatementBlock) {
        ArrayList<String> candidates = new ArrayList<>();
        VariableSet updated = sb.variablesUpdated();
        VariableSet liveout = sb.liveOut();
        for (String varname : updated.getVariableNames()) {
            if (updated.getVariable(varname).getDataType() == DataType.MATRIX && // exclude local vars
            liveout.containsVariable(varname)) {
                if (sb instanceof WhileStatementBlock) {
                    WhileStatement wstmt = (WhileStatement) sb.getStatement(0);
                    if (rIsApplicableForUpdateInPlace(wstmt.getBody(), varname))
                        candidates.add(varname);
                } else if (sb instanceof ForStatementBlock) {
                    ForStatement wstmt = (ForStatement) sb.getStatement(0);
                    if (rIsApplicableForUpdateInPlace(wstmt.getBody(), varname))
                        candidates.add(varname);
                }
            }
        }
        sb.setUpdateInPlaceVars(candidates);
    }
    // return modified statement block
    return Arrays.asList(sb);
}
Also used : ForStatementBlock(org.apache.sysml.parser.ForStatementBlock) VariableSet(org.apache.sysml.parser.VariableSet) ArrayList(java.util.ArrayList) WhileStatement(org.apache.sysml.parser.WhileStatement) ForStatement(org.apache.sysml.parser.ForStatement) WhileStatementBlock(org.apache.sysml.parser.WhileStatementBlock)

Example 7 with VariableSet

use of org.apache.sysml.parser.VariableSet in project incubator-systemml by apache.

the class RewriteSplitDagDataDependentOperators method rewriteStatementBlock.

@Override
public List<StatementBlock> rewriteStatementBlock(StatementBlock sb, ProgramRewriteStatus state) {
    // DAG splits not required for forced single node
    if (DMLScript.rtplatform == RUNTIME_PLATFORM.SINGLE_NODE || !HopRewriteUtils.isLastLevelStatementBlock(sb))
        return Arrays.asList(sb);
    ArrayList<StatementBlock> ret = new ArrayList<>();
    // collect all unknown csv reads hops
    ArrayList<Hop> cand = new ArrayList<>();
    collectDataDependentOperators(sb.getHops(), cand);
    Hop.resetVisitStatus(sb.getHops());
    // split hop dag on demand
    if (!cand.isEmpty()) {
        // collect child operators of candidates (to prevent rewrite anomalies)
        HashSet<Hop> candChilds = new HashSet<>();
        collectCandidateChildOperators(cand, candChilds);
        try {
            // duplicate sb incl live variable sets
            StatementBlock sb1 = new StatementBlock();
            sb1.setDMLProg(sb.getDMLProg());
            sb1.setParseInfo(sb);
            sb1.setLiveIn(new VariableSet());
            sb1.setLiveOut(new VariableSet());
            // move data-dependent ops incl transient writes to new statement block
            // (and replace original persistent read with transient read)
            ArrayList<Hop> sb1hops = new ArrayList<>();
            for (Hop c : cand) {
                // if there are already transient writes use them and don't introduce artificial variables;
                // unless there are transient reads w/ the same variable name in the current dag which can
                // lead to invalid reordering if variable consumers are not feeding into the candidate op.
                boolean hasTWrites = hasTransientWriteParents(c);
                boolean moveTWrite = hasTWrites ? HopRewriteUtils.rHasSimpleReadChain(c, getFirstTransientWriteParent(c).getName()) : false;
                String varname = null;
                long rlen = c.getDim1();
                long clen = c.getDim2();
                long nnz = c.getNnz();
                UpdateType update = c.getUpdateType();
                int brlen = c.getRowsInBlock();
                int bclen = c.getColsInBlock();
                if (// reuse existing transient_write
                hasTWrites && moveTWrite) {
                    Hop twrite = getFirstTransientWriteParent(c);
                    varname = twrite.getName();
                    // create new transient read
                    DataOp tread = new DataOp(varname, c.getDataType(), c.getValueType(), DataOpTypes.TRANSIENTREAD, null, rlen, clen, nnz, update, brlen, bclen);
                    tread.setVisited();
                    HopRewriteUtils.copyLineNumbers(c, tread);
                    // replace data-dependent operator with transient read
                    ArrayList<Hop> parents = new ArrayList<>(c.getParent());
                    for (int i = 0; i < parents.size(); i++) {
                        // prevent concurrent modification by index access
                        Hop parent = parents.get(i);
                        if (!candChilds.contains(parent)) {
                            // anomaly filter
                            if (parent != twrite)
                                HopRewriteUtils.replaceChildReference(parent, c, tread);
                            else
                                sb.getHops().remove(parent);
                        }
                    }
                    // add data-dependent operator sub dag to first statement block
                    sb1hops.add(twrite);
                } else // create transient write to artificial variables
                {
                    varname = createCutVarName(false);
                    // create new transient read
                    DataOp tread = new DataOp(varname, c.getDataType(), c.getValueType(), DataOpTypes.TRANSIENTREAD, null, rlen, clen, nnz, update, brlen, bclen);
                    tread.setVisited();
                    HopRewriteUtils.copyLineNumbers(c, tread);
                    // replace data-dependent operator with transient read
                    ArrayList<Hop> parents = new ArrayList<>(c.getParent());
                    for (int i = 0; i < parents.size(); i++) {
                        // prevent concurrent modification by index access
                        Hop parent = parents.get(i);
                        if (// anomaly filter
                        !candChilds.contains(parent))
                            HopRewriteUtils.replaceChildReference(parent, c, tread);
                    }
                    // add data-dependent operator sub dag to first statement block
                    DataOp twrite = new DataOp(varname, c.getDataType(), c.getValueType(), c, DataOpTypes.TRANSIENTWRITE, null);
                    twrite.setVisited();
                    twrite.setOutputParams(rlen, clen, nnz, update, brlen, bclen);
                    HopRewriteUtils.copyLineNumbers(c, twrite);
                    sb1hops.add(twrite);
                }
                // update live in and out of new statement block (for piggybacking)
                DataIdentifier diVar = new DataIdentifier(varname);
                diVar.setDimensions(rlen, clen);
                diVar.setBlockDimensions(brlen, bclen);
                diVar.setDataType(c.getDataType());
                diVar.setValueType(c.getValueType());
                sb1.liveOut().addVariable(varname, new DataIdentifier(diVar));
                sb.liveIn().addVariable(varname, new DataIdentifier(diVar));
            }
            // ensure disjoint operators across DAGs (prevent replicated operations)
            handleReplicatedOperators(sb1hops, sb.getHops(), sb1.liveOut(), sb.liveIn());
            // deep copy new dag (in order to prevent any dangling references)
            sb1.setHops(Recompiler.deepCopyHopsDag(sb1hops));
            sb1.updateRecompilationFlag();
            // avoid later merge by other rewrites
            sb1.setSplitDag(true);
            // recursive application of rewrite rule (in case of multiple data dependent operators
            // with data dependencies in between each other)
            List<StatementBlock> tmp = rewriteStatementBlock(sb1, state);
            // add new statement blocks to output
            // statement block with data dependent hops
            ret.addAll(tmp);
            // statement block with remaining hops
            ret.add(sb);
            // avoid later merge by other rewrites
            sb.setSplitDag(true);
        } catch (Exception ex) {
            throw new HopsException("Failed to split hops dag for data dependent operators with unknown size.", ex);
        }
        LOG.debug("Applied splitDagDataDependentOperators (lines " + sb.getBeginLine() + "-" + sb.getEndLine() + ").");
    } else // keep original hop dag
    {
        ret.add(sb);
    }
    return ret;
}
Also used : DataIdentifier(org.apache.sysml.parser.DataIdentifier) ArrayList(java.util.ArrayList) Hop(org.apache.sysml.hops.Hop) HopsException(org.apache.sysml.hops.HopsException) UpdateType(org.apache.sysml.runtime.controlprogram.caching.MatrixObject.UpdateType) HopsException(org.apache.sysml.hops.HopsException) VariableSet(org.apache.sysml.parser.VariableSet) DataOp(org.apache.sysml.hops.DataOp) StatementBlock(org.apache.sysml.parser.StatementBlock) HashSet(java.util.HashSet)

Example 8 with VariableSet

use of org.apache.sysml.parser.VariableSet in project incubator-systemml by apache.

the class OptimizerRuleBased method rValidateUIPConsumerList.

/* 	
	 * This will validate candidate's consumer list.
	 * 
	 * @param pn:				OpNode of parfor loop
	 * @param uipCandHopHM:		Hashmap of UIPCandidateHop with name as a key.		
	 * @throws DMLRuntimeException
	 */
private void rValidateUIPConsumerList(OptNode pn, HashMap<String, ArrayList<UIPCandidateHop>> uipCandHopHM) throws DMLRuntimeException {
    if (!pn.isLeaf()) {
        if (pn.getNodeType() == OptNode.NodeType.FUNCCALL) {
            Hop hop = (Hop) OptTreeConverter.getAbstractPlanMapping().getMappedHop(pn.getID());
            rValidateUIPConsumerList(hop.getInput(), uipCandHopHM);
            return;
        }
        ProgramBlock pb = (ProgramBlock) OptTreeConverter.getAbstractPlanMapping().getMappedProg(pn.getID())[1];
        VariableSet varRead = pb.getStatementBlock().variablesRead();
        boolean bUIPCandHopRead = false;
        for (Entry<String, ArrayList<UIPCandidateHop>> entry : uipCandHopHM.entrySet()) {
            ArrayList<UIPCandidateHop> uipCandHopList = entry.getValue();
            if (uipCandHopList != null) {
                for (UIPCandidateHop uipCandHop : uipCandHopList) {
                    ArrayList<Hop> consumerHops = uipCandHop.getConsumerHops();
                    if (consumerHops != null) {
                        // remove candidate from the list.
                        for (Hop consumerHop : consumerHops) {
                            if (varRead.containsVariable(consumerHop.getName())) {
                                bUIPCandHopRead = true;
                                break;
                            }
                        }
                    }
                }
            }
        }
        // As none of the UIP candidates updated in this DAG, no need for further processing within this DAG
        if (!bUIPCandHopRead)
            return;
        for (OptNode optNode : pn.getChilds()) rValidateUIPConsumerList(optNode, uipCandHopHM);
    } else {
        OptTreePlanMappingAbstract map = OptTreeConverter.getAbstractPlanMapping();
        long ppid = map.getMappedParentID(map.getMappedParentID(pn.getID()));
        Object[] o = map.getMappedProg(ppid);
        ProgramBlock pb = (ProgramBlock) o[1];
        if (pb instanceof IfProgramBlock || pb instanceof WhileProgramBlock || //TODO
        (pb instanceof ForProgramBlock && !(pb instanceof ParForProgramBlock)))
            rValidateUIPConsumerList(pb, uipCandHopHM);
        long pid = map.getMappedParentID(pn.getID());
        o = map.getMappedProg(pid);
        pb = (ProgramBlock) o[1];
        Hop hop = map.getMappedHop(pn.getID());
        rValidateUIPConsumerList(hop, uipCandHopHM, pb.getStatementBlock().variablesRead());
    }
}
Also used : IfProgramBlock(org.apache.sysml.runtime.controlprogram.IfProgramBlock) ForProgramBlock(org.apache.sysml.runtime.controlprogram.ForProgramBlock) ParForProgramBlock(org.apache.sysml.runtime.controlprogram.ParForProgramBlock) Hop(org.apache.sysml.hops.Hop) MultiThreadedHop(org.apache.sysml.hops.Hop.MultiThreadedHop) ArrayList(java.util.ArrayList) WhileProgramBlock(org.apache.sysml.runtime.controlprogram.WhileProgramBlock) ParForProgramBlock(org.apache.sysml.runtime.controlprogram.ParForProgramBlock) VariableSet(org.apache.sysml.parser.VariableSet) FunctionProgramBlock(org.apache.sysml.runtime.controlprogram.FunctionProgramBlock) WhileProgramBlock(org.apache.sysml.runtime.controlprogram.WhileProgramBlock) ForProgramBlock(org.apache.sysml.runtime.controlprogram.ForProgramBlock) IfProgramBlock(org.apache.sysml.runtime.controlprogram.IfProgramBlock) ProgramBlock(org.apache.sysml.runtime.controlprogram.ProgramBlock) ParForProgramBlock(org.apache.sysml.runtime.controlprogram.ParForProgramBlock) MatrixObject(org.apache.sysml.runtime.controlprogram.caching.MatrixObject) RDDObject(org.apache.sysml.runtime.instructions.spark.data.RDDObject)

Example 9 with VariableSet

use of org.apache.sysml.parser.VariableSet in project incubator-systemml by apache.

the class OptimizerRuleBased method rGetUIPConsumerList.

/* 	
	 * This will get consumer list for candidate LeftIndexingOp.
	 * 
	 * @param pn:				OpNode of parfor loop
	 * @param uipCandHopHM:		Hashmap of UIPCandidateHop with name as a key.		
	 * @throws DMLRuntimeException
	 */
private void rGetUIPConsumerList(OptNode pn, HashMap<String, ArrayList<UIPCandidateHop>> uipCandHopHM) throws DMLRuntimeException {
    if (!pn.isLeaf()) {
        if (pn.getNodeType() == OptNode.NodeType.FUNCCALL)
            return;
        ProgramBlock pb = (ProgramBlock) OptTreeConverter.getAbstractPlanMapping().getMappedProg(pn.getID())[1];
        VariableSet varRead = pb.getStatementBlock().variablesRead();
        boolean bUIPCandHopRead = false;
        for (Entry<String, ArrayList<UIPCandidateHop>> entry : uipCandHopHM.entrySet()) {
            String uipCandHopID = entry.getKey();
            if (varRead.containsVariable(uipCandHopID)) {
                bUIPCandHopRead = true;
                break;
            }
        }
        // As none of the UIP candidates updated in this DAG, no need for further processing within this DAG
        if (!bUIPCandHopRead)
            return;
        for (OptNode optNode : pn.getChilds()) rGetUIPConsumerList(optNode, uipCandHopHM);
    } else {
        OptTreePlanMappingAbstract map = OptTreeConverter.getAbstractPlanMapping();
        long ppid = map.getMappedParentID(map.getMappedParentID(pn.getID()));
        Object[] o = map.getMappedProg(ppid);
        ProgramBlock pb = (ProgramBlock) o[1];
        Hop hop = (Hop) OptTreeConverter.getAbstractPlanMapping().getMappedHop(pn.getID());
        rGetUIPConsumerList(hop, uipCandHopHM);
        if (pb instanceof IfProgramBlock || pb instanceof WhileProgramBlock || //TODO
        (pb instanceof ForProgramBlock && !(pb instanceof ParForProgramBlock)))
            rGetUIPConsumerList(pb, uipCandHopHM);
    }
}
Also used : IfProgramBlock(org.apache.sysml.runtime.controlprogram.IfProgramBlock) ForProgramBlock(org.apache.sysml.runtime.controlprogram.ForProgramBlock) ParForProgramBlock(org.apache.sysml.runtime.controlprogram.ParForProgramBlock) ArrayList(java.util.ArrayList) Hop(org.apache.sysml.hops.Hop) MultiThreadedHop(org.apache.sysml.hops.Hop.MultiThreadedHop) WhileProgramBlock(org.apache.sysml.runtime.controlprogram.WhileProgramBlock) ParForProgramBlock(org.apache.sysml.runtime.controlprogram.ParForProgramBlock) VariableSet(org.apache.sysml.parser.VariableSet) FunctionProgramBlock(org.apache.sysml.runtime.controlprogram.FunctionProgramBlock) WhileProgramBlock(org.apache.sysml.runtime.controlprogram.WhileProgramBlock) ForProgramBlock(org.apache.sysml.runtime.controlprogram.ForProgramBlock) IfProgramBlock(org.apache.sysml.runtime.controlprogram.IfProgramBlock) ProgramBlock(org.apache.sysml.runtime.controlprogram.ProgramBlock) ParForProgramBlock(org.apache.sysml.runtime.controlprogram.ParForProgramBlock) MatrixObject(org.apache.sysml.runtime.controlprogram.caching.MatrixObject) RDDObject(org.apache.sysml.runtime.instructions.spark.data.RDDObject)

Aggregations

VariableSet (org.apache.sysml.parser.VariableSet)9 ArrayList (java.util.ArrayList)7 Hop (org.apache.sysml.hops.Hop)6 DataIdentifier (org.apache.sysml.parser.DataIdentifier)4 DataOp (org.apache.sysml.hops.DataOp)3 MultiThreadedHop (org.apache.sysml.hops.Hop.MultiThreadedHop)3 StatementBlock (org.apache.sysml.parser.StatementBlock)3 ForProgramBlock (org.apache.sysml.runtime.controlprogram.ForProgramBlock)3 FunctionProgramBlock (org.apache.sysml.runtime.controlprogram.FunctionProgramBlock)3 IfProgramBlock (org.apache.sysml.runtime.controlprogram.IfProgramBlock)3 ParForProgramBlock (org.apache.sysml.runtime.controlprogram.ParForProgramBlock)3 ProgramBlock (org.apache.sysml.runtime.controlprogram.ProgramBlock)3 WhileProgramBlock (org.apache.sysml.runtime.controlprogram.WhileProgramBlock)3 HopsException (org.apache.sysml.hops.HopsException)2 ForStatementBlock (org.apache.sysml.parser.ForStatementBlock)2 WhileStatementBlock (org.apache.sysml.parser.WhileStatementBlock)2 MatrixObject (org.apache.sysml.runtime.controlprogram.caching.MatrixObject)2 UpdateType (org.apache.sysml.runtime.controlprogram.caching.MatrixObject.UpdateType)2 Data (org.apache.sysml.runtime.instructions.cp.Data)2 RDDObject (org.apache.sysml.runtime.instructions.spark.data.RDDObject)2