Repository: systemml
Updated Branches:
  refs/heads/master cc90a0e59 -> 9067654e7


[SYSTEMML-2058] Fix sparse-unsafe, sparse-dense unary block operations

This patch fixes a special case of sparse-unsafe unary operations for
sparse inputs and dense outputs. These operations reset the output to
the constant value op(0) and subsequently redirect to sparseSafe
operations which in turn use append to add computed values. However,
this append rejects computed 0s (as is the case for NOT), leading to
incorrect results. We now directly update the dense target and also
ensure that the reset uses the double instead of long function because
the latter might not be implemented for all function objects.


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

Branch: refs/heads/master
Commit: ebdf770c872429a03ca125f2d69b25db59d0fa8c
Parents: cc90a0e
Author: Matthias Boehm <[email protected]>
Authored: Thu Jan 4 17:53:53 2018 -0800
Committer: Matthias Boehm <[email protected]>
Committed: Thu Jan 4 17:53:53 2018 -0800

----------------------------------------------------------------------
 .../sysml/runtime/matrix/data/MatrixBlock.java  | 25 ++++++++++++--------
 1 file changed, 15 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/systemml/blob/ebdf770c/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 2336588..ff70cfd 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
@@ -2599,9 +2599,8 @@ public class MatrixBlock extends MatrixValue implements 
CacheBlock, Externalizab
                MatrixBlock ret = checkType(result);
                
                // estimate the sparsity structure of result matrix
-               boolean sp = this.sparse; // by default, we guess 
result.sparsity=input.sparsity
-               if (!op.sparseSafe)
-                       sp = false; // if the operation is not sparse safe, 
then result will be in dense format
+               // by default, we guess result.sparsity=input.sparsity, unless 
not sparse safe
+               boolean sp = this.sparse && op.sparseSafe;
                
                //allocate output
                if( ret == null )
@@ -2643,6 +2642,7 @@ public class MatrixBlock extends MatrixValue implements 
CacheBlock, Externalizab
                        return;
                
                final int m = rlen;
+               final int n = clen;
                
                if( sparse && ret.sparse ) //SPARSE <- SPARSE
                {
@@ -2671,21 +2671,24 @@ public class MatrixBlock extends MatrixValue implements 
CacheBlock, Externalizab
                else if( sparse ) //DENSE <- SPARSE
                {
                        SparseBlock a = sparseBlock;
-                       
+                       DenseBlock c = ret.denseBlock;
+                       long nnz = (ret.nonZeros > 0) ?
+                               (long) m*n-a.size() : 0;
                        for(int i=0; i<m; i++) {
                                if( a.isEmpty(i) ) continue;
-                       
                                int apos = a.pos(i);
                                int alen = a.size(i);
                                int[] aix = a.indexes(i);
                                double[] avals = a.values(i);
-                               
+                               double[] cvals = c.values(i);
+                               int cix = c.pos(i);
                                for( int j=apos; j<apos+alen; j++ ) {
                                        double val = op.fn.execute(avals[j]);
-                                       ret.appendValue(i, aix[j], val);
+                                       cvals[cix + aix[j]] = val; 
+                                       nnz += (val != 0) ? 1 : 0;
                                }
                        }
-                       //nnz maintained on appendValue
+                       ret.nonZeros = nnz;
                }
                else //DENSE <- DENSE
                {
@@ -2713,7 +2716,7 @@ public class MatrixBlock extends MatrixValue implements 
CacheBlock, Externalizab
                throws DMLRuntimeException
        {
                //prepare 0-value init (determine if unnecessarily 
sparse-unsafe)
-               double val0 = op.fn.execute(0);
+               double val0 = op.fn.execute(0d);
                
                final int m = rlen;
                final int n = clen;
@@ -2727,8 +2730,10 @@ public class MatrixBlock extends MatrixValue implements 
CacheBlock, Externalizab
                }
                
                //redirection to sparse safe operation w/ init by val0
-               if( sparse && val0 != 0 )
+               if( sparse && val0 != 0 ) {
                        ret.reset(m, n, val0);
+                       ret.nonZeros = (long)m * n;
+               }
                sparseUnaryOperations(op, ret);
        }
 

Reply via email to