use of org.apache.sysml.hops.IndexingOp in project incubator-systemml by apache.
the class RewriteIndexingVectorization method vectorizeRightLeftIndexingChains.
private static Hop vectorizeRightLeftIndexingChains(Hop hi) {
// check for valid root operator
if (!(hi instanceof LeftIndexingOp && hi.getInput().get(1) instanceof IndexingOp && hi.getInput().get(1).getParent().size() == 1))
return hi;
LeftIndexingOp lix0 = (LeftIndexingOp) hi;
IndexingOp rix0 = (IndexingOp) hi.getInput().get(1);
if (!(lix0.isRowLowerEqualsUpper() || lix0.isColLowerEqualsUpper()) || lix0.isRowLowerEqualsUpper() != rix0.isRowLowerEqualsUpper() || lix0.isColLowerEqualsUpper() != rix0.isColLowerEqualsUpper())
return hi;
boolean row = lix0.isRowLowerEqualsUpper();
if (!((row ? HopRewriteUtils.isFullRowIndexing(lix0) : HopRewriteUtils.isFullColumnIndexing(lix0)) && (row ? HopRewriteUtils.isFullRowIndexing(rix0) : HopRewriteUtils.isFullColumnIndexing(rix0))))
return hi;
// determine consecutive left-right indexing chains for rows/columns
List<LeftIndexingOp> lix = new ArrayList<>();
lix.add(lix0);
List<IndexingOp> rix = new ArrayList<>();
rix.add(rix0);
LeftIndexingOp clix = lix0;
IndexingOp crix = rix0;
while (isConsecutiveLeftRightIndexing(clix, crix, clix.getInput().get(0)) && clix.getInput().get(0).getParent().size() == 1 && clix.getInput().get(0).getInput().get(1).getParent().size() == 1) {
clix = (LeftIndexingOp) clix.getInput().get(0);
crix = (IndexingOp) clix.getInput().get(1);
lix.add(clix);
rix.add(crix);
}
// rewrite pattern if at least two consecutive pairs
if (lix.size() >= 2) {
IndexingOp rixn = rix.get(rix.size() - 1);
Hop rlrix = rixn.getInput().get(1);
Hop rurix = row ? HopRewriteUtils.createBinary(rlrix, new LiteralOp(rix.size() - 1), OpOp2.PLUS) : rixn.getInput().get(2);
Hop clrix = rixn.getInput().get(3);
Hop curix = row ? rixn.getInput().get(4) : HopRewriteUtils.createBinary(clrix, new LiteralOp(rix.size() - 1), OpOp2.PLUS);
IndexingOp rixNew = HopRewriteUtils.createIndexingOp(rixn.getInput().get(0), rlrix, rurix, clrix, curix);
LeftIndexingOp lixn = lix.get(rix.size() - 1);
Hop rllix = lixn.getInput().get(2);
Hop rulix = row ? HopRewriteUtils.createBinary(rllix, new LiteralOp(lix.size() - 1), OpOp2.PLUS) : lixn.getInput().get(3);
Hop cllix = lixn.getInput().get(4);
Hop culix = row ? lixn.getInput().get(5) : HopRewriteUtils.createBinary(cllix, new LiteralOp(lix.size() - 1), OpOp2.PLUS);
LeftIndexingOp lixNew = HopRewriteUtils.createLeftIndexingOp(lixn.getInput().get(0), rixNew, rllix, rulix, cllix, culix);
// rewire parents and childs
HopRewriteUtils.replaceChildReference(hi.getParent().get(0), hi, lixNew);
for (int i = 0; i < lix.size(); i++) {
HopRewriteUtils.removeAllChildReferences(lix.get(i));
HopRewriteUtils.removeAllChildReferences(rix.get(i));
}
hi = lixNew;
LOG.debug("Applied vectorizeRightLeftIndexingChains (line " + hi.getBeginLine() + ")");
}
return hi;
}
use of org.apache.sysml.hops.IndexingOp in project incubator-systemml by apache.
the class RewriteIndexingVectorization method vectorizeLeftIndexing.
@SuppressWarnings("unchecked")
private static Hop vectorizeLeftIndexing(Hop hop) {
Hop ret = hop;
if (// left indexing
hop instanceof LeftIndexingOp) {
LeftIndexingOp ihop0 = (LeftIndexingOp) hop;
boolean isSingleRow = ihop0.isRowLowerEqualsUpper();
boolean isSingleCol = ihop0.isColLowerEqualsUpper();
boolean appliedRow = false;
if (isSingleRow && isSingleCol) {
// collect simple chains (w/o multiple consumers) of left indexing ops
ArrayList<Hop> ihops = new ArrayList<>();
ihops.add(ihop0);
Hop current = ihop0;
while (current.getInput().get(0) instanceof LeftIndexingOp) {
LeftIndexingOp tmp = (LeftIndexingOp) current.getInput().get(0);
if (// multiple consumers, i.e., not a simple chain
tmp.getParent().size() > 1 || // row merge not applicable
!((LeftIndexingOp) tmp).isRowLowerEqualsUpper() || // not the same row
tmp.getInput().get(2) != ihop0.getInput().get(2) || // target is single column or unknown
tmp.getInput().get(0).getDim2() <= 1) {
break;
}
ihops.add(tmp);
current = tmp;
}
// apply rewrite if found candidates
if (ihops.size() > 1) {
Hop input = current.getInput().get(0);
// keep before reset
Hop rowExpr = ihop0.getInput().get(2);
// new row indexing operator
IndexingOp newRix = new IndexingOp("tmp1", input.getDataType(), input.getValueType(), input, rowExpr, rowExpr, new LiteralOp(1), HopRewriteUtils.createValueHop(input, false), true, false);
HopRewriteUtils.setOutputParameters(newRix, -1, -1, input.getRowsInBlock(), input.getColsInBlock(), -1);
newRix.refreshSizeInformation();
// reset visit status of copied hops (otherwise hidden by left indexing)
for (Hop c : newRix.getInput()) c.resetVisitStatus();
// rewrite bottom left indexing operator
// input data
HopRewriteUtils.removeChildReference(current, input);
HopRewriteUtils.addChildReference(current, newRix, 0);
// reset row index all candidates and refresh sizes (bottom-up)
for (int i = ihops.size() - 1; i >= 0; i--) {
Hop c = ihops.get(i);
// row lower expr
HopRewriteUtils.replaceChildReference(c, c.getInput().get(2), new LiteralOp(1), 2);
// row upper expr
HopRewriteUtils.replaceChildReference(c, c.getInput().get(3), new LiteralOp(1), 3);
((LeftIndexingOp) c).setRowLowerEqualsUpper(true);
c.refreshSizeInformation();
}
// new row left indexing operator (for all parents, only intermediates are guaranteed to have 1 parent)
// (note: it's important to clone the parent list before creating newLix on top of ihop0)
ArrayList<Hop> ihop0parents = (ArrayList<Hop>) ihop0.getParent().clone();
ArrayList<Integer> ihop0parentsPos = new ArrayList<>();
for (Hop parent : ihop0parents) {
int posp = HopRewriteUtils.getChildReferencePos(parent, ihop0);
// input data
HopRewriteUtils.removeChildReferenceByPos(parent, ihop0, posp);
ihop0parentsPos.add(posp);
}
LeftIndexingOp newLix = new LeftIndexingOp("tmp2", input.getDataType(), input.getValueType(), input, ihop0, rowExpr, rowExpr, new LiteralOp(1), HopRewriteUtils.createValueHop(input, false), true, false);
HopRewriteUtils.setOutputParameters(newLix, -1, -1, input.getRowsInBlock(), input.getColsInBlock(), -1);
newLix.refreshSizeInformation();
// reset visit status of copied hops (otherwise hidden by left indexing)
for (Hop c : newLix.getInput()) c.resetVisitStatus();
for (int i = 0; i < ihop0parentsPos.size(); i++) {
Hop parent = ihop0parents.get(i);
int posp = ihop0parentsPos.get(i);
HopRewriteUtils.addChildReference(parent, newLix, posp);
}
appliedRow = true;
ret = newLix;
LOG.debug("Applied vectorizeLeftIndexingRow for hop " + hop.getHopID());
}
}
if (isSingleRow && isSingleCol && !appliedRow) {
// collect simple chains (w/o multiple consumers) of left indexing ops
ArrayList<Hop> ihops = new ArrayList<>();
ihops.add(ihop0);
Hop current = ihop0;
while (current.getInput().get(0) instanceof LeftIndexingOp) {
LeftIndexingOp tmp = (LeftIndexingOp) current.getInput().get(0);
if (// multiple consumers, i.e., not a simple chain
tmp.getParent().size() > 1 || // row merge not applicable
!((LeftIndexingOp) tmp).isColLowerEqualsUpper() || // not the same col
tmp.getInput().get(4) != ihop0.getInput().get(4) || // target is single row or unknown
tmp.getInput().get(0).getDim1() <= 1) {
break;
}
ihops.add(tmp);
current = tmp;
}
// apply rewrite if found candidates
if (ihops.size() > 1) {
Hop input = current.getInput().get(0);
// keep before reset
Hop colExpr = ihop0.getInput().get(4);
// new row indexing operator
IndexingOp newRix = new IndexingOp("tmp1", input.getDataType(), input.getValueType(), input, new LiteralOp(1), HopRewriteUtils.createValueHop(input, true), colExpr, colExpr, false, true);
HopRewriteUtils.setOutputParameters(newRix, -1, -1, input.getRowsInBlock(), input.getColsInBlock(), -1);
newRix.refreshSizeInformation();
// reset visit status of copied hops (otherwise hidden by left indexing)
for (Hop c : newRix.getInput()) c.resetVisitStatus();
// rewrite bottom left indexing operator
// input data
HopRewriteUtils.removeChildReference(current, input);
HopRewriteUtils.addChildReference(current, newRix, 0);
// reset col index all candidates and refresh sizes (bottom-up)
for (int i = ihops.size() - 1; i >= 0; i--) {
Hop c = ihops.get(i);
// col lower expr
HopRewriteUtils.replaceChildReference(c, c.getInput().get(4), new LiteralOp(1), 4);
// col upper expr
HopRewriteUtils.replaceChildReference(c, c.getInput().get(5), new LiteralOp(1), 5);
((LeftIndexingOp) c).setColLowerEqualsUpper(true);
c.refreshSizeInformation();
}
// new row left indexing operator (for all parents, only intermediates are guaranteed to have 1 parent)
// (note: it's important to clone the parent list before creating newLix on top of ihop0)
ArrayList<Hop> ihop0parents = (ArrayList<Hop>) ihop0.getParent().clone();
ArrayList<Integer> ihop0parentsPos = new ArrayList<>();
for (Hop parent : ihop0parents) {
int posp = HopRewriteUtils.getChildReferencePos(parent, ihop0);
// input data
HopRewriteUtils.removeChildReferenceByPos(parent, ihop0, posp);
ihop0parentsPos.add(posp);
}
LeftIndexingOp newLix = new LeftIndexingOp("tmp2", input.getDataType(), input.getValueType(), input, ihop0, new LiteralOp(1), HopRewriteUtils.createValueHop(input, true), colExpr, colExpr, false, true);
HopRewriteUtils.setOutputParameters(newLix, -1, -1, input.getRowsInBlock(), input.getColsInBlock(), -1);
newLix.refreshSizeInformation();
// reset visit status of copied hops (otherwise hidden by left indexing)
for (Hop c : newLix.getInput()) c.resetVisitStatus();
for (int i = 0; i < ihop0parentsPos.size(); i++) {
Hop parent = ihop0parents.get(i);
int posp = ihop0parentsPos.get(i);
HopRewriteUtils.addChildReference(parent, newLix, posp);
}
ret = newLix;
LOG.debug("Applied vectorizeLeftIndexingCol for hop " + hop.getHopID());
}
}
}
return ret;
}
use of org.apache.sysml.hops.IndexingOp in project incubator-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 incubator-systemml by apache.
the class LiteralReplacement method replaceLiteralValueTypeCastRightIndexing.
private static LiteralOp replaceLiteralValueTypeCastRightIndexing(Hop c, LocalVariableMap vars) {
LiteralOp ret = null;
// as.scalar/right indexing w/ literals/vars and matrix less than 10^6 cells
if (c instanceof UnaryOp && ((UnaryOp) c).getOp() == OpOp1.CAST_AS_SCALAR && c.getInput().get(0) instanceof IndexingOp && c.getInput().get(0).getDataType() == DataType.MATRIX) {
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 (rix.dimsKnown() && rix.getDim1() == 1 && rix.getDim2() == 1 && 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 clval = getIntValueDataLiteral(cl, 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();
double value = mBlock.getValue((int) rlval - 1, (int) clval - 1);
mo.release();
// literal substitution (always double)
ret = new LiteralOp(value);
}
}
}
return ret;
}
use of org.apache.sysml.hops.IndexingOp in project incubator-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