[SYSTEMML-1960] Shallow copy on right-indexing of sparse row batches This patch improves the performance of rightindexing row batches from sparse matrices with X[rl:ru, ]. In case of our default MCSR sparse block representation, we now use a shallow copy (pointer move) of rows because the physical row representation remains unchanged. Result correctness is ensured because we only use this in the CP matrix indexing instruction, where other instructions are guaranteed to adhere to copy on write semantics.
Project: http://git-wip-us.apache.org/repos/asf/systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/8ca61ae2 Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/8ca61ae2 Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/8ca61ae2 Branch: refs/heads/master Commit: 8ca61ae269ce4e365c57f74ff0487d483766ccf6 Parents: db725de Author: Matthias Boehm <mboe...@gmail.com> Authored: Fri Oct 13 23:29:40 2017 -0700 Committer: Matthias Boehm <mboe...@gmail.com> Committed: Sat Oct 14 02:30:38 2017 -0700 ---------------------------------------------------------------------- .../cp/MatrixIndexingCPInstruction.java | 16 +++++++------ .../data/BinaryBlockToRowBlockConverter.java | 3 +-- .../sysml/runtime/matrix/data/MatrixBlock.java | 25 +++++++++++++------- 3 files changed, 26 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/systemml/blob/8ca61ae2/src/main/java/org/apache/sysml/runtime/instructions/cp/MatrixIndexingCPInstruction.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/cp/MatrixIndexingCPInstruction.java b/src/main/java/org/apache/sysml/runtime/instructions/cp/MatrixIndexingCPInstruction.java index 85c2a3d..bee0434 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/cp/MatrixIndexingCPInstruction.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/cp/MatrixIndexingCPInstruction.java @@ -48,7 +48,7 @@ public final class MatrixIndexingCPInstruction extends IndexingCPInstruction { @Override public void processInstruction(ExecutionContext ec) throws DMLRuntimeException - { + { String opcode = getOpcode(); IndexRange ixrange = getIndexRange(ec); @@ -64,17 +64,19 @@ public final class MatrixIndexingCPInstruction extends IndexingCPInstruction { resultBlock = mo.readMatrixPartition(ixrange.add(1)); else //via slicing the in-memory matrix { - //execute right indexing operation + //execute right indexing operation (with shallow row copies for range + //of entire sparse rows, which is safe due to copy on update) MatrixBlock matBlock = ec.getMatrixInput(input1.getName(), getExtendedOpcode()); - resultBlock = matBlock.sliceOperations(ixrange, new MatrixBlock()); + resultBlock = matBlock.sliceOperations((int)ixrange.rowStart, (int)ixrange.rowEnd, + (int)ixrange.colStart, (int)ixrange.colEnd, false, new MatrixBlock()); //unpin rhs input ec.releaseMatrixInput(input1.getName(), getExtendedOpcode()); //ensure correct sparse/dense output representation - //(memory guarded by release of input) - resultBlock.examSparsity(getExtendedOpcode()); - } + if( checkGuardedRepresentationChange(matBlock, resultBlock) ) + resultBlock.examSparsity(getExtendedOpcode()); + } //unpin output ec.setMatrixOutput(output.getName(), resultBlock, getExtendedOpcode()); @@ -119,6 +121,6 @@ public final class MatrixIndexingCPInstruction extends IndexingCPInstruction { ec.setMatrixOutput(output.getName(), resultBlock, updateType, getExtendedOpcode()); } else - throw new DMLRuntimeException("Invalid opcode (" + opcode +") encountered in MatrixIndexingCPInstruction."); + throw new DMLRuntimeException("Invalid opcode (" + opcode +") encountered in MatrixIndexingCPInstruction."); } } http://git-wip-us.apache.org/repos/asf/systemml/blob/8ca61ae2/src/main/java/org/apache/sysml/runtime/matrix/data/BinaryBlockToRowBlockConverter.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/matrix/data/BinaryBlockToRowBlockConverter.java b/src/main/java/org/apache/sysml/runtime/matrix/data/BinaryBlockToRowBlockConverter.java index 68bf038..cd133da 100644 --- a/src/main/java/org/apache/sysml/runtime/matrix/data/BinaryBlockToRowBlockConverter.java +++ b/src/main/java/org/apache/sysml/runtime/matrix/data/BinaryBlockToRowBlockConverter.java @@ -92,8 +92,7 @@ public class BinaryBlockToRowBlockConverter implements Converter<MatrixIndexes, //rowlow, rowup, collow, colup (1-based specification) _srcBlock.sliceOperations( _pos, _pos, 0, _srcBlock.getNumColumns()-1, _destBlock ); } - catch(DMLException ex) - { + catch(DMLException ex) { throw new RuntimeException("Failed to slice matrix block into row blocks.", ex); } http://git-wip-us.apache.org/repos/asf/systemml/blob/8ca61ae2/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java b/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java index e563c60..dac4315 100644 --- a/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java +++ b/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java @@ -3833,10 +3833,15 @@ public class MatrixBlock extends MatrixValue implements CacheBlock, Externalizab return ret; } - public final MatrixBlock sliceOperations(IndexRange ixrange, MatrixBlock ret) throws DMLRuntimeException { + public MatrixBlock sliceOperations(IndexRange ixrange, MatrixBlock ret) throws DMLRuntimeException { return sliceOperations( - (int)ixrange.rowStart, (int)ixrange.rowEnd, - (int)ixrange.colStart, (int)ixrange.colEnd, ret); + (int)ixrange.rowStart, (int)ixrange.rowEnd, + (int)ixrange.colStart, (int)ixrange.colEnd, true, ret); + } + + @Override + public MatrixBlock sliceOperations(int rl, int ru, int cl, int cu, CacheBlock ret) throws DMLRuntimeException { + return sliceOperations(rl, ru, cl, cu, true, ret); } /** @@ -3851,7 +3856,7 @@ public class MatrixBlock extends MatrixValue implements CacheBlock, Externalizab * @return matrix block * @throws DMLRuntimeException if DMLRuntimeException occurs */ - public MatrixBlock sliceOperations(int rl, int ru, int cl, int cu, CacheBlock ret) + public MatrixBlock sliceOperations(int rl, int ru, int cl, int cu, boolean deep, CacheBlock ret) throws DMLRuntimeException { // check the validity of bounds @@ -3880,7 +3885,7 @@ public class MatrixBlock extends MatrixValue implements CacheBlock, Externalizab { //core slicing operation (nnz maintained internally) if (sparse) - sliceSparse(rl, ru, cl, cu, result); + sliceSparse(rl, ru, cl, cu, deep, result); else sliceDense(rl, ru, cl, cu, result); } @@ -3888,7 +3893,7 @@ public class MatrixBlock extends MatrixValue implements CacheBlock, Externalizab return result; } - private void sliceSparse(int rl, int ru, int cl, int cu, MatrixBlock dest) + private void sliceSparse(int rl, int ru, int cl, int cu, boolean deep, MatrixBlock dest) throws DMLRuntimeException { //check for early abort @@ -3909,10 +3914,12 @@ public class MatrixBlock extends MatrixValue implements CacheBlock, Externalizab } } } - else if( rl==ru && cl==0 && cu==clen-1 ) //ROW VECTOR + else if( cl==0 && cu==clen-1 ) //ROW batch { //note: always sparse dest, but also works for dense - dest.appendRow(0, sparseBlock.get(rl)); + boolean ldeep = (deep && sparseBlock instanceof SparseBlockMCSR); + for(int i = rl; i <= ru; i++) + dest.appendRow(i-rl, sparseBlock.get(i), ldeep); } else //general case (sparse/dense dest) { @@ -3926,7 +3933,7 @@ public class MatrixBlock extends MatrixValue implements CacheBlock, Externalizab int astart = (cl>0)?sparseBlock.posFIndexGTE(i, cl) : apos; if( astart != -1 ) for( int j=astart; j<apos+alen && aix[j] <= cu; j++ ) - dest.appendValue(i-rl, aix[j]-cl, avals[j]); + dest.appendValue(i-rl, aix[j]-cl, avals[j]); } } }