Repository: systemml
Updated Branches:
  refs/heads/master bb53c6b46 -> 79db07968


[SYSTEMML-2241] Fine tuning ultra-sparse matrix mult selection

This patch further tunes the selection of ultra-sparse matrix mult block
operations by (1) using ultra-sparse operations (with sparse output) for
outer-product like operations that are known to result in sparse
outputs, and (2) avoid unnecessary sparse-dense conversion for
operations with colunm vector outputs. 


Project: http://git-wip-us.apache.org/repos/asf/systemml/repo
Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/79db0796
Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/79db0796
Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/79db0796

Branch: refs/heads/master
Commit: 79db07968d3f5425e6ff27c024e0260f13077b52
Parents: bb53c6b
Author: Matthias Boehm <mboe...@gmail.com>
Authored: Sat Apr 14 15:25:00 2018 -0700
Committer: Matthias Boehm <mboe...@gmail.com>
Committed: Sat Apr 14 16:27:45 2018 -0700

----------------------------------------------------------------------
 .../instructions/spark/MapmmSPInstruction.java  | 36 ++++++--------------
 .../runtime/matrix/data/LibMatrixMult.java      | 14 ++++++--
 .../sysml/runtime/matrix/data/MatrixBlock.java  |  4 ++-
 .../matrix/data/OperationsOnMatrixValues.java   |  6 ++--
 4 files changed, 27 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/systemml/blob/79db0796/src/main/java/org/apache/sysml/runtime/instructions/spark/MapmmSPInstruction.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/instructions/spark/MapmmSPInstruction.java
 
b/src/main/java/org/apache/sysml/runtime/instructions/spark/MapmmSPInstruction.java
index d54ccf8..21c1be3 100644
--- 
a/src/main/java/org/apache/sysml/runtime/instructions/spark/MapmmSPInstruction.java
+++ 
b/src/main/java/org/apache/sysml/runtime/instructions/spark/MapmmSPInstruction.java
@@ -431,43 +431,27 @@ public class MapmmSPInstruction extends 
BinarySPInstruction {
                        throws Exception 
                {
                        ArrayList<Tuple2<MatrixIndexes, MatrixBlock>> ret = new 
ArrayList<>();
-                       
                        MatrixIndexes ixIn = arg0._1();
                        MatrixBlock blkIn = arg0._2();
 
-                       if( _type == CacheType.LEFT )
-                       {
+                       if( _type == CacheType.LEFT ) {
                                //for all matching left-hand-side blocks
                                int len = _pbc.getNumRowBlocks();
-                               for( int i=1; i<=len; i++ ) 
-                               {
+                               for( int i=1; i<=len; i++ ) {
                                        MatrixBlock left = _pbc.getBlock(i, 
(int)ixIn.getRowIndex());
-                                       MatrixIndexes ixOut = new 
MatrixIndexes();
-                                       MatrixBlock blkOut = new MatrixBlock();
-                                       
-                                       //execute matrix-vector mult
-                                       
OperationsOnMatrixValues.performAggregateBinary( 
-                                                       new 
MatrixIndexes(i,ixIn.getRowIndex()), left, ixIn, blkIn, ixOut, blkOut, _op);
-                                       
-                                       ret.add(new Tuple2<>(ixOut, blkOut));
+                                       MatrixBlock blkOut = 
OperationsOnMatrixValues
+                                               
.performAggregateBinaryIgnoreIndexes(left, blkIn, new MatrixBlock(), _op);
+                                       ret.add(new Tuple2<>(new 
MatrixIndexes(i, ixIn.getColumnIndex()), blkOut));
                                }
                        }
-                       else //if( _type == CacheType.RIGHT )
-                       {
+                       else { //RIGHT
                                //for all matching right-hand-side blocks
                                int len = _pbc.getNumColumnBlocks();
-                               for( int j=1; j<=len; j++ ) 
-                               {
-                                       //get the right hand side matrix
+                               for( int j=1; j<=len; j++ )  {
                                        MatrixBlock right = 
_pbc.getBlock((int)ixIn.getColumnIndex(), j);
-                                       MatrixIndexes ixOut = new 
MatrixIndexes();
-                                       MatrixBlock blkOut = new MatrixBlock();
-                                       
-                                       //execute matrix-vector mult
-                                       
OperationsOnMatrixValues.performAggregateBinary(
-                                                       ixIn, blkIn, new 
MatrixIndexes(ixIn.getColumnIndex(),j), right, ixOut, blkOut, _op);
-                               
-                                       ret.add(new Tuple2<>(ixOut, blkOut));
+                                       MatrixBlock blkOut = 
OperationsOnMatrixValues
+                                               
.performAggregateBinaryIgnoreIndexes(blkIn, right, new MatrixBlock(), _op);
+                                       ret.add(new Tuple2<>(new 
MatrixIndexes(ixIn.getRowIndex(), j), blkOut));
                                }
                        }
                        

http://git-wip-us.apache.org/repos/asf/systemml/blob/79db0796/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java 
b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
index b36e306..91adc93 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
@@ -1490,7 +1490,8 @@ public class LibMatrixMult
         */
        private static void matrixMultUltraSparse(MatrixBlock m1, MatrixBlock 
m2, MatrixBlock ret, int rl, int ru) {
                final boolean leftUS = m1.isUltraSparse()
-                       || (m1.isUltraSparse(false) && !m2.isUltraSparse());
+                       || (m1.isUltraSparse(false) && !m2.isUltraSparse())
+                       || (m1.sparse && !m2.sparse);
                final int m  = m1.rlen;
                final int cd = m1.clen;
                final int n  = m2.clen;
@@ -3693,14 +3694,21 @@ public class LibMatrixMult
        }
        
        public static boolean isUltraSparseMatrixMult(MatrixBlock m1, 
MatrixBlock m2) {
+               if( m2.clen == 1 ) //mv always dense
+                       return false;
                //note: ultra-sparse matrix mult implies also sparse outputs, 
hence we need
                //to be conservative an cannot use this for all ultra-sparse 
matrices.
+               double outSp = OptimizerUtils.getMatMultSparsity(
+                       m1.getSparsity(), m2.getSparsity(), m1.rlen, m1.clen, 
m2.clen, true);
                return (m1.isUltraSparse() || m2.isUltraSparse()) //base case
                        || (m1.isUltraSparsePermutationMatrix() 
                                && OptimizerUtils.getSparsity(m2.rlen, m2.clen, 
m2.nonZeros)<1.0)
                        || ((m1.isUltraSparse(false) || 
m2.isUltraSparse(false)) 
-                               && 
OptimizerUtils.getMatMultSparsity(m1.getSparsity(), m2.getSparsity(),
-                               m1.rlen, m1.clen, m2.clen, true) < 
MatrixBlock.ULTRA_SPARSITY_TURN_POINT2);
+                               && outSp < 
MatrixBlock.ULTRA_SPARSITY_TURN_POINT2)
+                       || (m1.getSparsity() < 
MatrixBlock.ULTRA_SPARSITY_TURN_POINT2
+                               && m1.getNonZeros() < 
MatrixBlock.ULTRA_SPARSE_BLOCK_NNZ
+                               && m1.getLength()+m2.getLength() < 
(long)m1.rlen*m2.clen
+                               && outSp < MatrixBlock.SPARSITY_TURN_POINT);
        }
 
        private static MatrixBlock prepMatrixMultRightInput( MatrixBlock m1, 
MatrixBlock m2 ) {

http://git-wip-us.apache.org/repos/asf/systemml/blob/79db0796/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 ce9ea3c..3b6d682 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
@@ -101,6 +101,7 @@ public class MatrixBlock extends MatrixValue implements 
CacheBlock, Externalizab
        //sparsity threshold for ultra-sparse matrix operations (40nnz in a 
1kx1k block)
        public static final double ULTRA_SPARSITY_TURN_POINT  = 0.00004;
        public static final double ULTRA_SPARSITY_TURN_POINT2 = 0.0004;
+       public static final int ULTRA_SPARSE_BLOCK_NNZ = 40;
        //default sparse block type: modified compressed sparse rows, for 
efficient incremental construction
        public static final SparseBlock.Type DEFAULT_SPARSEBLOCK = 
SparseBlock.Type.MCSR;
        //default sparse block type for update in place: compressed sparse 
rows, to prevent serialization
@@ -874,7 +875,8 @@ public class MatrixBlock extends MatrixValue implements 
CacheBlock, Externalizab
        public boolean isUltraSparse(boolean checkNnz) {
                double sp = ((double)nonZeros/rlen)/clen;
                //check for sparse representation in order to account for 
vectors in dense
-               return sparse && sp<ULTRA_SPARSITY_TURN_POINT && (!checkNnz || 
nonZeros<40);
+               return sparse && sp<ULTRA_SPARSITY_TURN_POINT 
+                       && (!checkNnz || nonZeros<ULTRA_SPARSE_BLOCK_NNZ);
        }
        
        public boolean isUltraSparsePermutationMatrix() {

http://git-wip-us.apache.org/repos/asf/systemml/blob/79db0796/src/main/java/org/apache/sysml/runtime/matrix/data/OperationsOnMatrixValues.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/matrix/data/OperationsOnMatrixValues.java
 
b/src/main/java/org/apache/sysml/runtime/matrix/data/OperationsOnMatrixValues.java
index 3715404..a698e46 100644
--- 
a/src/main/java/org/apache/sysml/runtime/matrix/data/OperationsOnMatrixValues.java
+++ 
b/src/main/java/org/apache/sysml/runtime/matrix/data/OperationsOnMatrixValues.java
@@ -217,15 +217,15 @@ public class OperationsOnMatrixValues
                valueIn.aggregateUnaryOperations(op, valueOut, brlen, bclen, 
indexesIn);
        }
        
-       public static void performAggregateBinary(MatrixIndexes indexes1, 
MatrixBlock value1, MatrixIndexes indexes2, MatrixBlock value2, 
+       public static MatrixBlock performAggregateBinary(MatrixIndexes 
indexes1, MatrixBlock value1, MatrixIndexes indexes2, MatrixBlock value2, 
                        MatrixIndexes indexesOut, MatrixBlock valueOut, 
AggregateBinaryOperator op) {
                //compute output index
                indexesOut.setIndexes(indexes1.getRowIndex(), 
indexes2.getColumnIndex());
                //perform on the value
                if( value2 instanceof CompressedMatrixBlock )
-                       value2.aggregateBinaryOperations(value1, value2, 
valueOut, op);
+                       return value2.aggregateBinaryOperations(value1, value2, 
valueOut, op);
                else //default
-                       value1.aggregateBinaryOperations(indexes1, value1, 
indexes2, value2, valueOut, op);
+                       return value1.aggregateBinaryOperations(indexes1, 
value1, indexes2, value2, valueOut, op);
        }
 
        public static MatrixBlock 
performAggregateBinaryIgnoreIndexes(MatrixBlock value1, MatrixBlock value2,

Reply via email to