use of org.apache.sysml.lops.Lop in project incubator-systemml by apache.
the class AggBinaryOp method constructCPLopsTSMM.
//////////////////////////
// CP Lops generation
/////////////////////////
private void constructCPLopsTSMM(MMTSJType mmtsj) throws HopsException, LopsException {
int k = OptimizerUtils.getConstrainedNumThreads(_maxNumThreads);
ExecType et = ExecType.CP;
if (DMLScript.USE_ACCELERATOR && (DMLScript.FORCE_ACCELERATOR || getMemEstimate() < OptimizerUtils.GPU_MEMORY_BUDGET)) {
et = ExecType.GPU;
}
Lop matmultCP = new MMTSJ(getInput().get(mmtsj.isLeft() ? 1 : 0).constructLops(), getDataType(), getValueType(), et, mmtsj, false, k);
matmultCP.getOutputParameters().setDimensions(getDim1(), getDim2(), getRowsInBlock(), getColsInBlock(), getNnz());
setLineNumbers(matmultCP);
setLops(matmultCP);
}
use of org.apache.sysml.lops.Lop in project incubator-systemml by apache.
the class Dag method doTopologicalSort_strict_order.
/**
* Method to topologically sort lops
*
* @param v list of lops
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private void doTopologicalSort_strict_order(ArrayList<Lop> v) {
//int numNodes = v.size();
/*
* Step 1: compute the level for each node in the DAG. Level for each node is
* computed as lops are created. So, this step is need not be performed here.
* Step 2: sort the nodes by level, and within a level by node ID.
*/
// Step1: Performed at the time of creating Lops
// Step2: sort nodes by level, and then by node ID
Lop[] nodearray = v.toArray(new Lop[0]);
Arrays.sort(nodearray, new LopComparator());
// Copy sorted nodes into "v" and construct a mapping between Lop IDs and sequence of numbers
v.clear();
IDMap.clear();
for (int i = 0; i < nodearray.length; i++) {
v.add(nodearray[i]);
IDMap.put(v.get(i).getID(), i);
}
//
for (int i = 0; i < nodearray.length; i++) {
boolean[] arr = v.get(i).create_reachable(nodearray.length);
Arrays.fill(arr, false);
dagDFS(v.get(i), arr);
}
// print the nodes in sorted order
if (LOG.isTraceEnabled()) {
for (Lop vnode : v) {
StringBuilder sb = new StringBuilder();
sb.append(vnode.getID());
sb.append("(");
sb.append(vnode.getLevel());
sb.append(") ");
sb.append(vnode.getType());
sb.append("(");
for (Lop vin : vnode.getInputs()) {
sb.append(vin.getID());
sb.append(",");
}
sb.append("), ");
LOG.trace(sb.toString());
}
LOG.trace("topological sort -- done");
}
}
use of org.apache.sysml.lops.Lop 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;
}
use of org.apache.sysml.lops.Lop 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;
}
use of org.apache.sysml.lops.Lop in project incubator-systemml by apache.
the class TernaryOp method constructLopsPlusMult.
private void constructLopsPlusMult() throws HopsException, LopsException {
if (_op != OpOp3.PLUS_MULT && _op != OpOp3.MINUS_MULT)
throw new HopsException("Unexpected operation: " + _op + ", expecting " + OpOp3.PLUS_MULT + " or" + OpOp3.MINUS_MULT);
ExecType et = null;
if (DMLScript.USE_ACCELERATOR && (DMLScript.FORCE_ACCELERATOR || getMemEstimate() < OptimizerUtils.GPU_MEMORY_BUDGET))
et = ExecType.GPU;
else
et = optFindExecType();
PlusMult plusmult = null;
if (et == ExecType.CP || et == ExecType.SPARK || et == ExecType.GPU) {
plusmult = new PlusMult(getInput().get(0).constructLops(), getInput().get(1).constructLops(), getInput().get(2).constructLops(), _op, getDataType(), getValueType(), et);
} else {
//MR
Hop left = getInput().get(0);
Hop right = getInput().get(2);
boolean requiresRep = BinaryOp.requiresReplication(left, right);
Lop rightLop = right.constructLops();
if (requiresRep) {
//ncol of left input (determines num replicates)
Lop offset = createOffsetLop(left, (right.getDim2() <= 1));
rightLop = new RepMat(rightLop, offset, (right.getDim2() <= 1), right.getDataType(), right.getValueType());
setOutputDimensions(rightLop);
setLineNumbers(rightLop);
}
Group group1 = new Group(left.constructLops(), Group.OperationTypes.Sort, getDataType(), getValueType());
setLineNumbers(group1);
setOutputDimensions(group1);
Group group2 = new Group(rightLop, Group.OperationTypes.Sort, getDataType(), getValueType());
setLineNumbers(group2);
setOutputDimensions(group2);
plusmult = new PlusMult(group1, getInput().get(1).constructLops(), group2, _op, getDataType(), getValueType(), et);
}
setOutputDimensions(plusmult);
setLineNumbers(plusmult);
setLops(plusmult);
}
Aggregations