use of org.apache.sysml.runtime.util.IndexRange in project systemml by apache.
the class OperationsOnMatrixValues method performSlice.
/**
* This function will get slice of the input frame block overlapping in overall slice(Range), slice has requested for.
*
* @param in ?
* @param ixrange index range
* @param brlen number of rows in a block
* @param bclen number of columns in a block
* @param outlist list of pairs of frame blocks
*/
public static void performSlice(Pair<Long, FrameBlock> in, IndexRange ixrange, int brlen, int bclen, ArrayList<Pair<Long, FrameBlock>> outlist) {
long index = in.getKey();
FrameBlock block = in.getValue();
// Get Block indexes (rows and columns boundaries)
long cellIndexTopRow = index;
long cellIndexBottomRow = index + block.getNumRows() - 1;
long cellIndexLeftCol = 1;
long cellIndexRightCol = block.getNumColumns();
// Calculate block boundaries with range of slice to be performed (Global index)
long cellIndexOverlapTop = Math.max(cellIndexTopRow, ixrange.rowStart);
long cellIndexOverlapBottom = Math.min(cellIndexBottomRow, ixrange.rowEnd);
long cellIndexOverlapLeft = Math.max(cellIndexLeftCol, ixrange.colStart);
long cellIndexOverlapRight = Math.min(cellIndexRightCol, ixrange.colEnd);
// check if block is outside the indexing range
if (cellIndexOverlapTop > cellIndexOverlapBottom || cellIndexOverlapLeft > cellIndexOverlapRight) {
return;
}
// Create IndexRange for the slice to be performed on this block.
IndexRange tmpRange = new IndexRange(cellIndexOverlapTop - index, cellIndexOverlapBottom - index, cellIndexOverlapLeft - 1, cellIndexOverlapRight - 1);
// Get Top Row and Left column cutting point.
int rowCut = (int) (ixrange.rowStart - index);
// Get indices for result block
long resultBlockIndexTop = UtilFunctions.computeBlockIndex(cellIndexOverlapTop, brlen);
long resultBlockIndexBottom = UtilFunctions.computeBlockIndex(cellIndexOverlapBottom, brlen);
// allocate space for the output value
for (long r = resultBlockIndexTop; r <= resultBlockIndexBottom; r++) {
ValueType[] schema = Arrays.copyOfRange(block.getSchema(), (int) tmpRange.colStart, (int) tmpRange.colEnd + 1);
long iResultIndex = Math.max(((r - 1) * brlen - ixrange.rowStart + 1), 0);
Pair<Long, FrameBlock> out = new Pair<>(new Long(iResultIndex + 1), new FrameBlock(schema));
outlist.add(out);
}
// execute actual slice operation
block.slice(outlist, tmpRange, rowCut);
}
use of org.apache.sysml.runtime.util.IndexRange in project systemml by apache.
the class FrameIndexingSPInstruction method processInstruction.
@Override
public void processInstruction(ExecutionContext ec) {
SparkExecutionContext sec = (SparkExecutionContext) ec;
String opcode = getOpcode();
// get indexing range
long rl = ec.getScalarInput(rowLower.getName(), rowLower.getValueType(), rowLower.isLiteral()).getLongValue();
long ru = ec.getScalarInput(rowUpper.getName(), rowUpper.getValueType(), rowUpper.isLiteral()).getLongValue();
long cl = ec.getScalarInput(colLower.getName(), colLower.getValueType(), colLower.isLiteral()).getLongValue();
long cu = ec.getScalarInput(colUpper.getName(), colUpper.getValueType(), colUpper.isLiteral()).getLongValue();
IndexRange ixrange = new IndexRange(rl, ru, cl, cu);
// right indexing
if (opcode.equalsIgnoreCase(RightIndex.OPCODE)) {
// update and check output dimensions
MatrixCharacteristics mcIn = sec.getMatrixCharacteristics(input1.getName());
MatrixCharacteristics mcOut = sec.getMatrixCharacteristics(output.getName());
mcOut.set(ru - rl + 1, cu - cl + 1, mcIn.getRowsPerBlock(), mcIn.getColsPerBlock());
checkValidOutputDimensions(mcOut);
// execute right indexing operation (partitioning-preserving if possible)
JavaPairRDD<Long, FrameBlock> in1 = sec.getFrameBinaryBlockRDDHandleForVariable(input1.getName());
JavaPairRDD<Long, FrameBlock> out = null;
if (isPartitioningPreservingRightIndexing(mcIn, ixrange)) {
out = in1.mapPartitionsToPair(new SliceBlockPartitionFunction(ixrange, mcOut), true);
} else {
out = in1.filter(new IsFrameBlockInRange(rl, ru, mcOut)).mapToPair(new SliceBlock(ixrange, mcOut));
}
// put output RDD handle into symbol table
sec.setRDDHandleForVariable(output.getName(), out);
sec.addLineageRDD(output.getName(), input1.getName());
// update schema of output with subset of input schema
sec.getFrameObject(output.getName()).setSchema(sec.getFrameObject(input1.getName()).getSchema((int) cl, (int) cu));
} else // left indexing
if (opcode.equalsIgnoreCase(LeftIndex.OPCODE) || opcode.equalsIgnoreCase("mapLeftIndex")) {
JavaPairRDD<Long, FrameBlock> in1 = sec.getFrameBinaryBlockRDDHandleForVariable(input1.getName());
PartitionedBroadcast<FrameBlock> broadcastIn2 = null;
JavaPairRDD<Long, FrameBlock> in2 = null;
JavaPairRDD<Long, FrameBlock> out = null;
// update and check output dimensions
MatrixCharacteristics mcOut = sec.getMatrixCharacteristics(output.getName());
MatrixCharacteristics mcLeft = ec.getMatrixCharacteristics(input1.getName());
mcOut.set(mcLeft.getRows(), mcLeft.getCols(), mcLeft.getRowsPerBlock(), mcLeft.getColsPerBlock());
checkValidOutputDimensions(mcOut);
// note: always frame rhs, scalars are preprocessed via cast to 1x1 frame
MatrixCharacteristics mcRight = ec.getMatrixCharacteristics(input2.getName());
// sanity check matching index range and rhs dimensions
if (!mcRight.dimsKnown()) {
throw new DMLRuntimeException("The right input frame dimensions are not specified for FrameIndexingSPInstruction");
}
if (!(ru - rl + 1 == mcRight.getRows() && cu - cl + 1 == mcRight.getCols())) {
throw new DMLRuntimeException("Invalid index range of leftindexing: [" + rl + ":" + ru + "," + cl + ":" + cu + "] vs [" + mcRight.getRows() + "x" + mcRight.getCols() + "].");
}
if (opcode.equalsIgnoreCase("mapLeftIndex")) {
broadcastIn2 = sec.getBroadcastForFrameVariable(input2.getName());
// partitioning-preserving mappartitions (key access required for broadcast loopkup)
out = in1.mapPartitionsToPair(new LeftIndexPartitionFunction(broadcastIn2, ixrange, mcOut), true);
} else {
// general case
// zero-out lhs
in1 = in1.flatMapToPair(new ZeroOutLHS(false, ixrange, mcLeft));
// slice rhs, shift and merge with lhs
in2 = sec.getFrameBinaryBlockRDDHandleForVariable(input2.getName()).flatMapToPair(new SliceRHSForLeftIndexing(ixrange, mcLeft));
out = FrameRDDAggregateUtils.mergeByKey(in1.union(in2));
}
sec.setRDDHandleForVariable(output.getName(), out);
sec.addLineageRDD(output.getName(), input1.getName());
if (broadcastIn2 != null)
sec.addLineageBroadcast(output.getName(), input2.getName());
if (in2 != null)
sec.addLineageRDD(output.getName(), input2.getName());
} else
throw new DMLRuntimeException("Invalid opcode (" + opcode + ") encountered in FrameIndexingSPInstruction.");
}
use of org.apache.sysml.runtime.util.IndexRange in project systemml by apache.
the class PartitionedBlock method slice.
/**
* Utility for slice operations over partitioned matrices, where the index range can cover
* multiple blocks. The result is always a single result matrix block. All semantics are
* equivalent to the core matrix block slice operations.
*
* @param rl row lower bound
* @param ru row upper bound
* @param cl column lower bound
* @param cu column upper bound
* @param block block object
* @return block object
*/
@SuppressWarnings("unchecked")
public T slice(long rl, long ru, long cl, long cu, T block) {
int lrl = (int) rl;
int lru = (int) ru;
int lcl = (int) cl;
int lcu = (int) cu;
ArrayList<Pair<?, ?>> allBlks = (ArrayList<Pair<?, ?>>) CacheBlockFactory.getPairList(block);
int start_iix = (lrl - 1) / _brlen + 1;
int end_iix = (lru - 1) / _brlen + 1;
int start_jix = (lcl - 1) / _bclen + 1;
int end_jix = (lcu - 1) / _bclen + 1;
for (int iix = start_iix; iix <= end_iix; iix++) for (int jix = start_jix; jix <= end_jix; jix++) {
IndexRange ixrange = new IndexRange(rl, ru, cl, cu);
allBlks.addAll(OperationsOnMatrixValues.performSlice(ixrange, _brlen, _bclen, iix, jix, getBlock(iix, jix)));
}
if (allBlks.size() == 1) {
return (T) allBlks.get(0).getValue();
} else {
// allocate output matrix
Constructor<?> constr;
try {
constr = block.getClass().getConstructor(int.class, int.class, boolean.class);
T ret = (T) constr.newInstance(lru - lrl + 1, lcu - lcl + 1, false);
for (Pair<?, ?> kv : allBlks) {
ret.merge((T) kv.getValue(), false);
}
return ret;
} catch (Exception e) {
throw new DMLRuntimeException(e);
}
}
}
Aggregations