You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@systemml.apache.org by mb...@apache.org on 2018/06/22 00:40:09 UTC
systemml git commit: [MINOR] Performance binary in-place operations,
especially plus
Repository: systemml
Updated Branches:
refs/heads/master 08f9e3e47 -> 36c217d38
[MINOR] Performance binary in-place operations, especially plus
This patch makes a minor performance improvement to binary in-place
operations for dense-dense and dense-sparse ops, especially plus. On a
scenario of paramserv ASP, 10 epochs 80 workers, this patch improved the
end-to-end runtime from 212s to 202.
Project: http://git-wip-us.apache.org/repos/asf/systemml/repo
Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/36c217d3
Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/36c217d3
Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/36c217d3
Branch: refs/heads/master
Commit: 36c217d38efe8ce031b568a799a9b796a64a1968
Parents: 08f9e3e
Author: Matthias Boehm <mb...@gmail.com>
Authored: Thu Jun 21 17:40:36 2018 -0700
Committer: Matthias Boehm <mb...@gmail.com>
Committed: Thu Jun 21 17:40:36 2018 -0700
----------------------------------------------------------------------
.../runtime/matrix/data/LibMatrixBincell.java | 70 ++++++++++++--------
1 file changed, 42 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/systemml/blob/36c217d3/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixBincell.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixBincell.java b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixBincell.java
index 8310e72..48fce40 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixBincell.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixBincell.java
@@ -1082,10 +1082,12 @@ public class LibMatrixBincell
private static void safeBinaryInPlace(MatrixBlock m1ret, MatrixBlock m2, BinaryOperator op) {
//early abort on skip and empty
- if( m1ret.isEmptyBlock(false) && m2.isEmptyBlock(false) )
+ if( (m1ret.isEmpty() && m2.isEmpty() )
+ || (op.fn instanceof Plus && m2.isEmpty())
+ || (op.fn instanceof Minus && m2.isEmpty()))
return; // skip entire empty block
//special case: start aggregation
- else if( op.fn instanceof Plus && m1ret.isEmptyBlock(false) ){
+ else if( op.fn instanceof Plus && m1ret.isEmpty() ){
m1ret.copy(m2);
return;
}
@@ -1094,6 +1096,8 @@ public class LibMatrixBincell
safeBinaryInPlaceSparse(m1ret, m2, op);
else if(!m1ret.sparse && !m2.sparse)
safeBinaryInPlaceDense(m1ret, m2, op);
+ else if(m2.sparse && (op.fn instanceof Plus || op.fn instanceof Minus))
+ safeBinaryInPlaceDenseSparseAdd(m1ret, m2, op);
else //GENERIC
safeBinaryInPlaceGeneric(m1ret, m2, op);
}
@@ -1191,6 +1195,14 @@ public class LibMatrixBincell
}
}
}
+ else if( op.fn instanceof Plus ) {
+ for(int r=0; r<rlen; r++) {
+ int aix = a.pos(r), bix = b.pos(r);
+ double[] avals = a.values(r), bvals = b.values(r);
+ LibMatrixMult.vectAdd(bvals, avals, bix, aix, clen);
+ lnnz += UtilFunctions.computeNnz(avals, aix, clen);
+ }
+ }
else {
for(int r=0; r<rlen; r++) {
double[] avals = a.values(r), bvals = b.values(r);
@@ -1204,36 +1216,38 @@ public class LibMatrixBincell
m1ret.setNonZeros(lnnz);
}
+ private static void safeBinaryInPlaceDenseSparseAdd(MatrixBlock m1ret, MatrixBlock m2, BinaryOperator op) {
+ final int rlen = m1ret.rlen;
+ DenseBlock a = m1ret.denseBlock;
+ SparseBlock b = m2.sparseBlock;
+ long nnz = m1ret.getNonZeros();
+ for(int r=0; r<rlen; r++) {
+ if( b.isEmpty(r) ) continue;
+ int apos = a.pos(r), bpos = b.pos(r);
+ int blen = b.size(r);
+ int[] bix = b.indexes(r);
+ double[] avals = a.values(r), bvals = b.values(r);
+ for(int k = bpos; k<bpos+blen; k++) {
+ double vold = avals[apos+bix[k]];
+ double vnew = op.fn.execute(vold, bvals[k]);
+ nnz += (vold == 0 && vnew != 0) ? 1 :
+ (vold != 0 && vnew ==0) ? -1 : 0;
+ avals[apos+bix[k]] = vnew;
+ }
+ }
+ m1ret.setNonZeros(nnz);
+ }
+
private static void safeBinaryInPlaceGeneric(MatrixBlock m1ret, MatrixBlock m2, BinaryOperator op) {
final int rlen = m1ret.rlen;
final int clen = m1ret.clen;
-
- if( m2.sparse && (op.fn instanceof Plus || op.fn instanceof Minus) ) {
- if( m2.isEmptyBlock(false) )
- return;
- SparseBlock b = m2.sparseBlock;
- for(int r=0; r<rlen; r++) {
- if( b.isEmpty(r) ) continue;
- int bpos = b.pos(r);
- int blen = b.size(r);
- int[] bix = b.indexes(r);
- double[] bvals = b.values(r);
- for(int k = bpos; k<bpos+blen; k++) {
- double vold = m1ret.quickGetValue(r, bix[k]);
- double vnew = op.fn.execute(vold, bvals[k]);
- m1ret.quickSetValue(r, bix[k], vnew);
- }
+ for(int r=0; r<rlen; r++)
+ for(int c=0; c<clen; c++) {
+ double thisvalue = m1ret.quickGetValue(r, c);
+ double thatvalue = m2.quickGetValue(r, c);
+ double resultvalue = op.fn.execute(thisvalue, thatvalue);
+ m1ret.quickSetValue(r, c, resultvalue);
}
- }
- else {
- for(int r=0; r<rlen; r++)
- for(int c=0; c<clen; c++) {
- double thisvalue = m1ret.quickGetValue(r, c);
- double thatvalue = m2.quickGetValue(r, c);
- double resultvalue = op.fn.execute(thisvalue, thatvalue);
- m1ret.quickSetValue(r, c, resultvalue);
- }
- }
}
private static void unsafeBinaryInPlace(MatrixBlock m1ret, MatrixBlock m2, BinaryOperator op)