use of org.apache.sysml.hops.ReorgOp in project incubator-systemml by apache.
the class RewriteAlgebraicSimplificationDynamic method simplifyEmptySortOperation.
private static Hop simplifyEmptySortOperation(Hop parent, Hop hi, int pos) {
// order(X, indexreturn=TRUE) -> seq(1,nrow(X),1)
if (hi instanceof ReorgOp && ((ReorgOp) hi).getOp() == ReOrgOp.SORT) {
ReorgOp rhi = (ReorgOp) hi;
Hop input = rhi.getInput().get(0);
if (// empty input
HopRewriteUtils.isEmpty(input)) {
// reorg-operation-specific rewrite
Hop hnew = null;
boolean ixret = false;
if (// index return known
rhi.getInput().get(3) instanceof LiteralOp) {
ixret = HopRewriteUtils.getBooleanValue((LiteralOp) rhi.getInput().get(3));
if (ixret)
hnew = HopRewriteUtils.createSeqDataGenOp(input);
else
hnew = HopRewriteUtils.createDataGenOp(input, 0);
}
// modify dag if one of the above rules applied
if (hnew != null) {
HopRewriteUtils.replaceChildReference(parent, hi, hnew, pos);
hi = hnew;
LOG.debug("Applied simplifyEmptySortOperation (indexreturn=" + ixret + ").");
}
}
}
return hi;
}
use of org.apache.sysml.hops.ReorgOp in project incubator-systemml by apache.
the class RewriteAlgebraicSimplificationDynamic method simplifyColSumsMVMult.
private static Hop simplifyColSumsMVMult(Hop parent, Hop hi, int pos) {
// removed by other rewrite if unnecessary, i.e., if Y==t(Z)
if (hi instanceof AggUnaryOp) {
AggUnaryOp uhi = (AggUnaryOp) hi;
Hop input = uhi.getInput().get(0);
if (// colsums
uhi.getOp() == AggOp.SUM && uhi.getDirection() == Direction.Col && // b(*)
HopRewriteUtils.isBinary(input, OpOp2.MULT)) {
Hop left = input.getInput().get(0);
Hop right = input.getInput().get(1);
if (left.getDim1() > 1 && left.getDim2() > 1 && right.getDim1() > 1 && // MV (col vector)
right.getDim2() == 1) {
// create new operators
ReorgOp trans = HopRewriteUtils.createTranspose(right);
AggBinaryOp mmult = HopRewriteUtils.createMatrixMultiply(trans, left);
// relink new child
HopRewriteUtils.replaceChildReference(parent, hi, mmult, pos);
HopRewriteUtils.cleanupUnreferenced(uhi, input);
hi = mmult;
LOG.debug("Applied simplifyColSumsMVMult");
}
}
}
return hi;
}
use of org.apache.sysml.hops.ReorgOp in project incubator-systemml by apache.
the class RewriteAlgebraicSimplificationDynamic method simplifyDotProductSum.
/**
* NOTE: dot-product-sum could be also applied to sum(a*b). However, we
* restrict ourselfs to sum(a^2) and transitively sum(a*a) since a general mm
* a%*%b on MR can be also counter-productive (e.g., MMCJ) while tsmm is always
* beneficial.
*
* @param parent parent high-level operator
* @param hi high-level operator
* @param pos position
* @return high-level operator
*/
private static Hop simplifyDotProductSum(Hop parent, Hop hi, int pos) {
// w/o materialization of intermediates
if (// sum
hi instanceof AggUnaryOp && ((AggUnaryOp) hi).getOp() == AggOp.SUM && // full aggregate
((AggUnaryOp) hi).getDirection() == Direction.RowCol && // vector (for correctness)
hi.getInput().get(0).getDim2() == 1) {
Hop baLeft = null;
Hop baRight = null;
// check for ^2 w/o multiple consumers
Hop hi2 = hi.getInput().get(0);
// check for sum(v^2), might have been rewritten from sum(v*v)
if (HopRewriteUtils.isBinary(hi2, OpOp2.POW) && hi2.getInput().get(1) instanceof LiteralOp && HopRewriteUtils.getDoubleValue((LiteralOp) hi2.getInput().get(1)) == 2 && // no other consumer than sum
hi2.getParent().size() == 1) {
Hop input = hi2.getInput().get(0);
baLeft = input;
baRight = input;
} else // check for sum(v1*v2), but prevent to rewrite sum(v1*v2*v3) which is later compiled into a ta+* lop
if (// no other consumer than sum
HopRewriteUtils.isBinary(hi2, OpOp2.MULT, 1) && hi2.getInput().get(0).getDim2() == 1 && hi2.getInput().get(1).getDim2() == 1 && !HopRewriteUtils.isBinary(hi2.getInput().get(0), OpOp2.MULT) && !HopRewriteUtils.isBinary(hi2.getInput().get(1), OpOp2.MULT) && (!ALLOW_SUM_PRODUCT_REWRITES || !(// do not rewrite (A^2)*B
HopRewriteUtils.isBinary(hi2.getInput().get(0), OpOp2.POW) && // let tak+* handle it
hi2.getInput().get(0).getInput().get(1) instanceof LiteralOp && ((LiteralOp) hi2.getInput().get(0).getInput().get(1)).getLongValue() == 2)) && (!ALLOW_SUM_PRODUCT_REWRITES || !(// do not rewrite B*(A^2)
HopRewriteUtils.isBinary(hi2.getInput().get(1), OpOp2.POW) && // let tak+* handle it
hi2.getInput().get(1).getInput().get(1) instanceof LiteralOp && ((LiteralOp) hi2.getInput().get(1).getInput().get(1)).getLongValue() == 2))) {
baLeft = hi2.getInput().get(0);
baRight = hi2.getInput().get(1);
}
// perform actual rewrite (if necessary)
if (baLeft != null && baRight != null) {
// create new operator chain
ReorgOp trans = HopRewriteUtils.createTranspose(baLeft);
AggBinaryOp mmult = HopRewriteUtils.createMatrixMultiply(trans, baRight);
UnaryOp cast = HopRewriteUtils.createUnary(mmult, OpOp1.CAST_AS_SCALAR);
// rehang new subdag under parent node
HopRewriteUtils.replaceChildReference(parent, hi, cast, pos);
HopRewriteUtils.cleanupUnreferenced(hi, hi2);
hi = cast;
LOG.debug("Applied simplifyDotProductSum.");
}
}
return hi;
}
use of org.apache.sysml.hops.ReorgOp in project incubator-systemml by apache.
the class RewriteAlgebraicSimplificationDynamic method simplifyDiagMatrixMult.
private static Hop simplifyDiagMatrixMult(Hop parent, Hop hi, int pos) {
if (// diagM2V
hi instanceof ReorgOp && ((ReorgOp) hi).getOp() == ReOrgOp.DIAG && hi.getDim2() == 1) {
Hop hi2 = hi.getInput().get(0);
if (// X%*%Y
HopRewriteUtils.isMatrixMultiply(hi2)) {
Hop left = hi2.getInput().get(0);
Hop right = hi2.getInput().get(1);
// create new operators (incl refresh size inside for transpose)
ReorgOp trans = HopRewriteUtils.createTranspose(right);
BinaryOp mult = HopRewriteUtils.createBinary(left, trans, OpOp2.MULT);
AggUnaryOp rowSum = HopRewriteUtils.createAggUnaryOp(mult, AggOp.SUM, Direction.Row);
// rehang new subdag under parent node
HopRewriteUtils.replaceChildReference(parent, hi, rowSum, pos);
HopRewriteUtils.cleanupUnreferenced(hi, hi2);
hi = rowSum;
LOG.debug("Applied simplifyDiagMatrixMult");
}
}
return hi;
}
use of org.apache.sysml.hops.ReorgOp in project incubator-systemml by apache.
the class DMLTranslator method processParameterizedBuiltinFunctionExpression.
/**
* Construct Hops from parse tree : Process ParameterizedBuiltinFunction Expression in an
* assignment statement
*
* @param source parameterized built-in function
* @param target data identifier
* @param hops map of high-level operators
* @return high-level operator
*/
private Hop processParameterizedBuiltinFunctionExpression(ParameterizedBuiltinFunctionExpression source, DataIdentifier target, HashMap<String, Hop> hops) {
// this expression has multiple "named" parameters
HashMap<String, Hop> paramHops = new HashMap<>();
// -- construct hops for all input parameters
// -- store them in hashmap so that their "name"s are maintained
Hop pHop = null;
for (String paramName : source.getVarParams().keySet()) {
pHop = processExpression(source.getVarParam(paramName), null, hops);
paramHops.put(paramName, pHop);
}
Hop currBuiltinOp = null;
if (target == null) {
target = createTarget(source);
}
// construct hop based on opcode
switch(source.getOpCode()) {
case CDF:
case INVCDF:
case QNORM:
case QT:
case QF:
case QCHISQ:
case QEXP:
case PNORM:
case PT:
case PF:
case PCHISQ:
case PEXP:
currBuiltinOp = constructDfHop(target.getName(), target.getDataType(), target.getValueType(), source.getOpCode(), paramHops);
break;
case GROUPEDAGG:
currBuiltinOp = new ParameterizedBuiltinOp(target.getName(), target.getDataType(), target.getValueType(), ParamBuiltinOp.GROUPEDAGG, paramHops);
break;
case RMEMPTY:
currBuiltinOp = new ParameterizedBuiltinOp(target.getName(), target.getDataType(), target.getValueType(), ParamBuiltinOp.RMEMPTY, paramHops);
break;
case REPLACE:
currBuiltinOp = new ParameterizedBuiltinOp(target.getName(), target.getDataType(), target.getValueType(), ParamBuiltinOp.REPLACE, paramHops);
break;
case ORDER:
ArrayList<Hop> inputs = new ArrayList<>();
inputs.add(paramHops.get("target"));
inputs.add(paramHops.get("by"));
inputs.add(paramHops.get("decreasing"));
inputs.add(paramHops.get("index.return"));
currBuiltinOp = new ReorgOp(target.getName(), target.getDataType(), target.getValueType(), ReOrgOp.SORT, inputs);
break;
case TRANSFORMAPPLY:
currBuiltinOp = new ParameterizedBuiltinOp(target.getName(), target.getDataType(), target.getValueType(), ParamBuiltinOp.TRANSFORMAPPLY, paramHops);
break;
case TRANSFORMDECODE:
currBuiltinOp = new ParameterizedBuiltinOp(target.getName(), target.getDataType(), target.getValueType(), ParamBuiltinOp.TRANSFORMDECODE, paramHops);
break;
case TRANSFORMCOLMAP:
currBuiltinOp = new ParameterizedBuiltinOp(target.getName(), target.getDataType(), target.getValueType(), ParamBuiltinOp.TRANSFORMCOLMAP, paramHops);
break;
case TRANSFORMMETA:
currBuiltinOp = new ParameterizedBuiltinOp(target.getName(), target.getDataType(), target.getValueType(), ParamBuiltinOp.TRANSFORMMETA, paramHops);
break;
case TOSTRING:
// check for input data type and only compile toString Hop for matrices/frames,
// for scalars, we compile (s + "") to ensure consistent string output value types
currBuiltinOp = !paramHops.get("target").getDataType().isScalar() ? new ParameterizedBuiltinOp(target.getName(), target.getDataType(), target.getValueType(), ParamBuiltinOp.TOSTRING, paramHops) : HopRewriteUtils.createBinary(paramHops.get("target"), new LiteralOp(""), OpOp2.PLUS);
break;
default:
throw new ParseException(source.printErrorLocation() + "processParameterizedBuiltinFunctionExpression() -- Unknown operation: " + source.getOpCode());
}
setIdentifierParams(currBuiltinOp, source.getOutput());
currBuiltinOp.setParseInfo(source);
return currBuiltinOp;
}
Aggregations