use of org.apache.sysml.hops.IndexingOp in project systemml by apache.
the class RewriteAlgebraicSimplificationStatic method simplifySlicedMatrixMult.
private static Hop simplifySlicedMatrixMult(Hop parent, Hop hi, int pos) {
// e.g., (X%*%Y)[1,1] -> X[1,] %*% Y[,1]
if (hi instanceof IndexingOp && ((IndexingOp) hi).isRowLowerEqualsUpper() && ((IndexingOp) hi).isColLowerEqualsUpper() && // rix is single mm consumer
hi.getInput().get(0).getParent().size() == 1 && HopRewriteUtils.isMatrixMultiply(hi.getInput().get(0))) {
Hop mm = hi.getInput().get(0);
Hop X = mm.getInput().get(0);
Hop Y = mm.getInput().get(1);
// rl==ru
Hop rowExpr = hi.getInput().get(1);
// cl==cu
Hop colExpr = hi.getInput().get(3);
HopRewriteUtils.removeAllChildReferences(mm);
// create new indexing operations
IndexingOp ix1 = new IndexingOp("tmp1", DataType.MATRIX, ValueType.DOUBLE, X, rowExpr, rowExpr, new LiteralOp(1), HopRewriteUtils.createValueHop(X, false), true, false);
ix1.setOutputBlocksizes(X.getRowsInBlock(), X.getColsInBlock());
ix1.refreshSizeInformation();
IndexingOp ix2 = new IndexingOp("tmp2", DataType.MATRIX, ValueType.DOUBLE, Y, new LiteralOp(1), HopRewriteUtils.createValueHop(Y, true), colExpr, colExpr, false, true);
ix2.setOutputBlocksizes(Y.getRowsInBlock(), Y.getColsInBlock());
ix2.refreshSizeInformation();
// rewire matrix mult over ix1 and ix2
HopRewriteUtils.addChildReference(mm, ix1, 0);
HopRewriteUtils.addChildReference(mm, ix2, 1);
mm.refreshSizeInformation();
hi = mm;
LOG.debug("Applied simplifySlicedMatrixMult");
}
return hi;
}
use of org.apache.sysml.hops.IndexingOp in project systemml by apache.
the class RewriteForLoopVectorization method vectorizeElementwiseBinary.
private static StatementBlock vectorizeElementwiseBinary(StatementBlock sb, StatementBlock csb, Hop from, Hop to, Hop increment, String itervar) {
StatementBlock ret = sb;
// check supported increment values
if (!(increment instanceof LiteralOp && ((LiteralOp) increment).getDoubleValue() == 1.0)) {
return ret;
}
// check for applicability
boolean apply = false;
// row or col
boolean rowIx = false;
if (csb.getHops() != null && csb.getHops().size() == 1) {
Hop root = csb.getHops().get(0);
if (root.getDataType() == DataType.MATRIX && root.getInput().get(0) instanceof LeftIndexingOp) {
LeftIndexingOp lix = (LeftIndexingOp) root.getInput().get(0);
Hop lixlhs = lix.getInput().get(0);
Hop lixrhs = lix.getInput().get(1);
if (lixlhs instanceof DataOp && lixrhs instanceof BinaryOp && lixrhs.getInput().get(0) instanceof IndexingOp && lixrhs.getInput().get(1) instanceof IndexingOp && lixrhs.getInput().get(0).getInput().get(0) instanceof DataOp && lixrhs.getInput().get(1).getInput().get(0) instanceof DataOp) {
IndexingOp rix0 = (IndexingOp) lixrhs.getInput().get(0);
IndexingOp rix1 = (IndexingOp) lixrhs.getInput().get(1);
// check for rowwise
if (lix.isRowLowerEqualsUpper() && rix0.isRowLowerEqualsUpper() && rix1.isRowLowerEqualsUpper() && lix.getInput().get(2).getName().equals(itervar) && rix0.getInput().get(1).getName().equals(itervar) && rix1.getInput().get(1).getName().equals(itervar)) {
apply = true;
rowIx = true;
}
// check for colwise
if (lix.isColLowerEqualsUpper() && rix0.isColLowerEqualsUpper() && rix1.isColLowerEqualsUpper() && lix.getInput().get(4).getName().equals(itervar) && rix0.getInput().get(3).getName().equals(itervar) && rix1.getInput().get(3).getName().equals(itervar)) {
apply = true;
rowIx = false;
}
}
}
}
// apply rewrite if possible
if (apply) {
Hop root = csb.getHops().get(0);
LeftIndexingOp lix = (LeftIndexingOp) root.getInput().get(0);
BinaryOp bop = (BinaryOp) lix.getInput().get(1);
IndexingOp rix0 = (IndexingOp) bop.getInput().get(0);
IndexingOp rix1 = (IndexingOp) bop.getInput().get(1);
int index1 = rowIx ? 2 : 4;
int index2 = rowIx ? 3 : 5;
// modify left indexing bounds
HopRewriteUtils.replaceChildReference(lix, lix.getInput().get(index1), from, index1);
HopRewriteUtils.replaceChildReference(lix, lix.getInput().get(index2), to, index2);
// modify both right indexing
HopRewriteUtils.replaceChildReference(rix0, rix0.getInput().get(index1 - 1), from, index1 - 1);
HopRewriteUtils.replaceChildReference(rix0, rix0.getInput().get(index2 - 1), to, index2 - 1);
HopRewriteUtils.replaceChildReference(rix1, rix1.getInput().get(index1 - 1), from, index1 - 1);
HopRewriteUtils.replaceChildReference(rix1, rix1.getInput().get(index2 - 1), to, index2 - 1);
updateLeftAndRightIndexingSizes(rowIx, lix, rix0, rix1);
bop.refreshSizeInformation();
// after bop update
lix.refreshSizeInformation();
ret = csb;
// ret.liveIn().removeVariable(itervar);
LOG.debug("Applied vectorizeElementwiseBinaryForLoop.");
}
return ret;
}
use of org.apache.sysml.hops.IndexingOp in project systemml by apache.
the class RewriteForLoopVectorization method vectorizeElementwiseUnary.
private static StatementBlock vectorizeElementwiseUnary(StatementBlock sb, StatementBlock csb, Hop from, Hop to, Hop increment, String itervar) {
StatementBlock ret = sb;
// check supported increment values
if (!(increment instanceof LiteralOp && ((LiteralOp) increment).getDoubleValue() == 1.0)) {
return ret;
}
// check for applicability
boolean apply = false;
// row or col
boolean rowIx = false;
if (csb.getHops() != null && csb.getHops().size() == 1) {
Hop root = csb.getHops().get(0);
if (root.getDataType() == DataType.MATRIX && root.getInput().get(0) instanceof LeftIndexingOp) {
LeftIndexingOp lix = (LeftIndexingOp) root.getInput().get(0);
Hop lixlhs = lix.getInput().get(0);
Hop lixrhs = lix.getInput().get(1);
if (lixlhs instanceof DataOp && lixrhs instanceof UnaryOp && lixrhs.getInput().get(0) instanceof IndexingOp && lixrhs.getInput().get(0).getInput().get(0) instanceof DataOp) {
boolean[] tmp = checkLeftAndRightIndexing(lix, (IndexingOp) lixrhs.getInput().get(0), itervar);
apply = tmp[0];
rowIx = tmp[1];
}
}
}
// apply rewrite if possible
if (apply) {
Hop root = csb.getHops().get(0);
LeftIndexingOp lix = (LeftIndexingOp) root.getInput().get(0);
UnaryOp uop = (UnaryOp) lix.getInput().get(1);
IndexingOp rix = (IndexingOp) uop.getInput().get(0);
int index1 = rowIx ? 2 : 4;
int index2 = rowIx ? 3 : 5;
// modify left indexing bounds
HopRewriteUtils.replaceChildReference(lix, lix.getInput().get(index1), from, index1);
HopRewriteUtils.replaceChildReference(lix, lix.getInput().get(index2), to, index2);
// modify right indexing
HopRewriteUtils.replaceChildReference(rix, rix.getInput().get(index1 - 1), from, index1 - 1);
HopRewriteUtils.replaceChildReference(rix, rix.getInput().get(index2 - 1), to, index2 - 1);
updateLeftAndRightIndexingSizes(rowIx, lix, rix);
uop.refreshSizeInformation();
// after uop update
lix.refreshSizeInformation();
ret = csb;
LOG.debug("Applied vectorizeElementwiseUnaryForLoop.");
}
return ret;
}
use of org.apache.sysml.hops.IndexingOp in project systemml by apache.
the class LiteralReplacement method replaceLiteralFullUnaryAggregateRightIndexing.
private static LiteralOp replaceLiteralFullUnaryAggregateRightIndexing(Hop c, LocalVariableMap vars) {
LiteralOp ret = null;
// full unary aggregate w/ indexed matrix less than 10^6 cells
if (c instanceof AggUnaryOp && isReplaceableUnaryAggregate((AggUnaryOp) c) && c.getInput().get(0) instanceof IndexingOp && c.getInput().get(0).getInput().get(0) instanceof DataOp) {
IndexingOp rix = (IndexingOp) c.getInput().get(0);
Hop data = rix.getInput().get(0);
Hop rl = rix.getInput().get(1);
Hop ru = rix.getInput().get(2);
Hop cl = rix.getInput().get(3);
Hop cu = rix.getInput().get(4);
if (data instanceof DataOp && vars.keySet().contains(data.getName()) && isIntValueDataLiteral(rl, vars) && isIntValueDataLiteral(ru, vars) && isIntValueDataLiteral(cl, vars) && isIntValueDataLiteral(cu, vars)) {
long rlval = getIntValueDataLiteral(rl, vars);
long ruval = getIntValueDataLiteral(ru, vars);
long clval = getIntValueDataLiteral(cl, vars);
long cuval = getIntValueDataLiteral(cu, vars);
MatrixObject mo = (MatrixObject) vars.get(data.getName());
// dimensions might not have been updated during recompile
if (mo.getNumRows() * mo.getNumColumns() < REPLACE_LITERALS_MAX_MATRIX_SIZE) {
MatrixBlock mBlock = mo.acquireRead();
MatrixBlock mBlock2 = mBlock.slice((int) (rlval - 1), (int) (ruval - 1), (int) (clval - 1), (int) (cuval - 1), new MatrixBlock());
double value = replaceUnaryAggregate((AggUnaryOp) c, mBlock2);
mo.release();
// literal substitution (always double)
ret = new LiteralOp(value);
}
}
}
return ret;
}
use of org.apache.sysml.hops.IndexingOp in project systemml by apache.
the class Recompiler method rUpdateStatistics.
public static void rUpdateStatistics(Hop hop, LocalVariableMap vars) {
if (hop.isVisited())
return;
// recursively process children
if (hop.getInput() != null)
for (Hop c : hop.getInput()) rUpdateStatistics(c, vars);
boolean updatedSizeExpr = false;
// (with awareness not to override persistent reads to an existing name)
if (hop instanceof DataOp && ((DataOp) hop).getDataOpType() != DataOpTypes.PERSISTENTREAD) {
DataOp d = (DataOp) hop;
String varName = d.getName();
if (vars.keySet().contains(varName)) {
Data dat = vars.get(varName);
if (dat instanceof MatrixObject) {
MatrixObject mo = (MatrixObject) dat;
d.setDim1(mo.getNumRows());
d.setDim2(mo.getNumColumns());
d.setNnz(mo.getNnz());
} else if (dat instanceof FrameObject) {
FrameObject fo = (FrameObject) dat;
d.setDim1(fo.getNumRows());
d.setDim2(fo.getNumColumns());
}
}
} else // special case for persistent reads with unknown size (read-after-write)
if (hop instanceof DataOp && ((DataOp) hop).getDataOpType() == DataOpTypes.PERSISTENTREAD && !hop.dimsKnown() && ((DataOp) hop).getInputFormatType() != FileFormatTypes.CSV && !ConfigurationManager.getCompilerConfigFlag(ConfigType.IGNORE_READ_WRITE_METADATA)) {
// update hop with read meta data
DataOp dop = (DataOp) hop;
tryReadMetaDataFileMatrixCharacteristics(dop);
} else // update size expression for rand/seq according to symbol table entries
if (hop instanceof DataGenOp) {
DataGenOp d = (DataGenOp) hop;
HashMap<String, Integer> params = d.getParamIndexMap();
if (d.getOp() == DataGenMethod.RAND || d.getOp() == DataGenMethod.SINIT || d.getOp() == DataGenMethod.SAMPLE) {
boolean initUnknown = !d.dimsKnown();
int ix1 = params.get(DataExpression.RAND_ROWS);
int ix2 = params.get(DataExpression.RAND_COLS);
// update rows/cols by evaluating simple expression of literals, nrow, ncol, scalars, binaryops
HashMap<Long, Long> memo = new HashMap<>();
d.refreshRowsParameterInformation(d.getInput().get(ix1), vars, memo);
d.refreshColsParameterInformation(d.getInput().get(ix2), vars, memo);
updatedSizeExpr = initUnknown & d.dimsKnown();
} else if (d.getOp() == DataGenMethod.SEQ) {
boolean initUnknown = !d.dimsKnown();
int ix1 = params.get(Statement.SEQ_FROM);
int ix2 = params.get(Statement.SEQ_TO);
int ix3 = params.get(Statement.SEQ_INCR);
HashMap<Long, Double> memo = new HashMap<>();
double from = d.computeBoundsInformation(d.getInput().get(ix1), vars, memo);
double to = d.computeBoundsInformation(d.getInput().get(ix2), vars, memo);
double incr = d.computeBoundsInformation(d.getInput().get(ix3), vars, memo);
// special case increment
if (from != Double.MAX_VALUE && to != Double.MAX_VALUE) {
incr *= ((from > to && incr > 0) || (from < to && incr < 0)) ? -1.0 : 1.0;
}
if (from != Double.MAX_VALUE && to != Double.MAX_VALUE && incr != Double.MAX_VALUE) {
d.setDim1(UtilFunctions.getSeqLength(from, to, incr));
d.setDim2(1);
d.setIncrementValue(incr);
}
updatedSizeExpr = initUnknown & d.dimsKnown();
} else {
throw new DMLRuntimeException("Unexpected data generation method: " + d.getOp());
}
} else // update size expression for reshape according to symbol table entries
if (hop instanceof ReorgOp && ((ReorgOp) (hop)).getOp() == Hop.ReOrgOp.RESHAPE) {
ReorgOp d = (ReorgOp) hop;
boolean initUnknown = !d.dimsKnown();
HashMap<Long, Long> memo = new HashMap<>();
d.refreshRowsParameterInformation(d.getInput().get(1), vars, memo);
d.refreshColsParameterInformation(d.getInput().get(2), vars, memo);
updatedSizeExpr = initUnknown & d.dimsKnown();
} else // update size expression for indexing according to symbol table entries
if (hop instanceof IndexingOp) {
IndexingOp iop = (IndexingOp) hop;
// inpRowL
Hop input2 = iop.getInput().get(1);
// inpRowU
Hop input3 = iop.getInput().get(2);
// inpColL
Hop input4 = iop.getInput().get(3);
// inpColU
Hop input5 = iop.getInput().get(4);
boolean initUnknown = !iop.dimsKnown();
HashMap<Long, Double> memo = new HashMap<>();
double rl = iop.computeBoundsInformation(input2, vars, memo);
double ru = iop.computeBoundsInformation(input3, vars, memo);
double cl = iop.computeBoundsInformation(input4, vars, memo);
double cu = iop.computeBoundsInformation(input5, vars, memo);
if (rl != Double.MAX_VALUE && ru != Double.MAX_VALUE)
iop.setDim1((long) (ru - rl + 1));
if (cl != Double.MAX_VALUE && cu != Double.MAX_VALUE)
iop.setDim2((long) (cu - cl + 1));
updatedSizeExpr = initUnknown & iop.dimsKnown();
}
// without overwriting inferred size expressions
if (!updatedSizeExpr) {
hop.refreshSizeInformation();
}
hop.setVisited();
}
Aggregations