use of org.apache.sysml.hops.LiteralOp in project incubator-systemml by apache.
the class RewriteAlgebraicSimplificationDynamic method removeUnnecessaryIfElseOperation.
private static Hop removeUnnecessaryIfElseOperation(Hop parent, Hop hi, int pos) {
if (!HopRewriteUtils.isTernary(hi, OpOp3.IFELSE))
return hi;
Hop expr = hi.getInput().get(0);
Hop first = hi.getInput().get(1);
Hop second = hi.getInput().get(2);
boolean applied = false;
// pattern 1: ifelse(TRUE/FALSE, A, B) -> A/B (constant scalar predicate)
if (expr instanceof LiteralOp) {
Hop hnew = ((LiteralOp) expr).getBooleanValue() ? first : second;
if (HopRewriteUtils.isEqualSize(hnew, hi)) {
HopRewriteUtils.replaceChildReference(parent, hi, hnew, pos);
HopRewriteUtils.cleanupUnreferenced(hi);
LOG.debug("Applied removeUnnecessaryIfElse1 (line " + hi.getBeginLine() + ")");
hi = hnew;
applied = true;
}
}
// pattern 2: ifelse(E, A, B) -> A/B if nnz(E)==length(E) or nnz(E)==0 (constant matrix predicate)
if (!applied && expr.getNnz() == expr.getLength() || expr.getNnz() == 0) {
Hop hnew = expr.getNnz() == 0 ? second : first;
if (HopRewriteUtils.isEqualSize(hnew, hi)) {
HopRewriteUtils.replaceChildReference(parent, hi, hnew, pos);
HopRewriteUtils.cleanupUnreferenced(hi);
LOG.debug("Applied removeUnnecessaryIfElse2 (line " + hi.getBeginLine() + ")");
hi = hnew;
applied = true;
}
}
// pattern 3: ifelse(E, A, A) -> A (same input)
if (// dep CSE
!applied && first == second && HopRewriteUtils.isEqualSize(first, hi)) {
HopRewriteUtils.replaceChildReference(parent, hi, first, pos);
HopRewriteUtils.cleanupUnreferenced(hi);
LOG.debug("Applied removeUnnecessaryIfElse3 (line " + hi.getBeginLine() + ")");
hi = first;
}
return hi;
}
use of org.apache.sysml.hops.LiteralOp in project incubator-systemml by apache.
the class RewriteAlgebraicSimplificationDynamic method simplifyWeightedCrossEntropy.
private static Hop simplifyWeightedCrossEntropy(Hop parent, Hop hi, int pos) {
Hop hnew = null;
boolean appliedPattern = false;
if (hi instanceof AggUnaryOp && ((AggUnaryOp) hi).getDirection() == Direction.RowCol && // pattern rooted by sum()
((AggUnaryOp) hi).getOp() == AggOp.SUM && // pattern subrooted by binary op
hi.getInput().get(0) instanceof BinaryOp && // not applied for vector-vector mult
hi.getInput().get(0).getDim2() > 1) {
BinaryOp bop = (BinaryOp) hi.getInput().get(0);
Hop left = bop.getInput().get(0);
Hop right = bop.getInput().get(1);
// Pattern 1) sum( X * log(U %*% t(V)))
if (bop.getOp() == OpOp2.MULT && left.getDataType() == DataType.MATRIX && // prevent mb
HopRewriteUtils.isEqualSize(left, right) && HopRewriteUtils.isUnary(right, OpOp1.LOG) && // ba gurantees matrices
right.getInput().get(0) instanceof AggBinaryOp && // BLOCKSIZE CONSTRAINT
HopRewriteUtils.isSingleBlock(right.getInput().get(0).getInput().get(0), true)) {
Hop X = left;
Hop U = right.getInput().get(0).getInput().get(0);
Hop V = right.getInput().get(0).getInput().get(1);
if (!HopRewriteUtils.isTransposeOperation(V))
V = HopRewriteUtils.createTranspose(V);
else
V = V.getInput().get(0);
hnew = new QuaternaryOp(hi.getName(), DataType.SCALAR, ValueType.DOUBLE, OpOp4.WCEMM, X, U, V, new LiteralOp(0.0), 0, false, false);
hnew.setOutputBlocksizes(X.getRowsInBlock(), X.getColsInBlock());
appliedPattern = true;
LOG.debug("Applied simplifyWeightedCEMM (line " + hi.getBeginLine() + ")");
}
// Pattern 2) sum( X * log(U %*% t(V) + eps))
if (!appliedPattern && bop.getOp() == OpOp2.MULT && left.getDataType() == DataType.MATRIX && HopRewriteUtils.isEqualSize(left, right) && HopRewriteUtils.isUnary(right, OpOp1.LOG) && HopRewriteUtils.isBinary(right.getInput().get(0), OpOp2.PLUS) && right.getInput().get(0).getInput().get(0) instanceof AggBinaryOp && right.getInput().get(0).getInput().get(1) instanceof LiteralOp && right.getInput().get(0).getInput().get(1).getDataType() == DataType.SCALAR && HopRewriteUtils.isSingleBlock(right.getInput().get(0).getInput().get(0).getInput().get(0), true)) {
Hop X = left;
Hop U = right.getInput().get(0).getInput().get(0).getInput().get(0);
Hop V = right.getInput().get(0).getInput().get(0).getInput().get(1);
Hop eps = right.getInput().get(0).getInput().get(1);
if (!HopRewriteUtils.isTransposeOperation(V))
V = HopRewriteUtils.createTranspose(V);
else
V = V.getInput().get(0);
hnew = new QuaternaryOp(hi.getName(), DataType.SCALAR, ValueType.DOUBLE, OpOp4.WCEMM, X, U, V, eps, 1, false, // 1 => BASIC_EPS
false);
hnew.setOutputBlocksizes(X.getRowsInBlock(), X.getColsInBlock());
LOG.debug("Applied simplifyWeightedCEMMEps (line " + hi.getBeginLine() + ")");
}
}
// relink new hop into original position
if (hnew != null) {
HopRewriteUtils.replaceChildReference(parent, hi, hnew, pos);
hi = hnew;
}
return hi;
}
use of org.apache.sysml.hops.LiteralOp in project incubator-systemml by apache.
the class RewriteAlgebraicSimplificationDynamic method simplifyTableSeqExpand.
private static Hop simplifyTableSeqExpand(Hop parent, Hop hi, int pos) {
// note: this rewrite supports both left/right sequence
if (// table without weights
hi instanceof TernaryOp && hi.getInput().size() == 5 && // i.e., weight of 1
HopRewriteUtils.isLiteralOfValue(hi.getInput().get(2), 1)) {
Hop first = hi.getInput().get(0);
Hop second = hi.getInput().get(1);
// pattern a: table(seq(1,nrow(v)), v, nrow(v), m, 1)
if (HopRewriteUtils.isBasic1NSequence(first, second, true) && HopRewriteUtils.isSizeExpressionOf(hi.getInput().get(3), second, true)) {
// setup input parameter hops
HashMap<String, Hop> args = new HashMap<>();
args.put("target", second);
args.put("max", hi.getInput().get(4));
args.put("dir", new LiteralOp("cols"));
args.put("ignore", new LiteralOp(false));
args.put("cast", new LiteralOp(true));
// create new hop
ParameterizedBuiltinOp pbop = HopRewriteUtils.createParameterizedBuiltinOp(second, args, ParamBuiltinOp.REXPAND);
HopRewriteUtils.replaceChildReference(parent, hi, pbop, pos);
HopRewriteUtils.cleanupUnreferenced(hi);
hi = pbop;
LOG.debug("Applied simplifyTableSeqExpand1 (line " + hi.getBeginLine() + ")");
} else // pattern b: table(v, seq(1,nrow(v)), m, nrow(v))
if (HopRewriteUtils.isBasic1NSequence(second, first, true) && HopRewriteUtils.isSizeExpressionOf(hi.getInput().get(4), first, true)) {
// setup input parameter hops
HashMap<String, Hop> args = new HashMap<>();
args.put("target", first);
args.put("max", hi.getInput().get(3));
args.put("dir", new LiteralOp("rows"));
args.put("ignore", new LiteralOp(false));
args.put("cast", new LiteralOp(true));
// create new hop
ParameterizedBuiltinOp pbop = HopRewriteUtils.createParameterizedBuiltinOp(first, args, ParamBuiltinOp.REXPAND);
HopRewriteUtils.replaceChildReference(parent, hi, pbop, pos);
HopRewriteUtils.cleanupUnreferenced(hi);
hi = pbop;
LOG.debug("Applied simplifyTableSeqExpand2 (line " + hi.getBeginLine() + ")");
}
}
return hi;
}
use of org.apache.sysml.hops.LiteralOp in project incubator-systemml by apache.
the class RewriteAlgebraicSimplificationDynamic method simplifyEmptyBinaryOperation.
private static Hop simplifyEmptyBinaryOperation(Hop parent, Hop hi, int pos) {
if (// b(?) X Y
hi instanceof BinaryOp) {
BinaryOp bop = (BinaryOp) hi;
Hop left = hi.getInput().get(0);
Hop right = hi.getInput().get(1);
if (left.getDataType() == DataType.MATRIX && right.getDataType() == DataType.MATRIX) {
Hop hnew = null;
// NOTE: these rewrites of binary cell operations need to be aware that right is
// potentially a vector but the result is of the size of left
boolean notBinaryMV = HopRewriteUtils.isNotMatrixVectorBinaryOperation(bop);
switch(bop.getOp()) {
// X * Y -> matrix(0,nrow(X),ncol(X));
case MULT:
{
if (// empty left and size known
HopRewriteUtils.isEmpty(left))
hnew = HopRewriteUtils.createDataGenOp(left, left, 0);
else if (// empty right and right not a vector
HopRewriteUtils.isEmpty(right) && right.getDim1() > 1 && right.getDim2() > 1) {
hnew = HopRewriteUtils.createDataGenOp(right, right, 0);
} else if (// empty right and right potentially a vector
HopRewriteUtils.isEmpty(right))
hnew = HopRewriteUtils.createDataGenOp(left, left, 0);
break;
}
case PLUS:
{
if (// empty left/right and size known
HopRewriteUtils.isEmpty(left) && HopRewriteUtils.isEmpty(right))
hnew = HopRewriteUtils.createDataGenOp(left, left, 0);
else if (// empty left
HopRewriteUtils.isEmpty(left) && notBinaryMV)
hnew = right;
else if (// empty right
HopRewriteUtils.isEmpty(right))
hnew = left;
break;
}
case MINUS:
{
if (HopRewriteUtils.isEmpty(left) && notBinaryMV) {
// empty left
HopRewriteUtils.removeChildReference(hi, left);
HopRewriteUtils.addChildReference(hi, new LiteralOp(0), 0);
hnew = hi;
} else if (// empty and size known
HopRewriteUtils.isEmpty(right))
hnew = left;
break;
}
default:
hnew = null;
}
if (hnew != null) {
// create datagen and add it to parent
HopRewriteUtils.replaceChildReference(parent, hi, hnew, pos);
hi = hnew;
LOG.debug("Applied simplifyEmptyBinaryOperation");
}
}
}
return hi;
}
use of org.apache.sysml.hops.LiteralOp in project incubator-systemml by apache.
the class RewriteAlgebraicSimplificationDynamic method reorderMinusMatrixMult.
/**
* This is rewrite tries to reorder minus operators from inputs of matrix
* multiply to its output because the output is (except for outer products)
* usually significantly smaller. Furthermore, this rewrite is a precondition
* for the important hops-lops rewrite of transpose-matrixmult if the transpose
* is hidden under the minus.
*
* NOTE: in this rewrite we need to modify the links to all parents because we
* remove existing links of subdags and hence affect all consumers.
*
* @param parent the parent high-level operator
* @param hi high-level operator
* @param pos position
* @return high-level operator
*/
@SuppressWarnings("unchecked")
private static Hop reorderMinusMatrixMult(Hop parent, Hop hi, int pos) {
if (// X%*%Y
HopRewriteUtils.isMatrixMultiply(hi)) {
Hop hileft = hi.getInput().get(0);
Hop hiright = hi.getInput().get(1);
if (// X=-Z
HopRewriteUtils.isBinary(hileft, OpOp2.MINUS) && hileft.getInput().get(0) instanceof LiteralOp && HopRewriteUtils.getDoubleValue((LiteralOp) hileft.getInput().get(0)) == 0.0 && hi.dimsKnown() && // size comparison
hileft.getInput().get(1).dimsKnown() && HopRewriteUtils.compareSize(hi, hileft.getInput().get(1)) < 0) {
Hop hi2 = hileft.getInput().get(1);
// remove link from matrixmult to minus
HopRewriteUtils.removeChildReference(hi, hileft);
// get old parents (before creating minus over matrix mult)
ArrayList<Hop> parents = (ArrayList<Hop>) hi.getParent().clone();
// create new operators
BinaryOp minus = HopRewriteUtils.createBinary(new LiteralOp(0), hi, OpOp2.MINUS);
// rehang minus under all parents
for (Hop p : parents) {
int ix = HopRewriteUtils.getChildReferencePos(p, hi);
HopRewriteUtils.removeChildReference(p, hi);
HopRewriteUtils.addChildReference(p, minus, ix);
}
// rehang child of minus under matrix mult
HopRewriteUtils.addChildReference(hi, hi2, 0);
// cleanup if only consumer of minus
HopRewriteUtils.cleanupUnreferenced(hileft);
hi = minus;
LOG.debug("Applied reorderMinusMatrixMult (line " + hi.getBeginLine() + ").");
} else if (// X=-Z
HopRewriteUtils.isBinary(hiright, OpOp2.MINUS) && hiright.getInput().get(0) instanceof LiteralOp && HopRewriteUtils.getDoubleValue((LiteralOp) hiright.getInput().get(0)) == 0.0 && hi.dimsKnown() && // size comparison
hiright.getInput().get(1).dimsKnown() && HopRewriteUtils.compareSize(hi, hiright.getInput().get(1)) < 0) {
Hop hi2 = hiright.getInput().get(1);
// remove link from matrixmult to minus
HopRewriteUtils.removeChildReference(hi, hiright);
// get old parents (before creating minus over matrix mult)
ArrayList<Hop> parents = (ArrayList<Hop>) hi.getParent().clone();
// create new operators
BinaryOp minus = HopRewriteUtils.createBinary(new LiteralOp(0), hi, OpOp2.MINUS);
// rehang minus under all parents
for (Hop p : parents) {
int ix = HopRewriteUtils.getChildReferencePos(p, hi);
HopRewriteUtils.removeChildReference(p, hi);
HopRewriteUtils.addChildReference(p, minus, ix);
}
// rehang child of minus under matrix mult
HopRewriteUtils.addChildReference(hi, hi2, 1);
// cleanup if only consumer of minus
HopRewriteUtils.cleanupUnreferenced(hiright);
hi = minus;
LOG.debug("Applied reorderMinusMatrixMult (line " + hi.getBeginLine() + ").");
}
}
return hi;
}
Aggregations