You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@systemds.apache.org by ba...@apache.org on 2022/06/09 14:20:26 UTC
[systemds] branch main updated (628b4e61b4 -> 7aa2e29d79)
This is an automated email from the ASF dual-hosted git repository.
baunsgaard pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/systemds.git
from 628b4e61b4 Bump actions/setup-python from 3 to 4 (#1633)
new 5e1cbbf0bd [MINOR] Dense&SparseBlock internal toString improvement
new 7c042dc158 [SYSTEMDS-3387] Col & Row Product on Sparse Matrix
new 7aa2e29d79 [SYSTEMDS-3388] TSMM sparse dense rows multi threaded bug
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../org/apache/sysds/runtime/data/DenseBlock.java | 6 ++-
.../apache/sysds/runtime/data/SparseBlockCSR.java | 17 ++++----
.../apache/sysds/runtime/data/SparseBlockMCSR.java | 40 +++++++++++-------
.../org/apache/sysds/runtime/data/SparseRow.java | 27 +++++++++---
.../apache/sysds/runtime/data/SparseRowScalar.java | 5 +++
.../apache/sysds/runtime/data/SparseRowVector.java | 37 +++++++++++++++-
.../sysds/runtime/matrix/data/LibMatrixAgg.java | 49 +++++++++++-----------
.../sysds/runtime/matrix/data/LibMatrixMult.java | 48 +++++++++++----------
.../sysds/test/component/matrix/TSMMTest.java | 42 ++++++++++++++-----
9 files changed, 182 insertions(+), 89 deletions(-)
[systemds] 03/03: [SYSTEMDS-3388] TSMM sparse dense rows multi threaded bug
Posted by ba...@apache.org.
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
commit 7aa2e29d79de79f3962517d5087ded0b4748592e
Author: baunsgaard <ba...@tugraz.at>
AuthorDate: Wed Jun 8 23:35:42 2022 +0200
[SYSTEMDS-3388] TSMM sparse dense rows multi threaded bug
This commit address a bug in TSMM with sparse matrix input with
filled dense rows where if the TSMM is executed in parallel, the
dense rows would not be fully computed
The bug was introduced in a previous fix of the same issue that fixed
single threaded execution but did not verify multithreaded execution.
Closes #1629
Closes #1630
Closes #1631
---
.../sysds/runtime/matrix/data/LibMatrixMult.java | 48 +++++++++++-----------
.../sysds/test/component/matrix/TSMMTest.java | 42 ++++++++++++++-----
2 files changed, 57 insertions(+), 33 deletions(-)
diff --git a/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixMult.java b/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixMult.java
index 026b090c9b..99fb4b30ca 100644
--- a/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixMult.java
+++ b/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixMult.java
@@ -431,7 +431,15 @@ public class LibMatrixMult
//System.out.println("TSMM ("+m1.isInSparseFormat()+","+m1.getNumRows()+","+m1.getNumColumns()+","+m1.getNonZeros()+","+leftTranspose+") in "+time.stop());
}
- public static void matrixMultTransposeSelf( MatrixBlock m1, MatrixBlock ret, boolean leftTranspose, int k ) {
+ /**
+ * TSMM with optional transposed left side or not (Transposed self matrix multiplication)
+ *
+ * @param m1 The matrix to do tsmm
+ * @param ret The output matrix to allocate the result to
+ * @param leftTranspose If the left side should be considered transposed
+ * @param k the number of threads to use
+ */
+ public static void matrixMultTransposeSelf(MatrixBlock m1, MatrixBlock ret, boolean leftTranspose, int k) {
//check inputs / outputs
if( m1.isEmptyBlock(false) ) {
ret.examSparsity(); //turn empty dense into sparse
@@ -451,21 +459,22 @@ public class LibMatrixMult
ret.allocateDenseBlock();
//core multi-threaded matrix mult computation
+ ExecutorService pool = CommonThreadPool.get(k);
try {
- ExecutorService pool = CommonThreadPool.get(k);
ArrayList<MatrixMultTransposeTask> tasks = new ArrayList<>();
//load balance via #tasks=2k due to triangular shape
- int blklen = (int)(Math.ceil((double)ret.rlen/(2*k)));
- for( int i=0; i<2*k & i*blklen<ret.rlen; i++ )
- tasks.add(new MatrixMultTransposeTask(m1, ret, leftTranspose, i*blklen, Math.min((i+1)*blklen, ret.rlen)));
- List<Future<Object>> rtasks = pool.invokeAll(tasks);
- pool.shutdown();
- for( Future<Object> rtask : rtasks )
- rtask.get(); //error handling
+ int blklen = (int)(Math.ceil((double)ret.rlen / (2 * k)));
+ for(int i = 0; i < ret.rlen; i += blklen)
+ tasks.add(new MatrixMultTransposeTask(m1, ret, leftTranspose, i, Math.min(i+blklen, ret.rlen)));
+ for( Future<Object> rtask : pool.invokeAll(tasks) )
+ rtask.get();
}
catch(Exception ex) {
throw new DMLRuntimeException(ex);
}
+ finally{
+ pool.shutdown();
+ }
//post-processing
long nnz = copyUpperToLowerTriangle(ret);
@@ -2069,32 +2078,25 @@ public class LibMatrixMult
final int arlen = a.numRows();
for( int r=0; r<arlen; r++ ) {
if( a.isEmpty(r) ) continue;
- int alen = a.size(r);
- double[] avals = a.values(r);
+ final int alen = a.size(r);
+ final double[] avals = a.values(r);
+ final int apos = a.pos(r);
if( alen == n ) { //dense row
- final int apos = a.pos(r);
for (int i = rl; i < ru; i++){
double[] cvals = c.values(i);
int cix = c.pos(i);
double val = avals[i + apos];
- for(int j = i ; j < ru; j++){
- double d = val * avals[j + apos];
- cvals[cix + j] +=d;
- }
+ for(int j = i; j < m1.clen; j++)
+ cvals[cix + j] +=val * avals[j + apos];
}
}
else { //non-full sparse row
- int apos = a.pos(r);
int[] aix = a.indexes(r);
int rlix = (rl==0) ? 0 : a.posFIndexGTE(r, rl);
rlix = (rlix>=0) ? apos+rlix : apos+alen;
int len = apos + alen;
- for(int i = rlix; i < len && aix[i]<ru; i++) {
- double val = avals[i];
- if( val != 0 )
- vectMultiplyAdd(val, avals, c.values(aix[i]),
- aix, i, c.pos(aix[i]), len-i);
- }
+ for(int i = rlix; i < len && aix[i] < ru; i++)
+ vectMultiplyAdd(avals[i], avals, c.values(aix[i]), aix, i, c.pos(aix[i]), len - i);
}
}
}
diff --git a/src/test/java/org/apache/sysds/test/component/matrix/TSMMTest.java b/src/test/java/org/apache/sysds/test/component/matrix/TSMMTest.java
index d195ea952b..e99f4803dd 100644
--- a/src/test/java/org/apache/sysds/test/component/matrix/TSMMTest.java
+++ b/src/test/java/org/apache/sysds/test/component/matrix/TSMMTest.java
@@ -48,13 +48,12 @@ public class TSMMTest {
MatrixBlock mb;
final double[] spar = new double[] {0.3, 0.1, 0.01};
final int[] cols = new int[] {10, 6, 4, 3, 2, 1};
- final int[] threads = new int[] {1, 10};
+ final int[] threads = new int[] {1, 3, 10, 11, 16, 32, 44};
final int[] rows = new int[] {10};
for(int i = 0; i < 3; i++) { // seeds
for(int s = 0; s < spar.length; s++) {
for(int c = 0; c < cols.length; c++) {
for(int r = 0; r < rows.length; r++) {
-
mb = TestUtils.round(TestUtils.generateTestMatrixBlock(rows[r], cols[c], 1, 10, spar[s], i));
for(int t = 0; t < threads.length; t++)
tests.add(new Object[] {mb, threads[t]});
@@ -63,39 +62,62 @@ public class TSMMTest {
}
}
+ MatrixBlock mb1 = new MatrixBlock(100, 100, true); // dense cols sparse block
+ for(int j : new int[] {1, 4, 44, 87})
+ for(int i = 0; i < 100; i++)
+ mb1.quickSetValue(i, j, 100);
+ for(int t = 0; t < threads.length; t++)
+ tests.add(new Object[] {mb1, threads[t]});
+
+ MatrixBlock mb2 = new MatrixBlock(100, 100, true); // sparse but specific
+ for(int j : new int[] {44, 87})
+ for(int i : new int[] {56, 92})
+ mb2.quickSetValue(i, j, 100);
+ for(int t = 0; t < threads.length; t++)
+ tests.add(new Object[] {mb2, threads[t]});
+
+ MatrixBlock mb3 = new MatrixBlock(100, 100, true); // dense rows sparse block
+ for(int j : new int[] {1, 4, 44, 87})
+ for(int i = 0; i < 100; i++)
+ mb3.quickSetValue(j, i, 100);
+ for(int t = 0; t < threads.length; t++)
+ tests.add(new Object[] {mb3, threads[t]});
return tests;
}
@Test
public void testTSMMLeftSparseVSDense() {
final MMTSJType mType = MMTSJType.LEFT;
- final MatrixBlock expected = in.transposeSelfMatrixMultOperations(null, mType, k);
+ final MatrixBlock expected = in.transposeSelfMatrixMultOperations(null, mType, 1);
+
+ if(k > 1) // test multithread
+ testCompare(expected, in, "Compare single vs multithread");
+
final boolean isSparse = in.isInSparseFormat();
if(isSparse) {
MatrixBlock m2 = new MatrixBlock();
m2.copy(in);
m2.sparseToDense();
- testCompare(expected, m2);
+ testCompare(expected, m2, "Compare sparse vs dense");
}
else {
MatrixBlock m2 = new MatrixBlock();
m2.copy(in);
m2.denseToSparse(true);
- testCompare(expected, m2);
+ testCompare(expected, m2, "Compare dense vs CSR Sparse");
MatrixBlock m3 = new MatrixBlock();
m3.copy(in);
- m3.copy(in);
m3.denseToSparse(false);
- testCompare(expected, m3);
+ testCompare(expected, m3, "Compare dense vs MCSR Sparse");
}
}
- private void testCompare(MatrixBlock expected, MatrixBlock m2) {
+ private void testCompare(MatrixBlock expected, MatrixBlock m2, String message) {
final MMTSJType mType = MMTSJType.LEFT;
final MatrixBlock actual = m2.transposeSelfMatrixMultOperations(null, mType, k);
- final String inString = m2.toString();
- TestUtils.compareMatricesBitAvgDistance(expected, actual, 10L, 256L, inString);
+ // final String inString = m2.toString();
+ TestUtils.compareMatricesBitAvgDistance(expected, actual, 10L, 256L, message);
}
}
[systemds] 02/03: [SYSTEMDS-3387] Col & Row Product on Sparse Matrix
Posted by ba...@apache.org.
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
commit 7c042dc158448735b8e3e42e1818dc53f2021718
Author: baunsgaard <ba...@tugraz.at>
AuthorDate: Wed Jun 8 23:30:31 2022 +0200
[SYSTEMDS-3387] Col & Row Product on Sparse Matrix
This commit fixes bugs for Row and Col product for sparse matrices.
Since it is highly unlikely that we randomly construct sparse matrices
that have full rows or cols these bugs were never found.
A fully dense row or column is required to detect these bugs
since product produce 0 in any other case.
---
.../sysds/runtime/matrix/data/LibMatrixAgg.java | 49 +++++++++++-----------
1 file changed, 25 insertions(+), 24 deletions(-)
diff --git a/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixAgg.java b/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixAgg.java
index 8ae1ad2d29..2d48fbe9c6 100644
--- a/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixAgg.java
+++ b/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixAgg.java
@@ -3081,9 +3081,9 @@ public class LibMatrixAgg
/**
* PROD, opcode: ua*, sparse input.
*
- * @param a ?
- * @param c ?
- * @param n ?
+ * @param a Sparse block to process
+ * @param c Dense result block
+ * @param n Number of columns
* @param rl row lower index
* @param ru row upper index
*/
@@ -3107,9 +3107,9 @@ public class LibMatrixAgg
/**
* ROWPROD, opcode: uar*, sparse input.
*
- * @param a ?
- * @param c ?
- * @param n ?
+ * @param a Sparse block to process
+ * @param c Dense result block
+ * @param n Number of columns
* @param rl row lower index
* @param ru row upper index
*/
@@ -3117,9 +3117,14 @@ public class LibMatrixAgg
double[] lc = c.valuesAt(0);
for( int i=rl; i<ru; i++ ) {
if( !a.isEmpty(i) ) {
- int alen = a.size(i);
- double tmp = product(a.values(i), 0, alen);
- lc[i] = tmp * ((alen<n) ? 0 : 1);
+ final int alen = a.size(i);
+ if(alen < n)
+ lc[i] = 0;
+ else{
+ final int apos = a.pos(i);
+ double tmp = product(a.values(i), apos, alen);
+ lc[i] = tmp * ((alen<n) ? 0 : 1);
+ }
}
else
lc[i] = (n==0) ? 1 : 0;
@@ -3129,27 +3134,23 @@ public class LibMatrixAgg
/**
* COLPROD, opcode: uac*, sparse input.
*
- * @param a ?
- * @param c ?
- * @param n ?
+ * @param a Sparse block to process
+ * @param c Dense result block
+ * @param n Number of columns
* @param rl row lower index
* @param ru row upper index
*/
private static void s_uacm( SparseBlock a, DenseBlock c, int n, int rl, int ru ) {
double[] lc = c.set(1).valuesAt(0);
- int[] cnt = new int[ n ];
- for( int i=rl; i<ru; i++ ) {
- if( a.isEmpty(i) ){
-
- countAgg(a.values(i), cnt, a.indexes(i), a.pos(i), a.size(i));
- LibMatrixMult.vectMultiplyWrite(lc, a.values(i), lc, 0, a.pos(i), 0, a.size(i));
- }
- else if(n != 0)
- for(int j = 0; j < n; j++)
- lc[j] *= 0;
+ int[] cnt = new int[n];
+ for(int i = rl; i < ru; i++) {
+ if(a.isEmpty(i)) // if there is a empty row then stop processing since it is equivalient to multiplying with zero on all columns
+ continue;
+ countAgg(a.values(i), cnt, a.indexes(i), a.pos(i), a.size(i));
+ LibMatrixMult.vectMultiplyWrite(lc, a.values(i), lc, a.indexes(i), 0, a.pos(i), 0, a.size(i));
}
- for( int j=0; j<n; j++ )
- if( cnt[j] < ru-rl )
+ for(int j = 0; j < n; j++)
+ if(cnt[j] < ru - rl)
lc[j] *= 0;
}
[systemds] 01/03: [MINOR] Dense&SparseBlock internal toString improvement
Posted by ba...@apache.org.
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
commit 5e1cbbf0bdbf001819253efab3e7234c8a46d7e8
Author: baunsgaard <ba...@tugraz.at>
AuthorDate: Wed Jun 8 23:24:02 2022 +0200
[MINOR] Dense&SparseBlock internal toString improvement
This commit change the internal toString to make it more readable
when we internally in systemds change a matrix block into a string.
This makes it more easy for us to debug a given matrix when printing.
This commit also contain a minor fix to "compact(int r)" for sparse
blocks that did not handle the transition between SparseRowScalar to
SparseRowVector well. There are more of these instances inside MCSR that
are not addressed in this commit.
---
.../org/apache/sysds/runtime/data/DenseBlock.java | 6 +++-
.../apache/sysds/runtime/data/SparseBlockCSR.java | 17 +++++----
.../apache/sysds/runtime/data/SparseBlockMCSR.java | 40 ++++++++++++++--------
.../org/apache/sysds/runtime/data/SparseRow.java | 27 ++++++++++++---
.../apache/sysds/runtime/data/SparseRowScalar.java | 5 +++
.../apache/sysds/runtime/data/SparseRowVector.java | 37 ++++++++++++++++++--
6 files changed, 100 insertions(+), 32 deletions(-)
diff --git a/src/main/java/org/apache/sysds/runtime/data/DenseBlock.java b/src/main/java/org/apache/sysds/runtime/data/DenseBlock.java
index 49d135087c..a0e4f0842e 100644
--- a/src/main/java/org/apache/sysds/runtime/data/DenseBlock.java
+++ b/src/main/java/org/apache/sysds/runtime/data/DenseBlock.java
@@ -650,7 +650,11 @@ public abstract class DenseBlock implements Serializable
double[] data = values(i);
int ix = pos(i);
for(int j=0; j<_odims[0]; j++) {
- sb.append(data[ix+j]);
+ double v = data[ix+j];
+ if(v == (long) v)
+ sb.append((long)v);
+ else
+ sb.append(data[ix+j]);
sb.append("\t");
}
sb.append("\n");
diff --git a/src/main/java/org/apache/sysds/runtime/data/SparseBlockCSR.java b/src/main/java/org/apache/sysds/runtime/data/SparseBlockCSR.java
index 4093ed94c4..474c43694b 100644
--- a/src/main/java/org/apache/sysds/runtime/data/SparseBlockCSR.java
+++ b/src/main/java/org/apache/sysds/runtime/data/SparseBlockCSR.java
@@ -882,21 +882,20 @@ public class SparseBlockCSR extends SparseBlock
sb.append(", nnz=");
sb.append(size());
sb.append("\n");
+ final int rowDigits = (int)Math.max(Math.ceil(Math.log10(numRows())),1) ;
for(int i = 0; i < numRows(); i++) {
// append row
final int pos = pos(i);
final int len = size(i);
if(pos < pos + len) {
-
- sb.append("row +");
- sb.append(i);
- sb.append(": ");
-
+ sb.append(String.format("row %0"+rowDigits+"d -- ", i));
for(int j = pos; j < pos + len; j++) {
- sb.append(_indexes[j]);
- sb.append(": ");
- sb.append(_values[j]);
- sb.append("\t");
+ if(_values[j] == (long) _values[j])
+ sb.append(String.format("%"+rowDigits+"d:%d", _indexes[j], (long)_values[j]));
+ else
+ sb.append(String.format("%"+rowDigits+"d:%s", _indexes[j], Double.toString(_values[j])));
+ if(j + 1 < pos + len)
+ sb.append(", ");
}
sb.append("\n");
}
diff --git a/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSR.java b/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSR.java
index 9687dea49d..8774d3f763 100644
--- a/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSR.java
+++ b/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSR.java
@@ -148,11 +148,18 @@ public class SparseBlockMCSR extends SparseBlock
@Override
public void compact(int r) {
- if( isAllocated(r) && _rows[r] instanceof SparseRowVector
- && _rows[r].size() > SparseBlock.INIT_CAPACITY
- && _rows[r].size() * SparseBlock.RESIZE_FACTOR1
- < ((SparseRowVector)_rows[r]).capacity() ) {
- ((SparseRowVector)_rows[r]).compact();
+ if( isAllocated(r) ){
+ if(_rows[r] instanceof SparseRowVector
+ && _rows[r].size() > SparseBlock.INIT_CAPACITY
+ && _rows[r].size() * SparseBlock.RESIZE_FACTOR1
+ < ((SparseRowVector)_rows[r]).capacity() ) {
+ ((SparseRowVector)_rows[r]).compact();
+ }
+ else if(_rows[r] instanceof SparseRowScalar) {
+ SparseRowScalar s = (SparseRowScalar) _rows[r];
+ if(s.getValue() == 0)
+ _rows[r] = null;
+ }
}
}
@@ -173,7 +180,7 @@ public class SparseBlockMCSR extends SparseBlock
@Override
public boolean isAllocated(int r) {
- return (_rows[r] != null);
+ return _rows[r] != null;
}
@Override
@@ -319,8 +326,13 @@ public class SparseBlockMCSR extends SparseBlock
public boolean add(int r, int c, double v) {
if( !isAllocated(r) )
_rows[r] = new SparseRowScalar();
- else if( _rows[r] instanceof SparseRowScalar && !_rows[r].isEmpty())
- _rows[r] = new SparseRowVector(_rows[r]);
+ else if( _rows[r] instanceof SparseRowScalar && !_rows[r].isEmpty()){
+ SparseRowScalar s = (SparseRowScalar) _rows[r];
+ if(s.getIndex() == c)
+ return s.set(s.getIndex(), v + s.getValue());
+ else
+ _rows[r] = new SparseRowVector(_rows[r]);
+ }
return _rows[r].add(c, v);
}
@@ -414,19 +426,17 @@ public class SparseBlockMCSR extends SparseBlock
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
+ final int nRow = numRows();
sb.append("SparseBlockMCSR: rlen=");
- sb.append(numRows());
+ sb.append(nRow);
sb.append(", nnz=");
sb.append(size());
sb.append("\n");
- for( int i=0; i<numRows(); i++ ) {
+ final int rowDigits = (int)Math.max(Math.ceil(Math.log10(nRow)),1) ;
+ for( int i=0; i<nRow; i++ ) {
if(isEmpty(i))
continue;
- sb.append("row +");
- sb.append(i);
- sb.append(": ");
- sb.append(_rows[i]);
- sb.append("\n");
+ sb.append(String.format("row %0"+rowDigits+"d -- %s\n", i, _rows[i].toString()));
}
return sb.toString();
diff --git a/src/main/java/org/apache/sysds/runtime/data/SparseRow.java b/src/main/java/org/apache/sysds/runtime/data/SparseRow.java
index 8184c035c9..07b8c0903d 100644
--- a/src/main/java/org/apache/sysds/runtime/data/SparseRow.java
+++ b/src/main/java/org/apache/sysds/runtime/data/SparseRow.java
@@ -124,16 +124,33 @@ public abstract class SparseRow implements Serializable
* and shifts non-zero entries to the left if necessary.
*/
public abstract void compact();
+
+ /**
+ * In-place compaction of values over eps away from zero;
+ * and shifts non-zero entries to the left if necessary.
+ * @param eps epsilon value
+ */
+ public abstract void compact(double eps);
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- for(int i=0; i<size(); i++) {
- sb.append(indexes()[i]);
- sb.append(": ");
- sb.append(values()[i]);
- sb.append("\t");
+ final int s = size();
+ if(s == 0)
+ return "";
+ final int[] indexes = indexes();
+ final double[] values = values();
+
+ final int rowDigits = (int) Math.max(Math.ceil(Math.log10(indexes[s-1])),1);
+ for(int i=0; i<s; i++){
+ if(values[i] == (long) values[i])
+ sb.append(String.format("%"+rowDigits+"d:%d", indexes[i], (long)values[i]));
+ else
+ sb.append(String.format("%"+rowDigits+"d:%s", indexes[i], Double.toString(values[i])));
+ if(i + 1 < s)
+ sb.append(", ");
}
+
return sb.toString();
}
}
diff --git a/src/main/java/org/apache/sysds/runtime/data/SparseRowScalar.java b/src/main/java/org/apache/sysds/runtime/data/SparseRowScalar.java
index 5fe0889070..0b1ca982cd 100644
--- a/src/main/java/org/apache/sysds/runtime/data/SparseRowScalar.java
+++ b/src/main/java/org/apache/sysds/runtime/data/SparseRowScalar.java
@@ -103,6 +103,11 @@ public final class SparseRowScalar extends SparseRow{
index = (value!=0) ? index : -1;
}
+ @Override
+ public void compact(double eps) {
+ index = (Math.abs(value) < eps) ? -1: index;
+ }
+
public int getIndex(){
return index;
}
diff --git a/src/main/java/org/apache/sysds/runtime/data/SparseRowVector.java b/src/main/java/org/apache/sysds/runtime/data/SparseRowVector.java
index 6d67707896..7419f126d1 100644
--- a/src/main/java/org/apache/sysds/runtime/data/SparseRowVector.java
+++ b/src/main/java/org/apache/sysds/runtime/data/SparseRowVector.java
@@ -58,6 +58,27 @@ public final class SparseRowVector extends SparseRow{
}
size = nnz;
}
+
+ /**
+ * Sparse row vector constructor that take a dense array, and allocate sparsely by ignoring zero values
+ * @param v The dense row
+ */
+ public SparseRowVector(double[] v){
+ int nnz = 0;
+ for(double vv: v)
+ if(vv != 0)
+ nnz++;
+
+ values = new double[nnz];
+ indexes = new int[nnz];
+ for(int i=0, pos=0; i<v.length; i++)
+ if( v[i] != 0 ) {
+ values[pos] = v[i];
+ indexes[pos] = i;
+ pos++;
+ }
+ size = nnz;
+ }
public SparseRowVector(int estnnz, int maxnnz) {
if( estnnz > initialCapacity )
@@ -71,7 +92,7 @@ public final class SparseRowVector extends SparseRow{
public SparseRowVector(SparseRow that) {
size = that.size();
- int cap = Math.max(initialCapacity, that.size());
+ int cap = Math.max(initialCapacity, size);
//allocate arrays and copy new values
values = Arrays.copyOf(that.values(), cap);
@@ -427,7 +448,19 @@ public final class SparseRowVector extends SparseRow{
public void compact() {
int nnz = 0;
for( int i=0; i<size; i++ )
- if( values[i] != 0 ){
+ if( values[i] != 0.0 ){
+ values[nnz] = values[i];
+ indexes[nnz] = indexes[i];
+ nnz++;
+ }
+ size = nnz; //adjust row size
+ }
+
+ @Override
+ public void compact(double eps) {
+ int nnz = 0;
+ for( int i=0; i<size; i++ )
+ if( Math.abs(values[i]) > eps ){
values[nnz] = values[i];
indexes[nnz] = indexes[i];
nnz++;