Search in sources :

Example 1 with MemoTable

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

the class Recompiler method recompileHopsDag.

/**
	 * A) Recompile basic program block hop DAG.
	 * 	
	 * We support to basic types inplace or via deep copy. Deep copy is the default and is required 
	 * in order to apply non-reversible rewrites. In-place is required in order to modify the existing
	 * hops (e.g., for parfor pre-recompilation).
	 * 
	 * @param sb statement block
	 * @param hops high-level operators
	 * @param vars local variable map
	 * @param status the recompile status
	 * @param inplace true if in place
	 * @param litreplace true if literal replacement
	 * @param tid thread id
	 * @return list of instructions
	 * @throws DMLRuntimeException if DMLRuntimeException occurs
	 * @throws HopsException if HopsException occurs
	 * @throws LopsException if LopsException occurs
	 * @throws IOException if IOException occurs
	 */
public static ArrayList<Instruction> recompileHopsDag(StatementBlock sb, ArrayList<Hop> hops, LocalVariableMap vars, RecompileStatus status, boolean inplace, boolean litreplace, long tid) throws DMLRuntimeException, HopsException, LopsException, IOException {
    ArrayList<Instruction> newInst = null;
    //however, we create deep copies for most dags to allow for concurrent recompile
    synchronized (hops) {
        LOG.debug("\n**************** Optimizer (Recompile) *************\nMemory Budget = " + OptimizerUtils.toMB(OptimizerUtils.getLocalMemBudget()) + " MB");
        // prepare hops dag for recompile
        if (!inplace) {
            // deep copy hop dag (for non-reversable rewrites)
            hops = deepCopyHopsDag(hops);
        } else {
            // clear existing lops
            Hop.resetVisitStatus(hops);
            for (Hop hopRoot : hops) rClearLops(hopRoot);
        }
        // replace scalar reads with literals 
        if (!inplace && litreplace) {
            Hop.resetVisitStatus(hops);
            for (Hop hopRoot : hops) rReplaceLiterals(hopRoot, vars, false);
        }
        // refresh matrix characteristics (update stats)			
        Hop.resetVisitStatus(hops);
        for (Hop hopRoot : hops) rUpdateStatistics(hopRoot, vars);
        // dynamic hop rewrites
        if (!inplace) {
            _rewriter.get().rewriteHopDAGs(hops, null);
            //update stats after rewrites
            Hop.resetVisitStatus(hops);
            for (Hop hopRoot : hops) rUpdateStatistics(hopRoot, vars);
        }
        // refresh memory estimates (based on updated stats,
        // before: init memo table with propagated worst-case estimates,
        // after: extract worst-case estimates from memo table 
        Hop.resetVisitStatus(hops);
        MemoTable memo = new MemoTable();
        memo.init(hops, status);
        Hop.resetVisitStatus(hops);
        for (Hop hopRoot : hops) hopRoot.refreshMemEstimates(memo);
        memo.extract(hops, status);
        // codegen if enabled
        if (ConfigurationManager.getDMLConfig().getBooleanValue(DMLConfig.CODEGEN) && SpoofCompiler.RECOMPILE_CODEGEN) {
            Hop.resetVisitStatus(hops);
            hops = SpoofCompiler.optimize(hops, true);
        }
        // construct lops			
        Dag<Lop> dag = new Dag<Lop>();
        for (Hop hopRoot : hops) {
            Lop lops = hopRoot.constructLops();
            lops.addToDag(dag);
        }
        // generate runtime instructions (incl piggybacking)
        newInst = dag.getJobs(sb, ConfigurationManager.getDMLConfig());
    }
    // replace thread ids in new instructions
    if (//only in parfor context
    tid != 0)
        newInst = ProgramConverter.createDeepCopyInstructionSet(newInst, tid, -1, null, null, null, false, false);
    // explain recompiled hops / instructions
    if (DMLScript.EXPLAIN == ExplainType.RECOMPILE_HOPS) {
        LOG.info("EXPLAIN RECOMPILE \nGENERIC (lines " + sb.getBeginLine() + "-" + sb.getEndLine() + "):\n" + Explain.explainHops(hops, 1));
    }
    if (DMLScript.EXPLAIN == ExplainType.RECOMPILE_RUNTIME) {
        LOG.info("EXPLAIN RECOMPILE \nGENERIC (lines " + sb.getBeginLine() + "-" + sb.getEndLine() + "):\n" + Explain.explain(newInst, 1));
    }
    return newInst;
}
Also used : Hop(org.apache.sysml.hops.Hop) Dag(org.apache.sysml.lops.compile.Dag) MRJobInstruction(org.apache.sysml.runtime.instructions.MRJobInstruction) Instruction(org.apache.sysml.runtime.instructions.Instruction) FunctionCallCPInstruction(org.apache.sysml.runtime.instructions.cp.FunctionCallCPInstruction) SeqInstruction(org.apache.sysml.runtime.instructions.mr.SeqInstruction) RandInstruction(org.apache.sysml.runtime.instructions.mr.RandInstruction) Lop(org.apache.sysml.lops.Lop) MemoTable(org.apache.sysml.hops.MemoTable)

Example 2 with MemoTable

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

the class Recompiler method recompileHopsDag.

/**
	 * B) Recompile predicate hop DAG (single root): 
	 * 
	 * Note: This overloaded method is required for predicate instructions because
	 * they have only a single hops DAG and we need to synchronize on the original 
	 * (shared) hops object. Hence, we cannot create any wrapper arraylist for each
	 * recompilation - this would result in race conditions for concurrent recompilation 
	 * in a parfor body. 	
	 * 
	 * Note: no statementblock passed because for predicate dags we dont have separate live variable analysis information.
	 * 
	 * @param hops high-level operator
	 * @param vars local variable map
	 * @param status recompile status
	 * @param inplace true if in place
	 * @param litreplace true if literal replacement
	 * @param tid thread id
	 * @return list of instructions
	 * @throws DMLRuntimeException if DMLRuntimeException occurs
	 * @throws HopsException if HopsException occurs
	 * @throws LopsException if LopsException occurs
	 * @throws IOException if IOException occurs
	 */
public static ArrayList<Instruction> recompileHopsDag(Hop hops, LocalVariableMap vars, RecompileStatus status, boolean inplace, boolean litreplace, long tid) throws DMLRuntimeException, HopsException, LopsException, IOException {
    ArrayList<Instruction> newInst = null;
    //need for synchronization as we do temp changes in shared hops/lops
    synchronized (hops) {
        LOG.debug("\n**************** Optimizer (Recompile) *************\nMemory Budget = " + OptimizerUtils.toMB(OptimizerUtils.getLocalMemBudget()) + " MB");
        // prepare hops dag for recompile
        if (!inplace) {
            // deep copy hop dag (for non-reversable rewrites)
            //(this also clears existing lops in the created dag) 
            hops = deepCopyHopsDag(hops);
        } else {
            // clear existing lops
            hops.resetVisitStatus();
            rClearLops(hops);
        }
        // replace scalar reads with literals 
        if (!inplace && litreplace) {
            hops.resetVisitStatus();
            rReplaceLiterals(hops, vars, false);
        }
        // refresh matrix characteristics (update stats)			
        hops.resetVisitStatus();
        rUpdateStatistics(hops, vars);
        // dynamic hop rewrites
        if (!inplace) {
            _rewriter.get().rewriteHopDAG(hops, null);
            //update stats after rewrites
            hops.resetVisitStatus();
            rUpdateStatistics(hops, vars);
        }
        // refresh memory estimates (based on updated stats)
        MemoTable memo = new MemoTable();
        hops.resetVisitStatus();
        memo.init(hops, status);
        hops.resetVisitStatus();
        hops.refreshMemEstimates(memo);
        // codegen if enabled
        if (ConfigurationManager.getDMLConfig().getBooleanValue(DMLConfig.CODEGEN) && SpoofCompiler.RECOMPILE_CODEGEN) {
            hops.resetVisitStatus();
            hops = SpoofCompiler.optimize(hops, false);
        }
        // construct lops			
        Dag<Lop> dag = new Dag<Lop>();
        Lop lops = hops.constructLops();
        lops.addToDag(dag);
        // generate runtime instructions (incl piggybacking)
        newInst = dag.getJobs(null, ConfigurationManager.getDMLConfig());
    }
    // replace thread ids in new instructions
    if (//only in parfor context
    tid != 0)
        newInst = ProgramConverter.createDeepCopyInstructionSet(newInst, tid, -1, null, null, null, false, false);
    // explain recompiled instructions
    if (DMLScript.EXPLAIN == ExplainType.RECOMPILE_HOPS)
        LOG.info("EXPLAIN RECOMPILE \nPRED (line " + hops.getBeginLine() + "):\n" + Explain.explain(hops, 1));
    if (DMLScript.EXPLAIN == ExplainType.RECOMPILE_RUNTIME)
        LOG.info("EXPLAIN RECOMPILE \nPRED (line " + hops.getBeginLine() + "):\n" + Explain.explain(newInst, 1));
    return newInst;
}
Also used : Dag(org.apache.sysml.lops.compile.Dag) MRJobInstruction(org.apache.sysml.runtime.instructions.MRJobInstruction) Instruction(org.apache.sysml.runtime.instructions.Instruction) FunctionCallCPInstruction(org.apache.sysml.runtime.instructions.cp.FunctionCallCPInstruction) SeqInstruction(org.apache.sysml.runtime.instructions.mr.SeqInstruction) RandInstruction(org.apache.sysml.runtime.instructions.mr.RandInstruction) Lop(org.apache.sysml.lops.Lop) MemoTable(org.apache.sysml.hops.MemoTable)

Example 3 with MemoTable

use of org.apache.sysml.hops.MemoTable in project systemml by apache.

the class DMLTranslator method refreshMemEstimates.

public void refreshMemEstimates(StatementBlock current) {
    MemoTable memo = new MemoTable();
    if (HopRewriteUtils.isLastLevelStatementBlock(current)) {
        ArrayList<Hop> hopsDAG = current.getHops();
        if (hopsDAG != null && !hopsDAG.isEmpty())
            for (Hop hop : hopsDAG) hop.refreshMemEstimates(memo);
    }
    if (current instanceof FunctionStatementBlock) {
        FunctionStatement fstmt = (FunctionStatement) current.getStatement(0);
        for (StatementBlock sb : fstmt.getBody()) {
            refreshMemEstimates(sb);
        }
    } else if (current instanceof WhileStatementBlock) {
        // handle predicate
        WhileStatementBlock wstb = (WhileStatementBlock) current;
        wstb.getPredicateHops().refreshMemEstimates(new MemoTable());
        if (wstb.getNumStatements() > 1)
            LOG.debug("While statement block has more than 1 stmt");
        WhileStatement ws = (WhileStatement) wstb.getStatement(0);
        for (StatementBlock sb : ws.getBody()) {
            refreshMemEstimates(sb);
        }
    } else if (current instanceof IfStatementBlock) {
        // handle predicate
        IfStatementBlock istb = (IfStatementBlock) current;
        istb.getPredicateHops().refreshMemEstimates(new MemoTable());
        if (istb.getNumStatements() > 1)
            LOG.debug("If statement block has more than 1 stmt");
        IfStatement is = (IfStatement) istb.getStatement(0);
        for (StatementBlock sb : is.getIfBody()) {
            refreshMemEstimates(sb);
        }
        for (StatementBlock sb : is.getElseBody()) {
            refreshMemEstimates(sb);
        }
    } else if (current instanceof ForStatementBlock) {
        // handle predicate
        ForStatementBlock fsb = (ForStatementBlock) current;
        if (fsb.getFromHops() != null)
            fsb.getFromHops().refreshMemEstimates(new MemoTable());
        if (fsb.getToHops() != null)
            fsb.getToHops().refreshMemEstimates(new MemoTable());
        if (fsb.getIncrementHops() != null)
            fsb.getIncrementHops().refreshMemEstimates(new MemoTable());
        if (fsb.getNumStatements() > 1)
            LOG.debug("For statement block has more than 1 stmt");
        ForStatement ws = (ForStatement) fsb.getStatement(0);
        for (StatementBlock sb : ws.getBody()) {
            refreshMemEstimates(sb);
        }
    }
}
Also used : Hop(org.apache.sysml.hops.Hop) MemoTable(org.apache.sysml.hops.MemoTable)

Example 4 with MemoTable

use of org.apache.sysml.hops.MemoTable in project systemml by apache.

the class Recompiler method recompile.

/**
 * Core internal primitive for the dynamic recompilation of any DAGs/predicate,
 * including all variants with slightly different configurations.
 *
 * @param sb statement block of DAG, null for predicates
 * @param hops list of DAG root nodes
 * @param vars symbol table
 * @param status recompilation status
 * @param inplace modify DAG in place, otherwise deep copy
 * @param replaceLit replace literals (only applicable on deep copy)
 * @param updateStats update statistics, rewrites, and memory estimates
 * @param forceEt force a given execution type, null for reset
 * @param pred recompile for predicate DAG
 * @param et given execution type
 * @param tid thread id, 0 for main or before worker creation
 * @return modified list of instructions
 */
private static ArrayList<Instruction> recompile(StatementBlock sb, ArrayList<Hop> hops, LocalVariableMap vars, RecompileStatus status, boolean inplace, boolean replaceLit, boolean updateStats, boolean forceEt, boolean pred, ExecType et, long tid) {
    // prepare hops dag for recompile
    if (!inplace) {
        // deep copy hop dag (for non-reversable rewrites)
        hops = deepCopyHopsDag(hops);
    } else {
        // clear existing lops
        Hop.resetVisitStatus(hops);
        for (Hop hopRoot : hops) rClearLops(hopRoot);
    }
    // replace scalar reads with literals
    if (!inplace && replaceLit) {
        Hop.resetVisitStatus(hops);
        for (Hop hopRoot : hops) rReplaceLiterals(hopRoot, vars, false);
    }
    // force exec type (et=null for reset)
    if (forceEt) {
        Hop.resetVisitStatus(hops);
        for (Hop hopRoot : hops) rSetExecType(hopRoot, et);
        Hop.resetVisitStatus(hops);
    }
    // update statistics, rewrites, and mem estimates
    if (updateStats) {
        // refresh matrix characteristics (update stats)
        Hop.resetVisitStatus(hops);
        for (Hop hopRoot : hops) rUpdateStatistics(hopRoot, vars);
        // dynamic hop rewrites
        if (!inplace) {
            _rewriter.get().rewriteHopDAG(hops, null);
            // update stats after rewrites
            Hop.resetVisitStatus(hops);
            for (Hop hopRoot : hops) rUpdateStatistics(hopRoot, vars);
        }
        // refresh memory estimates (based on updated stats,
        // before: init memo table with propagated worst-case estimates,
        // after: extract worst-case estimates from memo table
        Hop.resetVisitStatus(hops);
        MemoTable memo = new MemoTable();
        memo.init(hops, status);
        Hop.resetVisitStatus(hops);
        for (Hop hopRoot : hops) hopRoot.refreshMemEstimates(memo);
        memo.extract(hops, status);
    }
    // codegen if enabled
    if (ConfigurationManager.isCodegenEnabled() && // not on reset
    !(forceEt && et == null) && SpoofCompiler.RECOMPILE_CODEGEN) {
        // create deep copy for in-place
        if (inplace)
            hops = deepCopyHopsDag(hops);
        Hop.resetVisitStatus(hops);
        hops = SpoofCompiler.optimize(hops, (status == null || !status.isInitialCodegen()));
    }
    // construct lops
    Dag<Lop> dag = new Dag<>();
    for (Hop hopRoot : hops) {
        Lop lops = hopRoot.constructLops();
        lops.addToDag(dag);
    }
    // generate runtime instructions (incl piggybacking)
    ArrayList<Instruction> newInst = dag.getJobs(sb, ConfigurationManager.getDMLConfig());
    // defer the explain of instructions after additional modifications
    if (DMLScript.EXPLAIN == ExplainType.RECOMPILE_HOPS) {
        if (pred)
            logExplainPred(hops.get(0), newInst);
        else
            logExplainDAG(sb, hops, newInst);
    }
    return newInst;
}
Also used : Hop(org.apache.sysml.hops.Hop) Dag(org.apache.sysml.lops.compile.Dag) Lop(org.apache.sysml.lops.Lop) MRJobInstruction(org.apache.sysml.runtime.instructions.MRJobInstruction) Instruction(org.apache.sysml.runtime.instructions.Instruction) FunctionCallCPInstruction(org.apache.sysml.runtime.instructions.cp.FunctionCallCPInstruction) SeqInstruction(org.apache.sysml.runtime.instructions.mr.SeqInstruction) RandInstruction(org.apache.sysml.runtime.instructions.mr.RandInstruction) MemoTable(org.apache.sysml.hops.MemoTable)

Example 5 with MemoTable

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

the class DMLTranslator method refreshMemEstimates.

public void refreshMemEstimates(StatementBlock current) {
    MemoTable memo = new MemoTable();
    if (HopRewriteUtils.isLastLevelStatementBlock(current)) {
        ArrayList<Hop> hopsDAG = current.getHops();
        if (hopsDAG != null && !hopsDAG.isEmpty())
            for (Hop hop : hopsDAG) hop.refreshMemEstimates(memo);
    }
    if (current instanceof FunctionStatementBlock) {
        FunctionStatement fstmt = (FunctionStatement) current.getStatement(0);
        for (StatementBlock sb : fstmt.getBody()) {
            refreshMemEstimates(sb);
        }
    } else if (current instanceof WhileStatementBlock) {
        // handle predicate
        WhileStatementBlock wstb = (WhileStatementBlock) current;
        wstb.getPredicateHops().refreshMemEstimates(new MemoTable());
        if (wstb.getNumStatements() > 1)
            LOG.debug("While statement block has more than 1 stmt");
        WhileStatement ws = (WhileStatement) wstb.getStatement(0);
        for (StatementBlock sb : ws.getBody()) {
            refreshMemEstimates(sb);
        }
    } else if (current instanceof IfStatementBlock) {
        // handle predicate
        IfStatementBlock istb = (IfStatementBlock) current;
        istb.getPredicateHops().refreshMemEstimates(new MemoTable());
        if (istb.getNumStatements() > 1)
            LOG.debug("If statement block has more than 1 stmt");
        IfStatement is = (IfStatement) istb.getStatement(0);
        for (StatementBlock sb : is.getIfBody()) {
            refreshMemEstimates(sb);
        }
        for (StatementBlock sb : is.getElseBody()) {
            refreshMemEstimates(sb);
        }
    } else if (current instanceof ForStatementBlock) {
        // handle predicate
        ForStatementBlock fsb = (ForStatementBlock) current;
        if (fsb.getFromHops() != null)
            fsb.getFromHops().refreshMemEstimates(new MemoTable());
        if (fsb.getToHops() != null)
            fsb.getToHops().refreshMemEstimates(new MemoTable());
        if (fsb.getIncrementHops() != null)
            fsb.getIncrementHops().refreshMemEstimates(new MemoTable());
        if (fsb.getNumStatements() > 1)
            LOG.debug("For statement block has more than 1 stmt");
        ForStatement ws = (ForStatement) fsb.getStatement(0);
        for (StatementBlock sb : ws.getBody()) {
            refreshMemEstimates(sb);
        }
    }
}
Also used : Hop(org.apache.sysml.hops.Hop) MemoTable(org.apache.sysml.hops.MemoTable)

Aggregations

MemoTable (org.apache.sysml.hops.MemoTable)6 Hop (org.apache.sysml.hops.Hop)5 Lop (org.apache.sysml.lops.Lop)4 Dag (org.apache.sysml.lops.compile.Dag)4 Instruction (org.apache.sysml.runtime.instructions.Instruction)4 MRJobInstruction (org.apache.sysml.runtime.instructions.MRJobInstruction)4 FunctionCallCPInstruction (org.apache.sysml.runtime.instructions.cp.FunctionCallCPInstruction)4 RandInstruction (org.apache.sysml.runtime.instructions.mr.RandInstruction)4 SeqInstruction (org.apache.sysml.runtime.instructions.mr.SeqInstruction)4