use of org.apache.sysml.hops.Hop in project incubator-systemml by apache.
the class PlanSelectionFuseNoRedundancy method rSelectPlans.
private void rSelectPlans(CPlanMemoTable memo, Hop current, TemplateType currentType) {
if (isVisited(current.getHopID(), currentType))
return;
// step 0: remove plans that refer to a common partial plan
if (memo.contains(current.getHopID())) {
HashSet<MemoTableEntry> rmSet = new HashSet<>();
List<MemoTableEntry> hopP = memo.get(current.getHopID());
for (MemoTableEntry e1 : hopP) for (int i = 0; i < 3; i++) if (e1.isPlanRef(i) && current.getInput().get(i).getParent().size() > 1)
// remove references to hops w/ multiple consumers
rmSet.add(e1);
memo.remove(current, rmSet);
}
// step 1: prune subsumed plans of same type
if (memo.contains(current.getHopID())) {
HashSet<MemoTableEntry> rmSet = new HashSet<>();
List<MemoTableEntry> hopP = memo.get(current.getHopID());
for (MemoTableEntry e1 : hopP) for (MemoTableEntry e2 : hopP) if (e1 != e2 && e1.subsumes(e2))
rmSet.add(e2);
memo.remove(current, rmSet);
}
// step 2: select plan for current path
MemoTableEntry best = null;
if (memo.contains(current.getHopID())) {
if (currentType == null) {
best = memo.get(current.getHopID()).stream().filter(p -> p.isValid()).min(new BasicPlanComparator()).orElse(null);
} else {
best = memo.get(current.getHopID()).stream().filter(p -> p.type == currentType || p.type == TemplateType.CELL).min(Comparator.comparing(p -> 7 - ((p.type == currentType) ? 4 : 0) - p.countPlanRefs())).orElse(null);
}
addBestPlan(current.getHopID(), best);
}
// step 3: recursively process children
for (int i = 0; i < current.getInput().size(); i++) {
TemplateType pref = (best != null && best.isPlanRef(i)) ? best.type : null;
rSelectPlans(memo, current.getInput().get(i), pref);
}
setVisited(current.getHopID(), currentType);
}
use of org.apache.sysml.hops.Hop in project incubator-systemml by apache.
the class CPlanMemoTable method pruneRedundant.
public void pruneRedundant(long hopID, boolean pruneDominated, InterestingPoint[] matPoints) {
if (!contains(hopID))
return;
// prune redundant plans (i.e., equivalent)
setDistinct(hopID, _plans.get(hopID));
// prune closed templates without group references
_plans.get(hopID).removeIf(p -> p.isClosed() && !p.hasPlanRef());
// heuristic that only consider materialization points)
if (pruneDominated) {
HashSet<MemoTableEntry> rmList = new HashSet<>();
List<MemoTableEntry> list = _plans.get(hopID);
Hop hop = _hopRefs.get(hopID);
for (MemoTableEntry e1 : list) for (MemoTableEntry e2 : list) if (e1 != e2 && e1.subsumes(e2)) {
// check that childs don't have multiple consumers
boolean rmSafe = true;
for (int i = 0; i <= 2; i++) {
rmSafe &= (e1.isPlanRef(i) && !e2.isPlanRef(i)) ? (matPoints != null && !InterestingPoint.isMatPoint(matPoints, hopID, e1.input(i))) || hop.getInput().get(i).getParent().size() == 1 : true;
}
if (rmSafe)
rmList.add(e2);
}
// update current entry list, by removing rmList
remove(hop, rmList);
}
}
use of org.apache.sysml.hops.Hop in project incubator-systemml by apache.
the class TemplateCell method constructCplan.
@Override
public Pair<Hop[], CNodeTpl> constructCplan(Hop hop, CPlanMemoTable memo, boolean compileLiterals) {
// recursively process required cplan output
HashSet<Hop> inHops = new HashSet<>();
HashMap<Long, CNode> tmp = new HashMap<>();
hop.resetVisitStatus();
rConstructCplan(hop, memo, tmp, inHops, compileLiterals);
hop.resetVisitStatus();
// reorder inputs (ensure matrices/vectors come first) and prune literals
// note: we order by number of cells and subsequently sparsity to ensure
// that sparse inputs are used as the main input w/o unnecessary conversion
Hop[] sinHops = inHops.stream().filter(h -> !(h.getDataType().isScalar() && tmp.get(h.getHopID()).isLiteral())).sorted(new HopInputComparator()).toArray(Hop[]::new);
// construct template node
ArrayList<CNode> inputs = new ArrayList<>();
for (Hop in : sinHops) inputs.add(tmp.get(in.getHopID()));
CNode output = tmp.get(hop.getHopID());
CNodeCell tpl = new CNodeCell(inputs, output);
tpl.setCellType(TemplateUtils.getCellType(hop));
tpl.setAggOp(TemplateUtils.getAggOp(hop));
tpl.setSparseSafe(isSparseSafe(Arrays.asList(hop), sinHops[0], Arrays.asList(tpl.getOutput()), Arrays.asList(tpl.getAggOp()), false));
tpl.setRequiresCastDtm(hop instanceof AggBinaryOp);
tpl.setBeginLine(hop.getBeginLine());
// return cplan instance
return new Pair<>(sinHops, tpl);
}
use of org.apache.sysml.hops.Hop in project incubator-systemml by apache.
the class TemplateCell method isValidOperation.
protected static boolean isValidOperation(Hop hop) {
// prepare indicators for binary operations
boolean isBinaryMatrixScalar = false;
boolean isBinaryMatrixVector = false;
boolean isBinaryMatrixMatrix = false;
if (hop instanceof BinaryOp && hop.getDataType().isMatrix()) {
Hop left = hop.getInput().get(0);
Hop right = hop.getInput().get(1);
DataType ldt = left.getDataType();
DataType rdt = right.getDataType();
isBinaryMatrixScalar = (ldt.isScalar() || rdt.isScalar());
isBinaryMatrixVector = hop.dimsKnown() && ((ldt.isMatrix() && TemplateUtils.isVectorOrScalar(right)) || (rdt.isMatrix() && TemplateUtils.isVectorOrScalar(left)));
isBinaryMatrixMatrix = hop.dimsKnown() && HopRewriteUtils.isEqualSize(left, right) && ldt.isMatrix() && rdt.isMatrix();
}
// prepare indicators for ternary operations
boolean isTernaryVectorScalarVector = false;
boolean isTernaryMatrixScalarMatrixDense = false;
boolean isTernaryIfElse = (HopRewriteUtils.isTernary(hop, OpOp3.IFELSE) && hop.getDataType().isMatrix());
if (hop instanceof TernaryOp && hop.getInput().size() == 3 && hop.dimsKnown() && HopRewriteUtils.checkInputDataTypes(hop, DataType.MATRIX, DataType.SCALAR, DataType.MATRIX)) {
Hop left = hop.getInput().get(0);
Hop right = hop.getInput().get(2);
isTernaryVectorScalarVector = TemplateUtils.isVector(left) && TemplateUtils.isVector(right);
isTernaryMatrixScalarMatrixDense = HopRewriteUtils.isEqualSize(left, right) && !HopRewriteUtils.isSparse(left) && !HopRewriteUtils.isSparse(right);
}
// check supported unary, binary, ternary operations
return hop.getDataType() == DataType.MATRIX && TemplateUtils.isOperationSupported(hop) && (hop instanceof UnaryOp || isBinaryMatrixScalar || isBinaryMatrixVector || isBinaryMatrixMatrix || isTernaryVectorScalarVector || isTernaryMatrixScalarMatrixDense || isTernaryIfElse || (hop instanceof ParameterizedBuiltinOp && ((ParameterizedBuiltinOp) hop).getOp() == ParamBuiltinOp.REPLACE));
}
use of org.apache.sysml.hops.Hop in project incubator-systemml by apache.
the class TemplateCell method isSparseSafe.
protected boolean isSparseSafe(List<Hop> roots, Hop mainInput, List<CNode> outputs, List<AggOp> aggOps, boolean onlySum) {
boolean ret = true;
for (int i = 0; i < outputs.size() && ret; i++) {
Hop root = (roots.get(i) instanceof AggUnaryOp || roots.get(i) instanceof AggBinaryOp) ? roots.get(i).getInput().get(0) : roots.get(i);
ret &= (HopRewriteUtils.isBinarySparseSafe(root) && root.getInput().contains(mainInput)) || (HopRewriteUtils.isBinary(root, OpOp2.DIV) && root.getInput().get(0) == mainInput) || (TemplateUtils.rIsSparseSafeOnly(outputs.get(i), BinType.MULT) && TemplateUtils.rContainsInput(outputs.get(i), mainInput.getHopID()));
if (onlySum)
ret &= (aggOps.get(i) == AggOp.SUM || aggOps.get(i) == AggOp.SUM_SQ);
}
return ret;
}
Aggregations