This is an automated email from the ASF dual-hosted git repository.

baunsgaard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/systemds.git


The following commit(s) were added to refs/heads/main by this push:
     new b420bdf68c [MINOR] Matrix equals empty support
b420bdf68c is described below

commit b420bdf68caa5e7d109b4ac9901ac912fe9adade
Author: Sebastian Baunsgaard <[email protected]>
AuthorDate: Sun Jan 7 16:38:25 2024 +0100

    [MINOR] Matrix equals empty support
    
    This commit makes minor improvements to the matrix equals operation.
    If someone reads this is it possible to compare MatrixBlock via
    a.equals(b) where a and b are MatrixBlocks internally.
    The update fixes an edge case of empty MatrixBlock with unknown non zero
    count.
    
    Closes #1978
---
 .../sysds/runtime/matrix/data/LibMatrixEquals.java | 41 ++++++++--------------
 .../sysds/runtime/matrix/data/MatrixBlock.java     | 20 ++++++-----
 2 files changed, 27 insertions(+), 34 deletions(-)

diff --git 
a/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixEquals.java 
b/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixEquals.java
index 63536d4c04..39e5a43980 100644
--- a/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixEquals.java
+++ b/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixEquals.java
@@ -25,7 +25,7 @@ import org.apache.commons.logging.LogFactory;
 /**
  * 
  * <p>
- * Equals library for MatrixBLocks:
+ * Equals library for MatrixBlocks:
  * </p>
  * 
  * <p>
@@ -39,6 +39,10 @@ import org.apache.commons.logging.LogFactory;
  * <li>Consistent</li>
  * </ul>
  * 
+ * <p>
+ * The equals also is valid if the metadata of number of non zeros are unknown 
in either input. An unknown number of non
+ * zero values is indicated by a negative nonzero count in the input matrices.
+ * </p>
  */
 public class LibMatrixEquals {
 
@@ -49,7 +53,7 @@ public class LibMatrixEquals {
        private final MatrixBlock a;
        /** second block */
        private final MatrixBlock b;
-       /** Epsilon */
+       /** Epsilon allowed between the blocks */
        private final double eps;
 
        /**
@@ -140,19 +144,20 @@ public class LibMatrixEquals {
         * @return if the blocks are equivalent
         */
        private boolean exec() {
+
                if(isMetadataDifferent())
                        return false;
-               Boolean empty = isEmpty();
-               if(empty != null)
-                       return empty;
-
-               if(a.denseBlock != null && b.denseBlock != null)
+               else if(a.isEmpty() && b.nonZeros != -1)
+                       return b.isEmpty();
+               else if(b.isEmpty() && a.nonZeros != -1)
+                       return false;
+               else if(a.denseBlock != null && b.denseBlock != null)
                        return a.denseBlock.equals(b.denseBlock, eps);
-               if(a.sparseBlock != null && b.sparseBlock != null)
+               else if(a.sparseBlock != null && b.sparseBlock != null)
                        return a.sparseBlock.equals(b.sparseBlock, eps);
-               if(a.sparseBlock != null && b.denseBlock != null && 
b.denseBlock.isContiguous())
+               else if(a.sparseBlock != null && b.denseBlock != null && 
b.denseBlock.isContiguous())
                        return a.sparseBlock.equals(b.denseBlock.values(0), 
b.getNumColumns(), eps);
-               if(b.sparseBlock != null && a.denseBlock != null && 
a.denseBlock.isContiguous())
+               else if(b.sparseBlock != null && a.denseBlock != null && 
a.denseBlock.isContiguous())
                        return b.sparseBlock.equals(a.denseBlock.values(0), 
a.getNumColumns(), eps);
 
                return genericEquals();
@@ -177,22 +182,6 @@ public class LibMatrixEquals {
                return diff;
        }
 
-       /**
-        * Empty metadata check. to verify if the content is empty and such.
-        * 
-        * @return Boolean that is not null if something was found otherwise 
null.
-        */
-       private Boolean isEmpty() {
-               final boolean emptyA = a.isEmpty();
-               final boolean emptyB = b.isEmpty();
-               // empty cases!
-               if(emptyA != emptyB)
-                       return false;
-               else if(emptyA)
-                       return true;
-               return null;
-       }
-
        /**
         * Generic implementation to cover all cases. But it is slow in most.
         * 
diff --git 
a/src/main/java/org/apache/sysds/runtime/matrix/data/MatrixBlock.java 
b/src/main/java/org/apache/sysds/runtime/matrix/data/MatrixBlock.java
index 2995b15efb..276f1aacee 100644
--- a/src/main/java/org/apache/sysds/runtime/matrix/data/MatrixBlock.java
+++ b/src/main/java/org/apache/sysds/runtime/matrix/data/MatrixBlock.java
@@ -587,15 +587,19 @@ public class MatrixBlock extends MatrixValue implements 
CacheBlock<MatrixBlock>,
                return isEmptyBlock(true);
        }
        
-       public boolean isEmptyBlock(boolean safe)
-       {
-               boolean ret = ( sparse && sparseBlock==null ) || ( !sparse && 
denseBlock==null );
-               if( nonZeros==0 )
-               {
-                       //prevent under-estimation
-                       if(safe)
+       /**
+        * Get if this MatrixBlock is an empty block. The call can potentially 
tricker a recomputation of non zeros if the
+        * non-zero count is unknown.
+        * 
+        * @param safe True if we want to ensure the count non zeros if the nnz 
is unknown.
+        * @return If the block is empty.
+        */
+       public boolean isEmptyBlock(boolean safe) {
+               boolean ret = (sparse && sparseBlock == null) || (!sparse && 
denseBlock == null);
+               if(nonZeros <= 0) { // estimate non zeros if unknown or 0.
+                       if(safe) // only allow the recompute if safe flag is 
false.
                                recomputeNonZeros();
-                       ret = (nonZeros==0);
+                       ret = (nonZeros == 0);
                }
                return ret;
        }

Reply via email to