Search in sources :

Example 31 with LocalVariableMap

use of org.apache.sysml.runtime.controlprogram.LocalVariableMap in project incubator-systemml by apache.

the class ResourceOptimizer method getProgramCosts.

private static double getProgramCosts(ProgramBlock pb) {
    double val = 0;
    if (COST_INDIVIDUAL_BLOCKS) {
        LocalVariableMap vars = new LocalVariableMap();
        collectReadVariables(pb.getStatementBlock().getHops(), vars);
        ExecutionContext ec = ExecutionContextFactory.createContext(false, null);
        ec.setVariables(vars);
        val = CostEstimationWrapper.getTimeEstimate(pb, ec, false);
    } else {
        // we need to cost the entire program in order to take in-memory status into account
        ExecutionContext ec = ExecutionContextFactory.createContext();
        val = CostEstimationWrapper.getTimeEstimate(pb.getProgram(), ec);
    }
    _cntCostPB++;
    return val;
}
Also used : ExecutionContext(org.apache.sysml.runtime.controlprogram.context.ExecutionContext) LocalVariableMap(org.apache.sysml.runtime.controlprogram.LocalVariableMap)

Example 32 with LocalVariableMap

use of org.apache.sysml.runtime.controlprogram.LocalVariableMap in project incubator-systemml by apache.

the class OptimizerRuleBased method rewriteSetInPlaceResultIndexing.

///////
//REWRITE set in-place result indexing
///
protected void rewriteSetInPlaceResultIndexing(OptNode pn, double M, LocalVariableMap vars, HashSet<String> inPlaceResultVars, ExecutionContext ec) throws DMLRuntimeException {
    //assertions (warnings of corrupt optimizer decisions)
    if (pn.getNodeType() != NodeType.PARFOR)
        LOG.warn(getOptMode() + " OPT: Set in-place result update is only applicable for a ParFor node.");
    boolean apply = false;
    ParForProgramBlock pfpb = (ParForProgramBlock) OptTreeConverter.getAbstractPlanMapping().getMappedProg(pn.getID())[1];
    //note currently we decide for all result vars jointly, i.e.,
    //only if all fit pinned in remaining budget, we apply this rewrite.
    ArrayList<String> retVars = pfpb.getResultVariables();
    //compute total sum of pinned result variable memory
    double sum = computeTotalSizeResultVariables(retVars, vars, pfpb.getDegreeOfParallelism());
    //NOTE: currently this rule is too conservative (the result variable is assumed to be dense and
    //most importantly counted twice if this is part of the maximum operation)
    HashMap<String, ArrayList<UIPCandidateHop>> uipCandHopHM = new HashMap<String, ArrayList<UIPCandidateHop>>();
    double totalMem = Math.max((M + sum), rComputeSumMemoryIntermediates(pn, new HashSet<String>(), uipCandHopHM));
    //optimization decision
    if (//basic correctness constraint
    rHasOnlyInPlaceSafeLeftIndexing(pn, retVars)) {
        //result update in-place for MR/Spark (w/ remote memory constraint)
        if ((pfpb.getExecMode() == PExecMode.REMOTE_MR_DP || pfpb.getExecMode() == PExecMode.REMOTE_MR || pfpb.getExecMode() == PExecMode.REMOTE_SPARK_DP || pfpb.getExecMode() == PExecMode.REMOTE_SPARK) && totalMem < _rm) {
            apply = true;
        } else //result update in-place for CP (w/ local memory constraint)
        if (pfpb.getExecMode() == PExecMode.LOCAL && totalMem * pfpb.getDegreeOfParallelism() < _lm && //no forced mr/spark execution  
        pn.isCPOnly()) {
            apply = true;
        }
    }
    if (APPLY_REWRITE_UPDATE_INPLACE_INTERMEDIATE && LOG.isDebugEnabled())
        listUIPRes.remove();
    //modify result variable meta data, if rewrite applied
    if (apply) {
        //will be serialized and transfered via symbol table 
        for (String var : retVars) {
            Data dat = vars.get(var);
            if (dat instanceof MatrixObject)
                ((MatrixObject) dat).setUpdateType(UpdateType.INPLACE_PINNED);
        }
        inPlaceResultVars.addAll(retVars);
        if (APPLY_REWRITE_UPDATE_INPLACE_INTERMEDIATE) {
            isUpdateInPlaceApplicable(pn, uipCandHopHM);
            boolean bAnyUIPApplicable = false;
            for (Entry<String, ArrayList<UIPCandidateHop>> entry : uipCandHopHM.entrySet()) {
                ArrayList<UIPCandidateHop> uipCandHopList = entry.getValue();
                if (uipCandHopList != null) {
                    for (UIPCandidateHop uipCandHop : uipCandHopList) if (uipCandHop.isIntermediate() && uipCandHop.isLoopApplicable() && uipCandHop.isUpdateInPlace()) {
                        uipCandHop.getHop().setUpdateType(UpdateType.INPLACE_PINNED);
                        bAnyUIPApplicable = true;
                        if (LOG.isDebugEnabled())
                            listUIPRes.get().add(uipCandHop.getHop().getName());
                    }
                }
            }
            if (bAnyUIPApplicable)
                try {
                    //Recompile this block recursively if there is any update in place applicable.
                    LocalVariableMap localVaraibleMap = (LocalVariableMap) ec.getVariables().clone();
                    Recompiler.recompileProgramBlockHierarchy(pfpb.getChildBlocks(), localVaraibleMap, 0L, true);
                } catch (Exception ex) {
                    throw new DMLRuntimeException(ex);
                }
        }
    }
    if (APPLY_REWRITE_UPDATE_INPLACE_INTERMEDIATE && LOG.isTraceEnabled()) {
        LOG.trace("UpdateInPlace = " + apply + " for lines between " + pn.getBeginLine() + " and " + pn.getEndLine() + " for " + uipCandHopHM.size() + " intermediate matrix objects:" + uipCandHopHM.keySet().toString());
        for (Entry<String, ArrayList<UIPCandidateHop>> entry : uipCandHopHM.entrySet()) {
            ArrayList<UIPCandidateHop> uipCandHopList = entry.getValue();
            if (uipCandHopList != null) {
                for (UIPCandidateHop uipCandHop : uipCandHopList) {
                    if (uipCandHop.getHop() != null) {
                        LOG.trace("Matrix Object: Name: " + uipCandHop.getHop().getName() + "<" + uipCandHop.getHop().getBeginLine() + "," + uipCandHop.getHop().getEndLine() + ">, InLoop:" + uipCandHop.isLoopApplicable() + ", UIPApplicable:" + uipCandHop.isUpdateInPlace() + ", HopUIPApplicable:" + uipCandHop.getHop().getUpdateType());
                        LOG.trace("Explain Candidate HOP after recompile");
                        LOG.trace(Explain.explain(uipCandHop.getHop()));
                    } else {
                        LOG.trace("Matrix Object: Name: " + uipCandHop.getLixHop().getName() + "<" + uipCandHop.getLixHop().getBeginLine() + "," + uipCandHop.getLixHop().getEndLine() + ">, InLoop:" + uipCandHop.isLoopApplicable() + ", Not an Intermediate matrix object");
                    }
                }
            }
        }
    }
    LOG.debug(getOptMode() + " OPT: rewrite 'set in-place result indexing' - result=" + apply + " (" + ProgramConverter.serializeStringCollection(inPlaceResultVars) + ", M=" + toMB(totalMem) + ")");
}
Also used : MatrixObject(org.apache.sysml.runtime.controlprogram.caching.MatrixObject) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Data(org.apache.sysml.runtime.instructions.cp.Data) MatrixFormatMetaData(org.apache.sysml.runtime.matrix.MatrixFormatMetaData) HopsException(org.apache.sysml.hops.HopsException) DMLRuntimeException(org.apache.sysml.runtime.DMLRuntimeException) LopsException(org.apache.sysml.lops.LopsException) LanguageException(org.apache.sysml.parser.LanguageException) IOException(java.io.IOException) ParForProgramBlock(org.apache.sysml.runtime.controlprogram.ParForProgramBlock) DMLRuntimeException(org.apache.sysml.runtime.DMLRuntimeException) LocalVariableMap(org.apache.sysml.runtime.controlprogram.LocalVariableMap) HashSet(java.util.HashSet)

Example 33 with LocalVariableMap

use of org.apache.sysml.runtime.controlprogram.LocalVariableMap in project incubator-systemml by apache.

the class InterProceduralAnalysis method propagateStatisticsIntoFunctions.

/**
	 * Propagate statistics from the calling program into a function
	 * block.
	 *
	 * @param prog  The DML program.
	 * @param hop HOP to propagate statistics into.
	 * @param fcand  Function candidates.
	 * @param callVars  Calling program's map of variables eligible for
	 *                     propagation.
	 * @param fcandSafeNNZ  Function candidate safe non-zeros.
	 * @param unaryFcands  Unary function candidates.
	 * @param fnStack  Function stack to determine current scope.
	 * @throws HopsException  If a HopsException occurs.
	 * @throws ParseException  If a ParseException occurs.
	 */
private void propagateStatisticsIntoFunctions(DMLProgram prog, Hop hop, Map<String, Integer> fcand, LocalVariableMap callVars, Map<String, Set<Long>> fcandSafeNNZ, Set<String> unaryFcands, Set<String> fnStack) throws HopsException, ParseException {
    if (hop.isVisited())
        return;
    for (Hop c : hop.getInput()) propagateStatisticsIntoFunctions(prog, c, fcand, callVars, fcandSafeNNZ, unaryFcands, fnStack);
    if (hop instanceof FunctionOp) {
        //maintain counters and investigate functions if not seen so far
        FunctionOp fop = (FunctionOp) hop;
        String fkey = DMLProgram.constructFunctionKey(fop.getFunctionNamespace(), fop.getFunctionName());
        if (fop.getFunctionType() == FunctionType.DML) {
            FunctionStatementBlock fsb = prog.getFunctionStatementBlock(fop.getFunctionNamespace(), fop.getFunctionName());
            FunctionStatement fstmt = (FunctionStatement) fsb.getStatement(0);
            if (fcand.containsKey(fkey) && //prevent recursion	
            !fnStack.contains(fkey)) {
                //maintain function call stack
                fnStack.add(fkey);
                //create mapping and populate symbol table for refresh
                LocalVariableMap tmpVars = new LocalVariableMap();
                populateLocalVariableMapForFunctionCall(fstmt, fop, callVars, tmpVars, fcandSafeNNZ.get(fkey), fcand.get(fkey));
                //recursively propagate statistics
                propagateStatisticsAcrossBlock(fsb, fcand, tmpVars, fcandSafeNNZ, unaryFcands, fnStack);
                //extract vars from symbol table, re-map and refresh main program
                extractFunctionCallReturnStatistics(fstmt, fop, tmpVars, callVars, true);
                //maintain function call stack
                fnStack.remove(fkey);
            } else if (unaryFcands.contains(fkey)) {
                extractFunctionCallEquivalentReturnStatistics(fstmt, fop, callVars);
            } else {
                extractFunctionCallUnknownReturnStatistics(fstmt, fop, callVars);
            }
        } else if (fop.getFunctionType() == FunctionType.EXTERNAL_FILE || fop.getFunctionType() == FunctionType.EXTERNAL_MEM) {
            //infer output size for known external functions
            FunctionStatementBlock fsb = prog.getFunctionStatementBlock(fop.getFunctionNamespace(), fop.getFunctionName());
            ExternalFunctionStatement fstmt = (ExternalFunctionStatement) fsb.getStatement(0);
            if (PROPAGATE_KNOWN_UDF_STATISTICS)
                extractExternalFunctionCallReturnStatistics(fstmt, fop, callVars);
            else
                extractFunctionCallUnknownReturnStatistics(fstmt, fop, callVars);
        }
    }
    hop.setVisited();
}
Also used : ExternalFunctionStatement(org.apache.sysml.parser.ExternalFunctionStatement) FunctionStatement(org.apache.sysml.parser.FunctionStatement) FunctionStatementBlock(org.apache.sysml.parser.FunctionStatementBlock) LocalVariableMap(org.apache.sysml.runtime.controlprogram.LocalVariableMap) Hop(org.apache.sysml.hops.Hop) ExternalFunctionStatement(org.apache.sysml.parser.ExternalFunctionStatement) FunctionOp(org.apache.sysml.hops.FunctionOp)

Example 34 with LocalVariableMap

use of org.apache.sysml.runtime.controlprogram.LocalVariableMap in project incubator-systemml by apache.

the class InterProceduralAnalysis method analyzeProgram.

/**
	 * Public interface to perform IPA over a given DML program.
	 * 
	 * @param dmlp the dml program
	 * @throws HopsException if HopsException occurs
	 * @throws ParseException if ParseException occurs
	 * @throws LanguageException if LanguageException occurs
	 */
public void analyzeProgram(DMLProgram dmlp) throws HopsException, ParseException, LanguageException {
    FunctionCallGraph fgraph = new FunctionCallGraph(dmlp);
    //step 1: get candidates for statistics propagation into functions (if required)
    Map<String, Integer> fcandCounts = new HashMap<String, Integer>();
    Map<String, FunctionOp> fcandHops = new HashMap<String, FunctionOp>();
    Map<String, Set<Long>> fcandSafeNNZ = new HashMap<String, Set<Long>>();
    if (!dmlp.getFunctionStatementBlocks().isEmpty()) {
        for (//get candidates (over entire program)
        StatementBlock sb : //get candidates (over entire program)
        dmlp.getStatementBlocks()) getFunctionCandidatesForStatisticPropagation(sb, fcandCounts, fcandHops);
        pruneFunctionCandidatesForStatisticPropagation(fcandCounts, fcandHops);
        determineFunctionCandidatesNNZPropagation(fcandHops, fcandSafeNNZ);
        DMLTranslator.resetHopsDAGVisitStatus(dmlp);
    }
    //step 2: get unary dimension-preserving non-candidate functions
    Collection<String> unaryFcandTmp = fgraph.getReachableFunctions(fcandCounts.keySet());
    HashSet<String> unaryFcands = new HashSet<String>();
    if (!unaryFcandTmp.isEmpty() && UNARY_DIMS_PRESERVING_FUNS) {
        for (String tmp : unaryFcandTmp) if (isUnarySizePreservingFunction(dmlp.getFunctionStatementBlock(tmp)))
            unaryFcands.add(tmp);
    }
    //step 3: propagate statistics and scalars into functions and across DAGs
    if (!fcandCounts.isEmpty() || INTRA_PROCEDURAL_ANALYSIS) {
        //(callVars used to chain outputs/inputs of multiple functions calls) 
        LocalVariableMap callVars = new LocalVariableMap();
        for (//propagate stats into candidates
        StatementBlock sb : //propagate stats into candidates
        dmlp.getStatementBlocks()) propagateStatisticsAcrossBlock(sb, fcandCounts, callVars, fcandSafeNNZ, unaryFcands, new HashSet<String>());
    }
    //step 4: remove unused functions (e.g., inlined or never called)
    if (REMOVE_UNUSED_FUNCTIONS) {
        removeUnusedFunctions(dmlp, fgraph);
    }
    //step 5: flag functions with loops for 'recompile-on-entry'
    if (FLAG_FUNCTION_RECOMPILE_ONCE) {
        flagFunctionsForRecompileOnce(dmlp, fgraph);
    }
    //step 6: set global data flow properties
    if (REMOVE_UNNECESSARY_CHECKPOINTS && OptimizerUtils.isSparkExecutionMode()) {
        //remove unnecessary checkpoint before update 
        removeCheckpointBeforeUpdate(dmlp);
        //move necessary checkpoint after update
        moveCheckpointAfterUpdate(dmlp);
        //remove unnecessary checkpoint read-{write|uagg}
        removeCheckpointReadWrite(dmlp);
    }
    //step 7: remove constant binary ops
    if (REMOVE_CONSTANT_BINARY_OPS) {
        removeConstantBinaryOps(dmlp);
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) FunctionOp(org.apache.sysml.hops.FunctionOp) LocalVariableMap(org.apache.sysml.runtime.controlprogram.LocalVariableMap) FunctionStatementBlock(org.apache.sysml.parser.FunctionStatementBlock) IfStatementBlock(org.apache.sysml.parser.IfStatementBlock) WhileStatementBlock(org.apache.sysml.parser.WhileStatementBlock) ForStatementBlock(org.apache.sysml.parser.ForStatementBlock) StatementBlock(org.apache.sysml.parser.StatementBlock) HashSet(java.util.HashSet)

Example 35 with LocalVariableMap

use of org.apache.sysml.runtime.controlprogram.LocalVariableMap in project incubator-systemml by apache.

the class GDFEnumOptimizer method costRuntimePlan.

private static double costRuntimePlan(Plan p) throws DMLRuntimeException {
    Program prog = p.getNode().getProgram();
    if (prog == null)
        throw new DMLRuntimeException("Program not available for runtime plan costing.");
    //put data flow configuration into program
    rSetRuntimePlanConfig(p, new HashMap<Long, Plan>());
    double costs = -1;
    if (COST_FULL_PROGRAMS || (p.getNode().getHop() == null || p.getNode().getProgramBlock() == null)) {
        //recompile entire runtime program
        Recompiler.recompileProgramBlockHierarchy(prog.getProgramBlocks(), new LocalVariableMap(), 0, false);
        _compiledPlans++;
        //cost entire runtime program
        ExecutionContext ec = ExecutionContextFactory.createContext(prog);
        costs = CostEstimationWrapper.getTimeEstimate(prog, ec);
    } else {
        Hop currentHop = p.getNode().getHop();
        ProgramBlock pb = p.getNode().getProgramBlock();
        try {
            //keep the old dag roots
            ArrayList<Hop> oldRoots = pb.getStatementBlock().get_hops();
            Hop tmpHop = null;
            if (!(currentHop instanceof DataOp && ((DataOp) currentHop).isWrite())) {
                ArrayList<Hop> newRoots = new ArrayList<Hop>();
                tmpHop = new DataOp("_tmp", currentHop.getDataType(), currentHop.getValueType(), currentHop, DataOpTypes.TRANSIENTWRITE, "tmp");
                //ensure recursive visitstatus reset on recompile
                tmpHop.setVisited();
                newRoots.add(tmpHop);
                pb.getStatementBlock().set_hops(newRoots);
            }
            //recompile modified runtime program
            Recompiler.recompileProgramBlockHierarchy(prog.getProgramBlocks(), new LocalVariableMap(), 0, false);
            _compiledPlans++;
            //cost partial runtime program up to current hop
            ExecutionContext ec = ExecutionContextFactory.createContext(prog);
            costs = CostEstimationWrapper.getTimeEstimate(prog, ec);
            //restore original hop dag
            if (tmpHop != null)
                HopRewriteUtils.removeChildReference(tmpHop, currentHop);
            pb.getStatementBlock().set_hops(oldRoots);
        } catch (HopsException ex) {
            throw new DMLRuntimeException(ex);
        }
    }
    //release forced data flow configuration from program
    rResetRuntimePlanConfig(p, new HashMap<Long, Plan>());
    _costedPlans++;
    return costs;
}
Also used : Program(org.apache.sysml.runtime.controlprogram.Program) Hop(org.apache.sysml.hops.Hop) ArrayList(java.util.ArrayList) HopsException(org.apache.sysml.hops.HopsException) DMLRuntimeException(org.apache.sysml.runtime.DMLRuntimeException) ExecutionContext(org.apache.sysml.runtime.controlprogram.context.ExecutionContext) LocalVariableMap(org.apache.sysml.runtime.controlprogram.LocalVariableMap) ProgramBlock(org.apache.sysml.runtime.controlprogram.ProgramBlock) DataOp(org.apache.sysml.hops.DataOp)

Aggregations

LocalVariableMap (org.apache.sysml.runtime.controlprogram.LocalVariableMap)36 ForStatementBlock (org.apache.sysml.parser.ForStatementBlock)11 IfStatementBlock (org.apache.sysml.parser.IfStatementBlock)11 StatementBlock (org.apache.sysml.parser.StatementBlock)11 WhileStatementBlock (org.apache.sysml.parser.WhileStatementBlock)11 ArrayList (java.util.ArrayList)9 FunctionStatementBlock (org.apache.sysml.parser.FunctionStatementBlock)9 HashMap (java.util.HashMap)8 HashSet (java.util.HashSet)7 FunctionStatement (org.apache.sysml.parser.FunctionStatement)6 DMLRuntimeException (org.apache.sysml.runtime.DMLRuntimeException)6 FunctionProgramBlock (org.apache.sysml.runtime.controlprogram.FunctionProgramBlock)6 MatrixObject (org.apache.sysml.runtime.controlprogram.caching.MatrixObject)6 FunctionOp (org.apache.sysml.hops.FunctionOp)5 ExternalFunctionStatement (org.apache.sysml.parser.ExternalFunctionStatement)5 ForProgramBlock (org.apache.sysml.runtime.controlprogram.ForProgramBlock)5 IfProgramBlock (org.apache.sysml.runtime.controlprogram.IfProgramBlock)5 WhileProgramBlock (org.apache.sysml.runtime.controlprogram.WhileProgramBlock)5 ExecutionContext (org.apache.sysml.runtime.controlprogram.context.ExecutionContext)5 Path (org.apache.hadoop.fs.Path)4