Search in sources :

Example 1 with InterProceduralAnalysis

use of org.apache.sysml.hops.ipa.InterProceduralAnalysis in project incubator-systemml by apache.

the class OptimizationWrapper method optimize.

@SuppressWarnings("unused")
private static void optimize(POptMode otype, int ck, double cm, ParForStatementBlock sb, ParForProgramBlock pb, ExecutionContext ec, boolean monitor) throws DMLRuntimeException {
    Timing time = new Timing(true);
    //maintain statistics
    if (DMLScript.STATISTICS)
        Statistics.incrementParForOptimCount();
    //create specified optimizer
    Optimizer opt = createOptimizer(otype);
    CostModelType cmtype = opt.getCostModelType();
    LOG.trace("ParFOR Opt: Created optimizer (" + otype + "," + opt.getPlanInputType() + "," + opt.getCostModelType());
    OptTree tree = null;
    //recompile parfor body 
    if (ConfigurationManager.isDynamicRecompilation()) {
        ForStatement fs = (ForStatement) sb.getStatement(0);
        //debug output before recompilation
        if (LOG.isDebugEnabled()) {
            try {
                tree = OptTreeConverter.createOptTree(ck, cm, opt.getPlanInputType(), sb, pb, ec);
                LOG.debug("ParFOR Opt: Input plan (before recompilation):\n" + tree.explain(false));
                OptTreeConverter.clear();
            } catch (Exception ex) {
                throw new DMLRuntimeException("Unable to create opt tree.", ex);
            }
        }
        //separate propagation required because recompile in-place without literal replacement)
        try {
            LocalVariableMap constVars = ProgramRecompiler.getReusableScalarVariables(sb.getDMLProg(), sb, ec.getVariables());
            ProgramRecompiler.replaceConstantScalarVariables(sb, constVars);
        } catch (Exception ex) {
            throw new DMLRuntimeException(ex);
        }
        //program rewrites (e.g., constant folding, branch removal) according to replaced literals
        try {
            ProgramRewriter rewriter = createProgramRewriterWithRuleSets();
            ProgramRewriteStatus state = new ProgramRewriteStatus();
            rewriter.rewriteStatementBlockHopDAGs(sb, state);
            fs.setBody(rewriter.rewriteStatementBlocks(fs.getBody(), state));
            if (state.getRemovedBranches()) {
                LOG.debug("ParFOR Opt: Removed branches during program rewrites, rebuilding runtime program");
                pb.setChildBlocks(ProgramRecompiler.generatePartitialRuntimeProgram(pb.getProgram(), fs.getBody()));
            }
        } catch (Exception ex) {
            throw new DMLRuntimeException(ex);
        }
        //recompilation of parfor body and called functions (if safe)
        try {
            //core parfor body recompilation (based on symbol table entries)
            //* clone of variables in order to allow for statistics propagation across DAGs
            //(tid=0, because deep copies created after opt)
            LocalVariableMap tmp = (LocalVariableMap) ec.getVariables().clone();
            Recompiler.recompileProgramBlockHierarchy(pb.getChildBlocks(), tmp, 0, true);
            //inter-procedural optimization (based on previous recompilation)
            if (pb.hasFunctions()) {
                InterProceduralAnalysis ipa = new InterProceduralAnalysis();
                Set<String> fcand = ipa.analyzeSubProgram(sb);
                if (!fcand.isEmpty()) {
                    //regenerate runtime program of modified functions
                    for (String func : fcand) {
                        String[] funcparts = DMLProgram.splitFunctionKey(func);
                        FunctionProgramBlock fpb = pb.getProgram().getFunctionProgramBlock(funcparts[0], funcparts[1]);
                        //reset recompilation flags according to recompileOnce because it is only safe if function is recompileOnce 
                        //because then recompiled for every execution (otherwise potential issues if func also called outside parfor)
                        Recompiler.recompileProgramBlockHierarchy(fpb.getChildBlocks(), new LocalVariableMap(), 0, fpb.isRecompileOnce());
                    }
                }
            }
        } catch (Exception ex) {
            throw new DMLRuntimeException(ex);
        }
    }
    //create opt tree (before optimization)
    try {
        tree = OptTreeConverter.createOptTree(ck, cm, opt.getPlanInputType(), sb, pb, ec);
        LOG.debug("ParFOR Opt: Input plan (before optimization):\n" + tree.explain(false));
    } catch (Exception ex) {
        throw new DMLRuntimeException("Unable to create opt tree.", ex);
    }
    //create cost estimator
    CostEstimator est = createCostEstimator(cmtype, ec.getVariables());
    LOG.trace("ParFOR Opt: Created cost estimator (" + cmtype + ")");
    //core optimize
    opt.optimize(sb, pb, tree, est, ec);
    LOG.debug("ParFOR Opt: Optimized plan (after optimization): \n" + tree.explain(false));
    //assert plan correctness
    if (CHECK_PLAN_CORRECTNESS && LOG.isDebugEnabled()) {
        try {
            OptTreePlanChecker.checkProgramCorrectness(pb, sb, new HashSet<String>());
            LOG.debug("ParFOR Opt: Checked plan and program correctness.");
        } catch (Exception ex) {
            throw new DMLRuntimeException("Failed to check program correctness.", ex);
        }
    }
    long ltime = (long) time.stop();
    LOG.trace("ParFOR Opt: Optimized plan in " + ltime + "ms.");
    if (DMLScript.STATISTICS)
        Statistics.incrementParForOptimTime(ltime);
    //cleanup phase
    OptTreeConverter.clear();
    //monitor stats
    if (monitor) {
        StatisticMonitor.putPFStat(pb.getID(), Stat.OPT_OPTIMIZER, otype.ordinal());
        StatisticMonitor.putPFStat(pb.getID(), Stat.OPT_NUMTPLANS, opt.getNumTotalPlans());
        StatisticMonitor.putPFStat(pb.getID(), Stat.OPT_NUMEPLANS, opt.getNumEvaluatedPlans());
    }
}
Also used : FunctionProgramBlock(org.apache.sysml.runtime.controlprogram.FunctionProgramBlock) ProgramRewriter(org.apache.sysml.hops.rewrite.ProgramRewriter) DMLRuntimeException(org.apache.sysml.runtime.DMLRuntimeException) DMLRuntimeException(org.apache.sysml.runtime.DMLRuntimeException) LocalVariableMap(org.apache.sysml.runtime.controlprogram.LocalVariableMap) CostModelType(org.apache.sysml.runtime.controlprogram.parfor.opt.Optimizer.CostModelType) InterProceduralAnalysis(org.apache.sysml.hops.ipa.InterProceduralAnalysis) Timing(org.apache.sysml.runtime.controlprogram.parfor.stat.Timing) ForStatement(org.apache.sysml.parser.ForStatement) ProgramRewriteStatus(org.apache.sysml.hops.rewrite.ProgramRewriteStatus)

Example 2 with InterProceduralAnalysis

use of org.apache.sysml.hops.ipa.InterProceduralAnalysis in project incubator-systemml by apache.

the class DMLTranslator method rewriteHopsDAG.

public void rewriteHopsDAG(DMLProgram dmlp) throws ParseException, LanguageException, HopsException {
    //apply hop rewrites (static rewrites)
    ProgramRewriter rewriter = new ProgramRewriter(true, false);
    rewriter.rewriteProgramHopDAGs(dmlp);
    resetHopsDAGVisitStatus(dmlp);
    //propagate size information from main into functions (but conservatively)
    if (OptimizerUtils.ALLOW_INTER_PROCEDURAL_ANALYSIS) {
        InterProceduralAnalysis ipa = new InterProceduralAnalysis();
        ipa.analyzeProgram(dmlp);
        resetHopsDAGVisitStatus(dmlp);
        if (OptimizerUtils.ALLOW_IPA_SECOND_CHANCE) {
            // SECOND CHANCE:
            // Rerun static rewrites + IPA to allow for further improvements, such as making use
            // of constant folding (static rewrite) after scalar -> literal replacement (IPA),
            // and then further scalar -> literal replacement (IPA).
            rewriter.rewriteProgramHopDAGs(dmlp);
            resetHopsDAGVisitStatus(dmlp);
            ipa.analyzeProgram(dmlp);
            resetHopsDAGVisitStatus(dmlp);
        }
    }
    //apply hop rewrites (dynamic rewrites, after IPA)
    ProgramRewriter rewriter2 = new ProgramRewriter(false, true);
    rewriter2.rewriteProgramHopDAGs(dmlp);
    resetHopsDAGVisitStatus(dmlp);
    // Compute memory estimates for all the hops. These estimates are used
    // subsequently in various optimizations, e.g. CP vs. MR scheduling and parfor.
    refreshMemEstimates(dmlp);
    resetHopsDAGVisitStatus(dmlp);
}
Also used : ProgramRewriter(org.apache.sysml.hops.rewrite.ProgramRewriter) InterProceduralAnalysis(org.apache.sysml.hops.ipa.InterProceduralAnalysis)

Aggregations

InterProceduralAnalysis (org.apache.sysml.hops.ipa.InterProceduralAnalysis)2 ProgramRewriter (org.apache.sysml.hops.rewrite.ProgramRewriter)2 ProgramRewriteStatus (org.apache.sysml.hops.rewrite.ProgramRewriteStatus)1 ForStatement (org.apache.sysml.parser.ForStatement)1 DMLRuntimeException (org.apache.sysml.runtime.DMLRuntimeException)1 FunctionProgramBlock (org.apache.sysml.runtime.controlprogram.FunctionProgramBlock)1 LocalVariableMap (org.apache.sysml.runtime.controlprogram.LocalVariableMap)1 CostModelType (org.apache.sysml.runtime.controlprogram.parfor.opt.Optimizer.CostModelType)1 Timing (org.apache.sysml.runtime.controlprogram.parfor.stat.Timing)1