[SYSTEMML-382] Initial runtime integration sparse matrix blocks This changes integrates the new sparse block abstraction into our matrix block data structure and modifies all operations of all backends accordingly. For the sake of a seamless integration without major performance regressions, some operations still rely on SparseRows as temporary container for obtaining and inserting entire rows. Also, all created matrix blocks still use the old MCSR representation.
As a next step, we need to tune important operations according to the new sparse block abstraction. Project: http://git-wip-us.apache.org/repos/asf/incubator-systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-systemml/commit/8ba0fdcc Tree: http://git-wip-us.apache.org/repos/asf/incubator-systemml/tree/8ba0fdcc Diff: http://git-wip-us.apache.org/repos/asf/incubator-systemml/diff/8ba0fdcc Branch: refs/heads/master Commit: 8ba0fdccad91cd91ca8fdeef0f51d0c071b6fb7d Parents: 2af90e0 Author: Matthias Boehm <[email protected]> Authored: Wed Jan 20 14:55:50 2016 -0800 Committer: Matthias Boehm <[email protected]> Committed: Wed Jan 20 14:58:34 2016 -0800 ---------------------------------------------------------------------- .../controlprogram/caching/CacheDataInput.java | 10 +- .../controlprogram/caching/CacheDataOutput.java | 19 +- .../spark/utils/RDDConverterUtils.java | 10 +- .../apache/sysml/runtime/io/WriterTextCSV.java | 19 +- .../sysml/runtime/io/WriterTextCSVParallel.java | 19 +- .../sysml/runtime/matrix/data/LibMatrixAgg.java | 555 +++++------- .../runtime/matrix/data/LibMatrixBincell.java | 265 +++--- .../runtime/matrix/data/LibMatrixDatagen.java | 14 +- .../runtime/matrix/data/LibMatrixMult.java | 565 ++++++------ .../runtime/matrix/data/LibMatrixOuterAgg.java | 60 +- .../runtime/matrix/data/LibMatrixReorg.java | 291 +++--- .../sysml/runtime/matrix/data/MatrixBlock.java | 897 +++++++++---------- .../matrix/data/MatrixBlockDataInput.java | 2 +- .../matrix/data/MatrixBlockDataOutput.java | 2 +- .../runtime/matrix/data/SparseRowsIterator.java | 110 --- .../util/FastBufferedDataInputStream.java | 12 +- .../util/FastBufferedDataOutputStream.java | 20 +- .../functions/sparse/SparseBlockDelete.java | 9 +- .../sparse/SparseBlockGetFirstIndex.java | 9 +- .../functions/sparse/SparseBlockGetSet.java | 9 +- .../functions/sparse/SparseBlockIndexRange.java | 9 +- .../functions/sparse/SparseBlockIterator.java | 9 +- .../functions/sparse/SparseBlockScan.java | 9 +- .../functions/sparse/SparseBlockSize.java | 9 +- 24 files changed, 1339 insertions(+), 1594 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8ba0fdcc/src/main/java/org/apache/sysml/runtime/controlprogram/caching/CacheDataInput.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/controlprogram/caching/CacheDataInput.java b/src/main/java/org/apache/sysml/runtime/controlprogram/caching/CacheDataInput.java index 712ad8a..bc81361 100644 --- a/src/main/java/org/apache/sysml/runtime/controlprogram/caching/CacheDataInput.java +++ b/src/main/java/org/apache/sysml/runtime/controlprogram/caching/CacheDataInput.java @@ -23,7 +23,7 @@ import java.io.DataInput; import java.io.IOException; import org.apache.sysml.runtime.matrix.data.MatrixBlockDataInput; -import org.apache.sysml.runtime.matrix.data.SparseRow; +import org.apache.sysml.runtime.matrix.data.SparseBlock; public class CacheDataInput implements DataInput, MatrixBlockDataInput { @@ -163,7 +163,7 @@ public class CacheDataInput implements DataInput, MatrixBlockDataInput } @Override - public long readSparseRows(int rlen, SparseRow[] rows) + public long readSparseRows(int rlen, SparseBlock rows) throws IOException { //counter for non-zero elements @@ -177,9 +177,7 @@ public class CacheDataInput implements DataInput, MatrixBlockDataInput if( lnnz > 0 ) //non-zero row { //get handle to sparse (allocate if necessary) - if( rows[i] == null ) - rows[i] = new SparseRow(lnnz); - SparseRow arow = rows[i]; + rows.allocate(i, lnnz); //read single sparse row for( int j=0; j<lnnz; j++ ) @@ -187,7 +185,7 @@ public class CacheDataInput implements DataInput, MatrixBlockDataInput int aix = baToInt(_buff, _count); long tmp = baToLong(_buff, _count+4); double aval = Double.longBitsToDouble( tmp ); - arow.append(aix, aval); + rows.append(i, aix, aval); _count+=12; } http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8ba0fdcc/src/main/java/org/apache/sysml/runtime/controlprogram/caching/CacheDataOutput.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/controlprogram/caching/CacheDataOutput.java b/src/main/java/org/apache/sysml/runtime/controlprogram/caching/CacheDataOutput.java index 66ad552..5fd0b4b 100644 --- a/src/main/java/org/apache/sysml/runtime/controlprogram/caching/CacheDataOutput.java +++ b/src/main/java/org/apache/sysml/runtime/controlprogram/caching/CacheDataOutput.java @@ -22,9 +22,8 @@ package org.apache.sysml.runtime.controlprogram.caching; import java.io.DataOutput; import java.io.IOException; - import org.apache.sysml.runtime.matrix.data.MatrixBlockDataOutput; -import org.apache.sysml.runtime.matrix.data.SparseRow; +import org.apache.sysml.runtime.matrix.data.SparseBlock; /** * Customer DataOutput to serialize directly into the given byte array. @@ -158,24 +157,24 @@ public class CacheDataOutput implements DataOutput, MatrixBlockDataOutput } @Override - public void writeSparseRows(int rlen, SparseRow[] rows) + public void writeSparseRows(int rlen, SparseBlock rows) throws IOException { - int lrlen = Math.min(rows.length, rlen); + int lrlen = Math.min(rows.numRows(), rlen); //process existing rows for( int i=0; i<lrlen; i++ ) { - SparseRow arow = rows[i]; - if( arow!=null && !arow.isEmpty() ) + if( !rows.isEmpty(i) ) { - int alen = arow.size(); - int[] aix = arow.getIndexContainer(); - double[] avals = arow.getValueContainer(); + int apos = rows.pos(i); + int alen = rows.size(i); + int[] aix = rows.indexes(i); + double[] avals = rows.values(i); writeInt( alen ); - for( int j=0; j<alen; j++ ) + for( int j=apos; j<apos+alen; j++ ) { intToBa(aix[j], _buff, _count); long tmp2 = Double.doubleToRawLongBits(avals[j]); http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8ba0fdcc/src/main/java/org/apache/sysml/runtime/instructions/spark/utils/RDDConverterUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/spark/utils/RDDConverterUtils.java b/src/main/java/org/apache/sysml/runtime/instructions/spark/utils/RDDConverterUtils.java index 656a618..3867dac 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/spark/utils/RDDConverterUtils.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/spark/utils/RDDConverterUtils.java @@ -48,7 +48,7 @@ import org.apache.sysml.runtime.matrix.data.CSVFileFormatProperties; import org.apache.sysml.runtime.matrix.data.MatrixBlock; import org.apache.sysml.runtime.matrix.data.MatrixCell; import org.apache.sysml.runtime.matrix.data.MatrixIndexes; -import org.apache.sysml.runtime.matrix.data.SparseRow; +import org.apache.sysml.runtime.matrix.data.SparseBlock; import org.apache.sysml.runtime.matrix.mapred.IndexedMatrixValue; import org.apache.sysml.runtime.matrix.mapred.ReblockBuffer; import org.apache.sysml.runtime.util.DataConverter; @@ -280,11 +280,9 @@ public class RDDConverterUtils } else if( tmp.isInSparseFormat() ) //SPARSE ROW { - SparseRow row = tmp.getSparseBlock()[0]; - int rlen = row.size(); - int[] rix = row.getIndexContainer(); - double[] rvals = row.getValueContainer(); - ret.add(new LabeledPoint(arg0.getValue(i, arg0.getNumColumns()-1), Vectors.sparse(rlen, rix, rvals))); + SparseBlock sblock = tmp.getSparseBlock(); + ret.add(new LabeledPoint(arg0.getValue(i, arg0.getNumColumns()-1), + Vectors.sparse(sblock.size(0), sblock.indexes(0), sblock.values(0)))); } else // DENSE ROW { http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8ba0fdcc/src/main/java/org/apache/sysml/runtime/io/WriterTextCSV.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/io/WriterTextCSV.java b/src/main/java/org/apache/sysml/runtime/io/WriterTextCSV.java index 96e31db..54ec1a4 100644 --- a/src/main/java/org/apache/sysml/runtime/io/WriterTextCSV.java +++ b/src/main/java/org/apache/sysml/runtime/io/WriterTextCSV.java @@ -34,14 +34,13 @@ import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.mapred.JobConf; - import org.apache.sysml.conf.ConfigurationManager; import org.apache.sysml.runtime.DMLRuntimeException; import org.apache.sysml.runtime.DMLUnsupportedOperationException; import org.apache.sysml.runtime.matrix.CSVReblockMR; import org.apache.sysml.runtime.matrix.data.CSVFileFormatProperties; import org.apache.sysml.runtime.matrix.data.MatrixBlock; -import org.apache.sysml.runtime.matrix.data.SparseRow; +import org.apache.sysml.runtime.matrix.data.SparseBlock; import org.apache.sysml.runtime.util.MapReduceTool; /** @@ -138,20 +137,20 @@ public class WriterTextCSV extends MatrixWriter // Write data lines if( sparse ) //SPARSE { - SparseRow[] sparseRows = src.getSparseBlock(); + SparseBlock sblock = src.getSparseBlock(); for(int i=0; i < rlen; i++) { //write row chunk-wise to prevent OOM on large number of columns int prev_jix = -1; - if( sparseRows!=null && i<sparseRows.length - && sparseRows[i]!=null && !sparseRows[i].isEmpty() ) + if( sblock!=null && i<sblock.numRows() + && !sblock.isEmpty(i) ) { - SparseRow arow = sparseRows[i]; - int alen = arow.size(); - int[] aix = arow.getIndexContainer(); - double[] avals = arow.getValueContainer(); + int pos = sblock.pos(i); + int alen = sblock.size(i); + int[] aix = sblock.indexes(i); + double[] avals = sblock.values(i); - for(int j=0; j < alen; j++) + for(int j=pos; j<pos+alen; j++) { int jix = aix[j]; http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8ba0fdcc/src/main/java/org/apache/sysml/runtime/io/WriterTextCSVParallel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/io/WriterTextCSVParallel.java b/src/main/java/org/apache/sysml/runtime/io/WriterTextCSVParallel.java index 9758dc5..cd400fe 100644 --- a/src/main/java/org/apache/sysml/runtime/io/WriterTextCSVParallel.java +++ b/src/main/java/org/apache/sysml/runtime/io/WriterTextCSVParallel.java @@ -32,14 +32,13 @@ import java.util.concurrent.Future; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.mapred.JobConf; - import org.apache.sysml.conf.DMLConfig; import org.apache.sysml.hops.OptimizerUtils; import org.apache.sysml.runtime.controlprogram.parfor.stat.InfrastructureAnalyzer; import org.apache.sysml.runtime.matrix.data.CSVFileFormatProperties; import org.apache.sysml.runtime.matrix.data.MatrixBlock; import org.apache.sysml.runtime.matrix.data.OutputInfo; -import org.apache.sysml.runtime.matrix.data.SparseRow; +import org.apache.sysml.runtime.matrix.data.SparseBlock; import org.apache.sysml.runtime.util.MapReduceTool; /** @@ -172,20 +171,20 @@ public class WriterTextCSVParallel extends WriterTextCSV // Write data lines if( sparse ) //SPARSE { - SparseRow[] sparseRows = _src.getSparseBlock(); + SparseBlock sblock = _src.getSparseBlock(); for( int i=_rl; i<_ru; i++ ) { //write row chunk-wise to prevent OOM on large number of columns int prev_jix = -1; - if( sparseRows!=null && i<sparseRows.length - && sparseRows[i]!=null && !sparseRows[i].isEmpty() ) + if( sblock!=null && i<sblock.numRows() + && !sblock.isEmpty(i) ) { - SparseRow arow = sparseRows[i]; - int alen = arow.size(); - int[] aix = arow.getIndexContainer(); - double[] avals = arow.getValueContainer(); + int pos = sblock.pos(i); + int alen = sblock.size(i); + int[] aix = sblock.indexes(i); + double[] avals = sblock.values(i); - for(int j=0; j < alen; j++) + for(int j=pos; j<pos+alen; j++) { int jix = aix[j]; http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8ba0fdcc/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixAgg.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixAgg.java b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixAgg.java index f856e06..b52aaaf 100644 --- a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixAgg.java +++ b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixAgg.java @@ -689,14 +689,15 @@ public class LibMatrixAgg if( in1.sparse ) { - SparseRow[] a = in1.sparseBlock; + SparseBlock a = in1.sparseBlock; for( int i=rl; i<ru; i++ ) - if( a[i]!=null && !a[i].isEmpty() ) { - int alen = a[i].size(); - int[] aix = a[i].getIndexContainer(); - double[] avals = a[i].getValueContainer(); - for( int j=0; j<alen; j++ ) { + if( !a.isEmpty(i) ) { + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + for( int j=apos; j<apos+alen; j++ ) { double val1 = avals[j]; double val2 = in2.quickGetValue(i, aix[j]); double val = val1 * val2; @@ -757,12 +758,13 @@ public class LibMatrixAgg if( target.sparse ) //SPARSE target { - if( target.sparseBlock[0]!=null ) + if( !target.sparseBlock.isEmpty(0) ) { - int len = target.sparseBlock[0].size(); - int[] aix = target.sparseBlock[0].getIndexContainer(); - double[] avals = target.sparseBlock[0].getValueContainer(); - for( int j=0; j<len; j++ ) //for each nnz + int pos = target.sparseBlock.pos(0); + int len = target.sparseBlock.size(0); + int[] aix = target.sparseBlock.indexes(0); + double[] avals = target.sparseBlock.values(0); + for( int j=pos; j<pos+len; j++ ) //for each nnz { int g = (int) groups.quickGetValue(aix[j], 0); if ( g > numGroups ) @@ -795,7 +797,7 @@ public class LibMatrixAgg { if( target.sparse ) //SPARSE target { - SparseRow[] a = target.sparseBlock; + SparseBlock a = target.sparseBlock; for( int i=0; i < groups.getNumRows(); i++ ) { @@ -803,15 +805,16 @@ public class LibMatrixAgg if ( g > numGroups ) continue; - if( a[i] != null && !a[i].isEmpty() ) + if( !a.isEmpty(i) ) { - int len = a[i].size(); - int[] aix = a[i].getIndexContainer(); - double[] avals = a[i].getValueContainer(); - int j = (cl==0) ? 0 : a[i].searchIndexesFirstGTE(cl); + int pos = a.pos(i); + int len = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + int j = (cl==0) ? pos : a.posFIndexGTE(i,cl); j = (j>=0) ? j : len; - for( ; j<len && aix[j]<cu; j++ ) //for each nnz + for( ; j<pos+len && aix[j]<cu; j++ ) //for each nnz { if ( weights != null ) w = weights.quickGetValue(aix[j],0); @@ -873,7 +876,7 @@ public class LibMatrixAgg //column vector or matrix if( target.sparse ) //SPARSE target { - SparseRow[] a = target.sparseBlock; + SparseBlock a = target.sparseBlock; for( int i=0; i < groups.getNumRows(); i++ ) { @@ -881,15 +884,16 @@ public class LibMatrixAgg if ( g > numGroups ) continue; - if( a[i] != null && !a[i].isEmpty() ) + if( !a.isEmpty(i) ) { - int len = a[i].size(); - int[] aix = a[i].getIndexContainer(); - double[] avals = a[i].getValueContainer(); - int j = (cl==0) ? 0 : a[i].searchIndexesFirstGTE(cl); - j = (j>=0) ? j : len; + int pos = a.pos(i); + int len = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + int j = (cl==0) ? pos : a.posFIndexGTE(i,cl); + j = (j>=0) ? j : pos+len; - for( ; j<len && aix[j]<cu; j++ ) //for each nnz + for( ; j<pos+len && aix[j]<cu; j++ ) //for each nnz { if ( weights != null ) w = weights.quickGetValue(i, 0); @@ -1001,8 +1005,6 @@ public class LibMatrixAgg aggVal.nonZeros = nnzC; aggCorr.nonZeros = nnzCC; - //aggVal.examSparsity(); - //aggCorr.examSparsity(); } /** @@ -1022,7 +1024,7 @@ public class LibMatrixAgg aggVal.allocateDenseBlock(); //should always stay in dense aggCorr.allocateDenseBlock(); //should always stay in dense - SparseRow[] a = in.getSparseBlock(); + SparseBlock a = in.getSparseBlock(); double[] c = aggVal.getDenseBlock(); double[] cc = aggCorr.getDenseBlock(); @@ -1031,18 +1033,18 @@ public class LibMatrixAgg final int m = in.rlen; final int n = in.clen; - final int rlen = Math.min(a.length, m); + final int rlen = Math.min(a.numRows(), m); for( int i=0, cix=0; i<rlen; i++, cix+=n ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) + if( !a.isEmpty(i) ) { - int alen = arow.size(); - int[] aix = arow.getIndexContainer(); - double[] avals = arow.getValueContainer(); + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); - for( int j=0; j<alen; j++ ) + for( int j=apos; j<apos+alen; j++ ) { int ix = cix+aix[j]; buffer1._sum = c[ix]; @@ -1055,9 +1057,7 @@ public class LibMatrixAgg } aggVal.recomputeNonZeros(); - aggCorr.recomputeNonZeros(); - //aggVal.examSparsity(); - //aggCorr.examSparsity(); + aggCorr.recomputeNonZeros(); } /** @@ -1073,24 +1073,24 @@ public class LibMatrixAgg if( in.isEmptyBlock(false) ) return; - SparseRow[] a = in.getSparseBlock(); + SparseBlock a = in.getSparseBlock(); KahanObject buffer1 = new KahanObject(0, 0); KahanPlus akplus = KahanPlus.getKahanPlusFnObject(); final int m = in.rlen; - final int rlen = Math.min(a.length, m); + final int rlen = Math.min(a.numRows(), m); for( int i=0; i<rlen; i++ ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) + if( !a.isEmpty(i) ) { - int alen = arow.size(); - int[] aix = arow.getIndexContainer(); - double[] avals = arow.getValueContainer(); + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); - for( int j=0; j<alen; j++ ) + for( int j=apos; j<apos+alen; j++ ) { int jix = aix[j]; buffer1._sum = aggVal.quickGetValue(i, jix); @@ -1194,24 +1194,24 @@ public class LibMatrixAgg if( in.isEmptyBlock(false) ) return; - SparseRow[] a = in.getSparseBlock(); + SparseBlock a = in.getSparseBlock(); KahanObject buffer1 = new KahanObject(0, 0); KahanPlus akplus = KahanPlus.getKahanPlusFnObject(); final int m = in.rlen; - final int rlen = Math.min(a.length, m); + final int rlen = Math.min(a.numRows(), m); for( int i=0; i<rlen-1; i++ ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) + if( !a.isEmpty(i) ) { - int alen = arow.size(); - int[] aix = arow.getIndexContainer(); - double[] avals = arow.getValueContainer(); + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); - for( int j=0; j<alen; j++ ) + for( int j=apos; j<apos+alen; j++ ) { int jix = aix[j]; double corr = in.quickGetValue(m-1, jix); @@ -1276,25 +1276,25 @@ public class LibMatrixAgg if( in.isEmptyBlock(false) ) return; - SparseRow[] a = in.getSparseBlock(); + SparseBlock a = in.getSparseBlock(); KahanObject buffer1 = new KahanObject(0, 0); KahanPlus akplus = KahanPlus.getKahanPlusFnObject(); final int m = in.rlen; final int n = in.clen; - final int rlen = Math.min(a.length, m); + final int rlen = Math.min(a.numRows(), m); for( int i=0; i<rlen; i++ ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) + if( !a.isEmpty(i) ) { - int alen = arow.size(); - int[] aix = arow.getIndexContainer(); - double[] avals = arow.getValueContainer(); + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); - for( int j=0; j<alen && aix[j]<n-1; j++ ) + for( int j=apos; j<apos+alen && aix[j]<n-1; j++ ) { int jix = aix[j]; double corr = in.quickGetValue(i, n-1); @@ -1455,7 +1455,7 @@ public class LibMatrixAgg final int m = in.rlen; final int n = in.clen; - SparseRow[] a = in.getSparseBlock(); + SparseBlock a = in.getSparseBlock(); double[] c = out.getDenseBlock(); switch( optype ) @@ -2116,17 +2116,11 @@ public class LibMatrixAgg * @param kbuff * @param kplus */ - private static void s_uakp( SparseRow[] a, double[] c, int m, int n, KahanObject kbuff, KahanPlus kplus, int rl, int ru ) + private static void s_uakp( SparseBlock a, double[] c, int m, int n, KahanObject kbuff, KahanPlus kplus, int rl, int ru ) { - for( int i=rl; i<ru; i++ ) - { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - sum(avals, 0, alen, kbuff, kplus); - } + for( int i=rl; i<ru; i++ ) { + if( !a.isEmpty(i) ) + sum(a.values(i), a.pos(i), a.size(i), kbuff, kplus); } c[0] = kbuff._sum; c[1] = kbuff._correction; @@ -2142,22 +2136,16 @@ public class LibMatrixAgg * @param kbuff * @param kplus */ - private static void s_uarkp( SparseRow[] a, double[] c, int m, int n, KahanObject kbuff, KahanPlus kplus, int rl, int ru ) + private static void s_uarkp( SparseBlock a, double[] c, int m, int n, KahanObject kbuff, KahanPlus kplus, int rl, int ru ) { //compute row aggregates for( int i=rl, cix=rl*2; i<ru; i++, cix+=2 ) - { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); + if( !a.isEmpty(i) ) { kbuff.set(0, 0); //reset buffer - sum( avals, 0, alen, kbuff, kplus ); + sum( a.values(i), a.pos(i), a.size(i), kbuff, kplus ); c[cix+0] = kbuff._sum; c[cix+1] = kbuff._correction; } - } } /** @@ -2170,20 +2158,13 @@ public class LibMatrixAgg * @param kbuff * @param kplus */ - private static void s_uackp( SparseRow[] a, double[] c, int m, int n, KahanObject kbuff, KahanPlus kplus, int rl, int ru ) + private static void s_uackp( SparseBlock a, double[] c, int m, int n, KahanObject kbuff, KahanPlus kplus, int rl, int ru ) { //compute column aggregates for( int i=rl; i<ru; i++ ) - { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - sumAgg( avals, c, aix, alen, n, kbuff, kplus ); + if( !a.isEmpty(i) ) { + sumAgg( a.values(i), c, a.indexes(i), a.pos(i), a.size(i), n, kbuff, kplus ); } - } } /** @@ -2201,15 +2182,12 @@ public class LibMatrixAgg * @param rl Lower row limit. * @param ru Upper row limit. */ - private static void s_uasqkp(SparseRow[] a, double[] c, int m, int n, KahanObject kbuff, + private static void s_uasqkp(SparseBlock a, double[] c, int m, int n, KahanObject kbuff, KahanPlusSq kplusSq, int rl, int ru ) { for (int i=rl; i<ru; i++) { - SparseRow arow = a[i]; - if (arow!=null && !arow.isEmpty()) { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - sumSq(avals, 0, alen, kbuff, kplusSq); + if (!a.isEmpty(i)) { + sumSq(a.values(i), a.pos(i), a.size(i), kbuff, kplusSq); } } c[0] = kbuff._sum; @@ -2232,17 +2210,14 @@ public class LibMatrixAgg * @param rl Lower row limit. * @param ru Upper row limit. */ - private static void s_uarsqkp(SparseRow[] a, double[] c, int m, int n, KahanObject kbuff, + private static void s_uarsqkp(SparseBlock a, double[] c, int m, int n, KahanObject kbuff, KahanPlusSq kplusSq, int rl, int ru ) { //compute row aggregates for (int i=rl, cix=rl*2; i<ru; i++, cix+=2) { - SparseRow arow = a[i]; - if (arow!=null && !arow.isEmpty()) { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); + if (!a.isEmpty(i)) { kbuff.set(0, 0); //reset buffer - sumSq(avals, 0, alen, kbuff, kplusSq); + sumSq(a.values(i), a.pos(i), a.size(i), kbuff, kplusSq); c[cix+0] = kbuff._sum; c[cix+1] = kbuff._correction; } @@ -2265,17 +2240,13 @@ public class LibMatrixAgg * @param rl Lower row limit. * @param ru Upper row limit. */ - private static void s_uacsqkp(SparseRow[] a, double[] c, int m, int n, KahanObject kbuff, + private static void s_uacsqkp(SparseBlock a, double[] c, int m, int n, KahanObject kbuff, KahanPlusSq kplusSq, int rl, int ru ) { //compute column aggregates for (int i=rl; i<ru; i++) { - SparseRow arow = a[i]; - if (arow!=null && !arow.isEmpty()) { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - sumSqAgg(avals, c, aix, alen, n, kbuff, kplusSq); + if (!a.isEmpty(i)) { + sumSqAgg(a.values(i), c, a.indexes(i), a.pos(i), a.size(i), n, kbuff, kplusSq); } } } @@ -2290,22 +2261,16 @@ public class LibMatrixAgg * @param kbuff * @param kplus */ - private static void s_ucumkp( SparseRow[] a, double[] c, int m, int n, KahanObject kbuff, KahanPlus kplus ) + private static void s_ucumkp( SparseBlock a, double[] c, int m, int n, KahanObject kbuff, KahanPlus kplus ) { //init current row sum/correction arrays w/ neutral 0 double[] csums = new double[ 2*n ]; //scan once and compute prefix sums - for( int i=0, ix=0; i<m; i++, ix+=n ) - { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - sumAgg( avals, csums, aix, alen, n, kbuff, kplus ); - } + for( int i=0, ix=0; i<m; i++, ix+=n ) { + if( !a.isEmpty(i) ) + sumAgg( a.values(i), csums, a.indexes(i), a.pos(i), a.size(i), n, kbuff, kplus ); + //always copy current sum (not sparse-safe) System.arraycopy(csums, 0, c, ix, n); } @@ -2319,7 +2284,7 @@ public class LibMatrixAgg * @param m * @param n */ - private static void s_ucumm( SparseRow[] a, double[] c, int m, int n ) + private static void s_ucumm( SparseBlock a, double[] c, int m, int n ) { //init current row prod arrays w/ neutral 1 double[] cprod = new double[ n ]; @@ -2331,15 +2296,14 @@ public class LibMatrixAgg //scan once and compute prefix products for( int i=0, ix=0; i<m; i++, ix+=n ) { - SparseRow arow = a[i]; - //multiply row of non-zero elements - if( arow!=null && !arow.isEmpty() ) { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - productAgg( avals, cprod, aix, 0, alen ); - countAgg( avals, cnt, aix, alen ); + if( !a.isEmpty(i) ) { + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + productAgg( avals, cprod, aix, apos, 0, alen ); + countAgg( avals, cnt, aix, apos, alen ); } //correction (not sparse-safe and cumulative) @@ -2363,7 +2327,7 @@ public class LibMatrixAgg * @param init * @param builtin */ - private static void s_ucummxx( SparseRow[] a, double[] c, int m, int n, double init, Builtin builtin ) + private static void s_ucummxx( SparseBlock a, double[] c, int m, int n, double init, Builtin builtin ) { //init current row min/max array w/ extreme value double[] cmxx = new double[ n ]; @@ -2375,14 +2339,13 @@ public class LibMatrixAgg //compute column aggregates min/max for( int i=0, ix=0; i<m; i++, ix+=n ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - builtinAgg( avals, cmxx, aix, alen, builtin ); - countAgg( avals, cnt, aix, alen ); + if( !a.isEmpty(i) ) { + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + builtinAgg( avals, cmxx, aix, apos, alen, builtin ); + countAgg( avals, cnt, aix, apos, alen ); } //correction (not sparse-safe and cumulative) @@ -2406,15 +2369,11 @@ public class LibMatrixAgg * @param kbuff * @param kplus */ - private static void s_uakptrace( SparseRow[] a, double[] c, int m, int n, KahanObject kbuff, KahanPlus kplus, int rl, int ru ) + private static void s_uakptrace( SparseBlock a, double[] c, int m, int n, KahanObject kbuff, KahanPlus kplus, int rl, int ru ) { for( int i=rl; i<ru; i++ ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - double val = arow.get( i ); - kplus.execute2(kbuff, val); - } + if( !a.isEmpty(i) ) + kplus.execute2(kbuff, a.get(i,i)); } c[0] = kbuff._sum; c[1] = kbuff._correction; @@ -2430,22 +2389,18 @@ public class LibMatrixAgg * @param init * @param builtin */ - private static void s_uamxx( SparseRow[] a, double[] c, int m, int n, double init, Builtin builtin, int rl, int ru ) + private static void s_uamxx( SparseBlock a, double[] c, int m, int n, double init, Builtin builtin, int rl, int ru ) { double ret = init; //keep init val for( int i=rl; i<ru; i++ ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - double lval = builtin(avals, 0, init, alen, builtin); + if( !a.isEmpty(i) ) { + double lval = builtin(a.values(i), a.pos(i), init, a.size(i), builtin); ret = builtin.execute2(ret, lval); } //correction (not sparse-safe) - if( arow==null || arow.size()<n ) + if( a.size(i) < n ) ret = builtin.execute2(ret, 0); } c[0] = ret; @@ -2461,22 +2416,18 @@ public class LibMatrixAgg * @param init * @param builtin */ - private static void s_uarmxx( SparseRow[] a, double[] c, int m, int n, double init, Builtin builtin, int rl, int ru ) + private static void s_uarmxx( SparseBlock a, double[] c, int m, int n, double init, Builtin builtin, int rl, int ru ) { //init result (for empty rows) Arrays.fill(c, rl, ru, init); //not sparse-safe for( int i=rl; i<ru; i++ ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - c[ i ] = builtin(avals, 0, init, alen, builtin); - } + if( !a.isEmpty(i) ) + c[ i ] = builtin(a.values(i), a.pos(i), init, a.size(i), builtin); + //correction (not sparse-safe) - if( arow==null || arow.size()<n ) + if( a.size(i) < n ) c[ i ] = builtin.execute2(c[ i ], 0); } } @@ -2491,7 +2442,7 @@ public class LibMatrixAgg * @param init * @param builtin */ - private static void s_uacmxx( SparseRow[] a, double[] c, int m, int n, double init, Builtin builtin, int rl, int ru ) + private static void s_uacmxx( SparseBlock a, double[] c, int m, int n, double init, Builtin builtin, int rl, int ru ) { //init output (base for incremental agg) Arrays.fill(c, init); @@ -2502,14 +2453,13 @@ public class LibMatrixAgg //compute column aggregates min/max for( int i=rl; i<ru; i++ ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - builtinAgg( avals, c, aix, alen, builtin ); - countAgg( avals, cnt, aix, alen ); + if( !a.isEmpty(i) ) { + int apos = a.pos(i); + int alen = a.size(i); + double[] avals = a.values(i); + int[] aix = a.indexes(i); + builtinAgg( avals, c, aix, apos, alen, builtin ); + countAgg( avals, cnt, aix, apos, alen ); } } @@ -2532,19 +2482,18 @@ public class LibMatrixAgg * @param init * @param builtin */ - private static void s_uarimxx( SparseRow[] a, double[] c, int m, int n, double init, Builtin builtin, int rl, int ru ) + private static void s_uarimxx( SparseBlock a, double[] c, int m, int n, double init, Builtin builtin, int rl, int ru ) { for( int i=rl, cix=rl*2; i<ru; i++, cix+=2 ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - int maxindex = indexmax(avals, 0, init, alen, builtin); - c[cix+0] = (double)aix[maxindex] + 1; - c[cix+1] = avals[maxindex]; //max value + if( !a.isEmpty(i) ) { + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + int maxindex = indexmax(a.values(i), apos, init, alen, builtin); + c[cix+0] = (double)aix[apos+maxindex] + 1; + c[cix+1] = avals[apos+maxindex]; //max value //correction (not sparse-safe) if(alen < n && (builtin.execute2( 0, c[cix+1] ) == 1)) @@ -2576,26 +2525,26 @@ public class LibMatrixAgg * @param init * @param builtin */ - private static void s_uarimin( SparseRow[] a, double[] c, int m, int n, double init, Builtin builtin, int rl, int ru ) + private static void s_uarimin( SparseBlock a, double[] c, int m, int n, double init, Builtin builtin, int rl, int ru ) { for( int i=rl, cix=rl*2; i<ru; i++, cix+=2 ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) + if( !a.isEmpty(i) ) { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - int minindex = indexmin(avals, 0, init, alen, builtin); - c[cix+0] = (double)aix[minindex] + 1; - c[cix+1] = avals[minindex]; //min value among non-zeros + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + int minindex = indexmin(avals, apos, init, alen, builtin); + c[cix+0] = (double)aix[apos+minindex] + 1; + c[cix+1] = avals[apos+minindex]; //min value among non-zeros //correction (not sparse-safe) if(alen < n && (builtin.execute2( 0, c[cix+1] ) == 1)) { int ix = n-1; //find last 0 value for( int j=alen-1; j>=0; j--, ix-- ) - if( aix[j]!=ix ) + if( aix[apos+j]!=ix ) break; c[cix+0] = ix + 1; //min index (last) c[cix+1] = 0; //min value @@ -2620,7 +2569,7 @@ public class LibMatrixAgg * @param kbuff * @param kplus */ - private static void s_uamean( SparseRow[] a, double[] c, int m, int n, KahanObject kbuff, Mean kmean, int rl, int ru ) + private static void s_uamean( SparseBlock a, double[] c, int m, int n, KahanObject kbuff, Mean kmean, int rl, int ru ) { int len = (ru-rl) * n; int count = 0; @@ -2629,17 +2578,14 @@ public class LibMatrixAgg //note: before aggregate computation in order to //exploit 0 sum (noop) and better numerical stability for( int i=rl; i<ru; i++ ) - count += (a[i]==null)? n : n-a[i].size(); + count += (a.isEmpty(i)) ? n : n-a.size(i); //compute aggregate mean for( int i=rl; i<ru; i++ ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - mean(avals, 0, alen, count, kbuff, kmean); + if( !a.isEmpty(i) ) { + int alen = a.size(i); + mean(a.values(i), a.pos(i), alen, count, kbuff, kmean); count += alen; } } @@ -2662,22 +2608,18 @@ public class LibMatrixAgg * @param kbuff * @param kplus */ - private static void s_uarmean( SparseRow[] a, double[] c, int m, int n, KahanObject kbuff, Mean kmean, int rl, int ru ) + private static void s_uarmean( SparseBlock a, double[] c, int m, int n, KahanObject kbuff, Mean kmean, int rl, int ru ) { for( int i=rl, cix=rl*3; i<ru; i++, cix+=3 ) { //correction remaining tuples (not sparse-safe) //note: before aggregate computation in order to //exploit 0 sum (noop) and better numerical stability - int count = (a[i]==null)? n : n-a[i].size(); + int count = (a.isEmpty(i)) ? n : n-a.size(i); kbuff.set(0, 0); //reset buffer - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - mean(avals, 0, alen, count, kbuff, kmean); + if( !a.isEmpty(i) ) { + mean(a.values(i), a.pos(i), a.size(i), count, kbuff, kmean); } //OLD VERSION: correction remaining tuples (not sparse-safe) @@ -2701,7 +2643,7 @@ public class LibMatrixAgg * @param kbuff * @param kplus */ - private static void s_uacmean( SparseRow[] a, double[] c, int m, int n, KahanObject kbuff, Mean kmean, int rl, int ru ) + private static void s_uacmean( SparseBlock a, double[] c, int m, int n, KahanObject kbuff, Mean kmean, int rl, int ru ) { //correction remaining tuples (not sparse-safe) //note: before aggregate computation in order to @@ -2709,26 +2651,16 @@ public class LibMatrixAgg Arrays.fill(c, n, n*2, ru-rl); for( int i=rl; i<ru; i++ ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - countDisAgg( avals, c, aix, n, alen ); + if( !a.isEmpty(i) ) { + countDisAgg( a.values(i), c, a.indexes(i), a.pos(i), n, a.size(i) ); } } //compute column aggregate means for( int i=rl; i<ru; i++ ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - meanAgg( avals, c, aix, alen, n, kbuff, kmean ); + if( !a.isEmpty(i) ) { + meanAgg( a.values(i), c, a.indexes(i), a.pos(i), a.size(i), n, kbuff, kmean ); } } } @@ -2748,23 +2680,19 @@ public class LibMatrixAgg * @param rl Lower row limit. * @param ru Upper row limit. */ - private static void s_uavar(SparseRow[] a, double[] c, int m, int n, CM_COV_Object cbuff, CM cm, + private static void s_uavar(SparseBlock a, double[] c, int m, int n, CM_COV_Object cbuff, CM cm, int rl, int ru) throws DMLRuntimeException { // compute and store count of empty cells before aggregation int count = 0; for (int i=rl; i<ru; i++) - count += (a[i]==null) ? n : n-a[i].size(); + count += (a.isEmpty(i)) ? n : n-a.size(i); cbuff.w = count; // calculate aggregated variance (only using non-empty cells) for (int i=rl; i<ru; i++) { - SparseRow arow = a[i]; - if (arow!=null && !arow.isEmpty()) { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - var(avals, 0, alen, cbuff, cm); - } + if (!a.isEmpty(i)) + var(a.values(i), a.pos(i), a.size(i), cbuff, cm); } // store results: { var | mean, count, m2 correction, mean correction } @@ -2790,7 +2718,7 @@ public class LibMatrixAgg * @param rl Lower row limit. * @param ru Upper row limit. */ - private static void s_uarvar(SparseRow[] a, double[] c, int m, int n, CM_COV_Object cbuff, CM cm, + private static void s_uarvar(SparseBlock a, double[] c, int m, int n, CM_COV_Object cbuff, CM cm, int rl, int ru) throws DMLRuntimeException { // calculate aggregated variance for each row @@ -2799,14 +2727,11 @@ public class LibMatrixAgg // compute and store count of empty cells in this row // before aggregation - int count = (a[i] == null) ? n : n-a[i].size(); + int count = (a.isEmpty(i)) ? n : n-a.size(i); cbuff.w = count; - SparseRow arow = a[i]; - if (arow != null && !arow.isEmpty()) { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - var(avals, 0, alen, cbuff, cm); + if (!a.isEmpty(i)) { + var(a.values(i), a.pos(i), a.size(i), cbuff, cm); } // store results: { var | mean, count, m2 correction, mean correction } @@ -2833,7 +2758,7 @@ public class LibMatrixAgg * @param rl Lower row limit. * @param ru Upper row limit. */ - private static void s_uacvar(SparseRow[] a, double[] c, int m, int n, CM_COV_Object cbuff, CM cm, + private static void s_uacvar(SparseBlock a, double[] c, int m, int n, CM_COV_Object cbuff, CM cm, int rl, int ru) throws DMLRuntimeException { // compute and store counts of empty cells per column before aggregation @@ -2842,23 +2767,16 @@ public class LibMatrixAgg Arrays.fill(c, n*2, n*3, ru-rl); // counts stored in 3rd row // - then subtract one from the column count for each dense value in the column for (int i=rl; i<ru; i++) { - SparseRow arow = a[i]; - if (arow!=null && !arow.isEmpty()) { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - countDisAgg(avals, c, aix, n*2, alen); // counts stored in 3rd row + if (!a.isEmpty(i)) { + // counts stored in 3rd row + countDisAgg(a.values(i), c, a.indexes(i), a.pos(i), n*2, a.size(i)); } } // calculate aggregated variance for each column for (int i=rl; i<ru; i++) { - SparseRow arow = a[i]; - if (arow != null && !arow.isEmpty()) { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - int[] aix = arow.getIndexContainer(); - varAgg(avals, c, aix, alen, n, cbuff, cm); + if (!a.isEmpty(i)) { + varAgg(a.values(i), c, a.indexes(i), a.pos(i), a.size(i), n, cbuff, cm); } } } @@ -2871,17 +2789,14 @@ public class LibMatrixAgg * @param m * @param n */ - private static void s_uam( SparseRow[] a, double[] c, int m, int n, int rl, int ru ) + private static void s_uam( SparseBlock a, double[] c, int m, int n, int rl, int ru ) { double ret = 1; for( int i=rl; i<ru; i++ ) { - SparseRow arow = a[i]; - if( arow!=null && !arow.isEmpty() ) - { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); - ret *= product(avals, 0, alen); + if( !a.isEmpty(i) ) { + int alen = a.size(i); + ret *= product(a.values(i), 0, alen); ret *= (alen<n) ? 0 : 1; } @@ -2919,10 +2834,10 @@ public class LibMatrixAgg * Aggregated summation using the Kahan summation algorithm with * the KahanPlus function. */ - private static void sumAgg(double[] a, double[] c, int[] ai, final int len, final int n, + private static void sumAgg(double[] a, double[] c, int[] aix, int ai, final int len, final int n, KahanObject kbuff, KahanPlus kplus) { - sumAggWithFn(a, c, ai, len, n, kbuff, kplus); + sumAggWithFn(a, c, aix, ai, len, n, kbuff, kplus); } /** @@ -2949,10 +2864,10 @@ public class LibMatrixAgg * Aggregated summation of squared values using the Kahan * summation algorithm with the KahanPlusSq function. */ - private static void sumSqAgg(double[] a, double[] c, int[] ai, final int len, final int n, + private static void sumSqAgg(double[] a, double[] c, int[] aix, int ai, final int len, final int n, KahanObject kbuff, KahanPlusSq kplusSq) { - sumAggWithFn(a, c, ai, len, n, kbuff, kplusSq); + sumAggWithFn(a, c, aix, ai, len, n, kbuff, kplusSq); } /** @@ -3017,15 +2932,15 @@ public class LibMatrixAgg * algorithm. * @param kfunc A KahanFunction object to perform the summation. */ - private static void sumAggWithFn(double[] a, double[] c, int[] ai, final int len, final int n, + private static void sumAggWithFn(double[] a, double[] c, int[] aix, int ai, final int len, final int n, KahanObject kbuff, KahanFunction kfunc) { - for (int i=0; i<len; i++) { - kbuff._sum = c[ai[i]]; - kbuff._correction = c[ai[i]+n]; + for (int i=ai; i<ai+len; i++) { + kbuff._sum = c[aix[i]]; + kbuff._correction = c[aix[i]+n]; kfunc.execute2(kbuff, a[i]); - c[ai[i]] = kbuff._sum; - c[ai[i]+n] = kbuff._correction; + c[aix[i]] = kbuff._sum; + c[aix[i]+n] = kbuff._correction; } } /** @@ -3081,13 +2996,13 @@ public class LibMatrixAgg * @param ci * @param len */ - private static void productAgg( double[] a, double[] c, int[] ai, int ci, final int len ) + private static void productAgg( double[] a, double[] c, int[] aix, int ai, int ci, final int len ) { //always w/ NAN_AWARENESS: product without early abort; //even if val is 0, it might turn into NaN. //(early abort would require column-flags and branches) - for( int i=0; i<len; i++ ) - c[ ci + ai[i] ] *= a[ i ]; + for( int i=ai; i<ai+len; i++ ) + c[ ci + aix[i] ] *= a[ i ]; } /** @@ -3140,17 +3055,17 @@ public class LibMatrixAgg * @param kbuff * @param kplus */ - private static void meanAgg( double[] a, double[] c, int[] ai, final int len, final int n, KahanObject kbuff, Mean mean ) + private static void meanAgg( double[] a, double[] c, int[] aix, int ai, final int len, final int n, KahanObject kbuff, Mean mean ) { - for( int i=0; i<len; i++ ) + for( int i=ai; i<ai+len; i++ ) { - kbuff._sum = c[ai[i]]; - double count = c[ai[i]+n] + 1; - kbuff._correction = c[ai[i]+2*n]; + kbuff._sum = c[aix[i]]; + double count = c[aix[i]+n] + 1; + kbuff._correction = c[aix[i]+2*n]; mean.execute2(kbuff, a[ i ], count); - c[ai[i]] = kbuff._sum; - c[ai[i]+n] = count; - c[ai[i]+2*n] = kbuff._correction; + c[aix[i]] = kbuff._sum; + c[aix[i]+n] = count; + c[aix[i]+2*n] = kbuff._correction; } } @@ -3222,24 +3137,24 @@ public class LibMatrixAgg * @param cm A CM object of type Variance to perform the variance * calculation. */ - private static void varAgg(double[] a, double[] c, int[] ai, final int len, final int n, + private static void varAgg(double[] a, double[] c, int[] aix, int ai, final int len, final int n, CM_COV_Object cbuff, CM cm) throws DMLRuntimeException { - for (int i=0; i<len; i++) { + for (int i=ai; i<ai+len; i++) { // extract current values: { var | mean, count, m2 correction, mean correction } - cbuff.w = c[ai[i]+2*n]; // count - cbuff.m2._sum = c[ai[i]] * (cbuff.w - 1); // m2 = var * (n - 1) - cbuff.mean._sum = c[ai[i]+n]; // mean - cbuff.m2._correction = c[ai[i]+3*n]; - cbuff.mean._correction = c[ai[i]+4*n]; + cbuff.w = c[aix[i]+2*n]; // count + cbuff.m2._sum = c[aix[i]] * (cbuff.w - 1); // m2 = var * (n - 1) + cbuff.mean._sum = c[aix[i]+n]; // mean + cbuff.m2._correction = c[aix[i]+3*n]; + cbuff.mean._correction = c[aix[i]+4*n]; // calculate incremental aggregated variance cbuff = (CM_COV_Object) cm.execute(cbuff, a[i]); // store updated values: { var | mean, count, m2 correction, mean correction } - c[ai[i]] = cbuff.getRequiredResult(AggregateOperationTypes.VARIANCE); - c[ai[i]+n] = cbuff.mean._sum; - c[ai[i]+2*n] = cbuff.w; - c[ai[i]+3*n] = cbuff.m2._correction; - c[ai[i]+4*n] = cbuff.mean._correction; + c[aix[i]] = cbuff.getRequiredResult(AggregateOperationTypes.VARIANCE); + c[aix[i]+n] = cbuff.mean._sum; + c[aix[i]+2*n] = cbuff.w; + c[aix[i]+3*n] = cbuff.m2._correction; + c[aix[i]+4*n] = cbuff.mean._correction; } } @@ -3285,10 +3200,10 @@ public class LibMatrixAgg * @param len * @param aggop */ - private static void builtinAgg( double[] a, double[] c, int[] ai, final int len, Builtin aggop ) + private static void builtinAgg( double[] a, double[] c, int[] aix, int ai, final int len, Builtin aggop ) { - for( int i=0; i<len; i++ ) - c[ ai[i] ] = aggop.execute2( c[ ai[i] ], a[ i ] ); + for( int i=ai; i<ai+len; i++ ) + c[ aix[i] ] = aggop.execute2( c[ aix[i] ], a[ i ] ); } /** @@ -3342,47 +3257,47 @@ public class LibMatrixAgg * @param ai * @param len */ - private static void countAgg( double[] a, int[] c, int[] ai, final int len ) + private static void countAgg( double[] a, int[] c, int[] aix, int ai, final int len ) { final int bn = len%8; //compute rest, not aligned to 8-block - for( int i=0; i<bn; i++ ) - c[ ai[i] ]++; + for( int i=ai; i<ai+bn; i++ ) + c[ aix[i] ]++; //unrolled 8-block (for better instruction level parallelism) - for( int i=bn; i<len; i+=8 ) + for( int i=ai+bn; i<ai+len; i+=8 ) { - c[ ai[ i+0 ] ] ++; - c[ ai[ i+1 ] ] ++; - c[ ai[ i+2 ] ] ++; - c[ ai[ i+3 ] ] ++; - c[ ai[ i+4 ] ] ++; - c[ ai[ i+5 ] ] ++; - c[ ai[ i+6 ] ] ++; - c[ ai[ i+7 ] ] ++; + c[ aix[ i+0 ] ] ++; + c[ aix[ i+1 ] ] ++; + c[ aix[ i+2 ] ] ++; + c[ aix[ i+3 ] ] ++; + c[ aix[ i+4 ] ] ++; + c[ aix[ i+5 ] ] ++; + c[ aix[ i+6 ] ] ++; + c[ aix[ i+7 ] ] ++; } } - private static void countDisAgg( double[] a, double[] c, int[] ai, final int ci, final int len ) + private static void countDisAgg( double[] a, double[] c, int[] aix, int ai, final int ci, final int len ) { final int bn = len%8; //compute rest, not aligned to 8-block - for( int i=0; i<bn; i++ ) - c[ ci+ai[i] ]--; + for( int i=ai; i<ai+bn; i++ ) + c[ ci+aix[i] ]--; //unrolled 8-block (for better instruction level parallelism) - for( int i=bn; i<len; i+=8 ) + for( int i=ai+bn; i<ai+len; i+=8 ) { - c[ ci+ai[ i+0 ] ] --; - c[ ci+ai[ i+1 ] ] --; - c[ ci+ai[ i+2 ] ] --; - c[ ci+ai[ i+3 ] ] --; - c[ ci+ai[ i+4 ] ] --; - c[ ci+ai[ i+5 ] ] --; - c[ ci+ai[ i+6 ] ] --; - c[ ci+ai[ i+7 ] ] --; + c[ ci+aix[ i+0 ] ] --; + c[ ci+aix[ i+1 ] ] --; + c[ ci+aix[ i+2 ] ] --; + c[ ci+aix[ i+3 ] ] --; + c[ ci+aix[ i+4 ] ] --; + c[ ci+aix[ i+5 ] ] --; + c[ ci+aix[ i+6 ] ] --; + c[ ci+aix[ i+7 ] ] --; } } http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8ba0fdcc/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 1147c5e..5428c96 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 @@ -264,25 +264,22 @@ public class LibMatrixBincell //both sparse blocks existing if(m1.sparseBlock!=null && m2.sparseBlock!=null) { + SparseBlock lsblock = m1.sparseBlock; + SparseBlock rsblock = m2.sparseBlock; + for(int r=0; r<rlen; r++) { - SparseRow lrow = (m1.sparseBlock.length>r && m1.sparseBlock[r]!=null) ? m1.sparseBlock[r] : null; - SparseRow rrow = (m2.sparseBlock.length>r && m2.sparseBlock[r]!=null) ? m2.sparseBlock[r] : null; - - if( lrow!=null && rrow!=null) - { - mergeForSparseBinary(op, lrow.getValueContainer(), lrow.getIndexContainer(), lrow.size(), - rrow.getValueContainer(), rrow.getIndexContainer(), rrow.size(), r, ret); + if( !lsblock.isEmpty(r) && !rsblock.isEmpty(r) ) { + mergeForSparseBinary(op, lsblock.values(r), lsblock.indexes(r), lsblock.pos(r), lsblock.size(r), + rsblock.values(r), rsblock.indexes(r), rsblock.pos(r), rsblock.size(r), r, ret); } - else if( rrow!=null ) - { - appendRightForSparseBinary(op, rrow.getValueContainer(), - rrow.getIndexContainer(), rrow.size(), 0, r, ret); + else if( !rsblock.isEmpty(r) ) { + appendRightForSparseBinary(op, rsblock.values(r), rsblock.indexes(r), + rsblock.pos(r), rsblock.size(r), 0, r, ret); } - else if( lrow!=null ) - { - appendLeftForSparseBinary(op, lrow.getValueContainer(), - lrow.getIndexContainer(), lrow.size(), 0, r, ret); + else if( !lsblock.isEmpty(r) ){ + appendLeftForSparseBinary(op, lsblock.values(r), lsblock.indexes(r), + lsblock.pos(r), lsblock.size(r), 0, r, ret); } // do nothing if both not existing @@ -291,21 +288,25 @@ public class LibMatrixBincell //right sparse block existing else if( m2.sparseBlock!=null ) { - for(int r=0; r<Math.min(rlen, m2.sparseBlock.length); r++) - if(m2.sparseBlock[r]!=null) + SparseBlock rsblock = m2.sparseBlock; + + for(int r=0; r<Math.min(rlen, rsblock.numRows()); r++) + if( !rsblock.isEmpty(r) ) { - appendRightForSparseBinary(op, m2.sparseBlock[r].getValueContainer(), - m2.sparseBlock[r].getIndexContainer(), m2.sparseBlock[r].size(), 0, r, ret); + appendRightForSparseBinary(op, rsblock.values(r), rsblock.indexes(r), + rsblock.pos(r), rsblock.size(r), 0, r, ret); } } //left sparse block existing else { + SparseBlock lsblock = m1.sparseBlock; + for(int r=0; r<rlen; r++) - if( m1.sparseBlock[r]!=null ) + if( !lsblock.isEmpty(r) ) { - appendLeftForSparseBinary(op, m1.sparseBlock[r].getValueContainer(), - m1.sparseBlock[r].getIndexContainer(), m1.sparseBlock[r].size(), 0, r, ret); + appendLeftForSparseBinary(op, lsblock.values(r), lsblock.indexes(r), + lsblock.pos(r), lsblock.size(r), 0, r, ret); } } } @@ -320,9 +321,6 @@ public class LibMatrixBincell double[] c = ret.denseBlock; //1) process left input: assignment - int alen; - int[] aix; - double[] avals; if( m1.sparse ) //SPARSE left { @@ -330,14 +328,16 @@ public class LibMatrixBincell if( m1.sparseBlock != null ) { + SparseBlock a = m1.sparseBlock; + for( int i=0, ix=0; i<m; i++, ix+=n ) { - SparseRow arow = m1.sparseBlock[i]; - if( arow != null && !arow.isEmpty() ) + if( !a.isEmpty(i) ) { - alen = arow.size(); - aix = arow.getIndexContainer(); - avals = arow.getValueContainer(); - for(int k = 0; k < alen; k++) + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + for(int k = apos; k < apos+alen; k++) c[ix+aix[k]] = avals[k]; } } @@ -356,14 +356,15 @@ public class LibMatrixBincell { if(m2.sparseBlock!=null) { + SparseBlock a = m2.sparseBlock; + for( int i=0, ix=0; i<m; i++, ix+=n ) { - SparseRow arow = m2.sparseBlock[i]; - if( arow != null && !arow.isEmpty() ) - { - alen = arow.size(); - aix = arow.getIndexContainer(); - avals = arow.getValueContainer(); - for(int k = 0; k < alen; k++) + if( !a.isEmpty(i) ) { + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + for(int k = apos; k < apos+alen; k++) c[ix+aix[k]] = op.fn.execute(c[ix+aix[k]], avals[k]); } } @@ -509,7 +510,7 @@ public class LibMatrixBincell int rlen = m1.rlen; int clen = m1.clen; - SparseRow[] a = m1.sparseBlock; + SparseBlock a = m1.sparseBlock; BinaryAccessType atype = getBinaryAccessType(m1, m2); //early abort on skip and empty @@ -525,28 +526,28 @@ public class LibMatrixBincell for( int i=0; i<rlen; i++ ) { double v2 = m2.quickGetValue(i, 0); - SparseRow arow = (a==null) ? null : a[i]; - if( (skipEmpty && (arow==null || arow.isEmpty() || v2 == 0 )) - || ((arow==null || arow.isEmpty()) && v2 == 0) ) + if( (skipEmpty && (a==null || a.isEmpty(i) || v2 == 0 )) + || ((a==null || a.isEmpty(i)) && v2 == 0) ) { continue; //skip empty rows } if( isMultiply && v2==1 ) //ROW COPY { - if( arow != null && !arow.isEmpty() ) - ret.appendRow(i, arow); + if( a != null && !a.isEmpty(i) ) + ret.appendRow(i, a.get(i)); } else //GENERAL CASE { int lastIx = -1; - if( arow != null && !arow.isEmpty() ) + if( a != null && !a.isEmpty(i) ) { - int alen = arow.size(); - int[] aix = arow.getIndexContainer(); - double[] avals = arow.getValueContainer(); - for( int j=0; j<alen; j++ ) + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + for( int j=apos; j<apos+alen; j++ ) { //empty left for( int k = lastIx+1; k<aix[j]; k++ ){ @@ -572,18 +573,17 @@ public class LibMatrixBincell { for( int i=0; i<rlen; i++ ) { - SparseRow arow = (a==null) ? null : a[i]; - - if( skipEmpty && (arow==null || arow.isEmpty()) ) + if( skipEmpty && (a==null || a.isEmpty(i)) ) continue; //skip empty rows int lastIx = -1; - if( arow != null && !arow.isEmpty() ) + if( a!=null && !a.isEmpty(i) ) { - int alen = arow.size(); - int[] aix = arow.getIndexContainer(); - double[] avals = arow.getValueContainer(); - for( int j=0; j<alen; j++ ) + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + for( int j=apos; j<apos+alen; j++ ) { //empty left for( int k = lastIx+1; k<aix[j]; k++ ){ @@ -672,12 +672,12 @@ public class LibMatrixBincell if( m2.sparse && isMultiply ) //SPARSE * { //note: sparse block guaranteed to be allocated (otherwise early about) - SparseRow brow = m2.sparseBlock[0]; - if( brow != null && !brow.isEmpty() ) + SparseBlock b = m2.sparseBlock; + if( !b.isEmpty(0) ) { - int blen = brow.size(); - int[] bix = brow.getIndexContainer(); - double[] bvals = brow.getValueContainer(); + int blen = b.size(0); //always pos 0 + int[] bix = b.indexes(0); + double[] bvals = b.values(0); for( int i=0; i<rlen; i++ ) { //for each row iterate only over non-zeros elements in rhs for( int j=0; j<blen; j++ ) { @@ -921,15 +921,16 @@ public class LibMatrixBincell { //allocate sparse row structure ret.allocateSparseRowsBlock(); - SparseRow[] a = m1.sparseBlock; - SparseRow[] c = ret.sparseBlock; + SparseBlock a = m1.sparseBlock; + SparseBlock c = ret.sparseBlock; - for(int r=0; r<Math.min(m1.rlen, m1.sparseBlock.length); r++) { - if( a[r]!=null && !a[r].isEmpty() ) + for(int r=0; r<Math.min(m1.rlen, m1.sparseBlock.numRows()); r++) { + if( !a.isEmpty(r) ) { - int alen = a[r].size(); - int[] aix = a[r].getIndexContainer(); - double[] avals = a[r].getValueContainer(); + int apos = a.pos(r); + int alen = a.size(r); + int[] aix = a.indexes(r); + double[] avals = a.values(r); if( copyOnes ) //SPECIAL CASE: e.g., (X != 0) { @@ -940,12 +941,12 @@ public class LibMatrixBincell //memcopy/memset of indexes and values //note: currently we do a safe copy of values because in special cases there //might exist zeros in a sparserow and we need to ensure result correctness - System.arraycopy(aix, 0, crow.getIndexContainer(), 0, alen); + System.arraycopy(aix, apos, crow.indexes(), 0, alen); //Arrays.fill(crow.getValueContainer(), 0, alen, 1); - double[] cvals = crow.getValueContainer(); + double[] cvals = crow.values(); for(int j=0; j<alen; j++) - cvals[j] = (avals[j] != 0) ? 1 : 0; - c[r] = crow; + cvals[j] = (avals[apos+j] != 0) ? 1 : 0; + c.set(r, crow); ret.nonZeros+=alen; } else //GENERAL CASE @@ -954,7 +955,9 @@ public class LibMatrixBincell if( op.fn instanceof Multiply || op.fn instanceof Multiply2 || op.fn instanceof Power2 ) { - c[r] = new SparseRow(alen); + c.allocate(r, alen, -1); + //TODO perf sparse block + //c[r] = new SparseRow(alen); } for(int j=0; j<alen; j++) { @@ -1012,7 +1015,7 @@ public class LibMatrixBincell { ret.allocateDenseBlock(); - SparseRow[] a = m1.sparseBlock; + SparseBlock a = m1.sparseBlock; double[] c = ret.denseBlock; int m = m1.rlen; int n = m1.clen; @@ -1024,12 +1027,12 @@ public class LibMatrixBincell //compute non-zero input values for(int i=0, cix=0; i<m; i++, cix+=n) { - if( a[i]!=null && !a[i].isEmpty() ) - { - int alen = a[i].size(); - int[] aix = a[i].getIndexContainer(); - double[] avals = a[i].getValueContainer(); - for(int j=0; j<alen; j++) { + if( !a.isEmpty(i) ) { + int apos = a.pos(i); + int alen = a.size(i); + int[] aix = a.indexes(i); + double[] avals = a.values(i); + for(int j=apos; j<apos+alen; j++) { double val = op.executeScalar(avals[j]); c[ cix+aix[j] ] = val; } @@ -1087,72 +1090,76 @@ public class LibMatrixBincell if(m2.sparseBlock!=null) m2.allocateSparseRowsBlock(false); - if(m1ret.sparseBlock!=null && m2.sparseBlock!=null) + SparseBlock c = m1ret.sparseBlock; + SparseBlock b = m2.sparseBlock; + + if( c!=null && b!=null ) { for(int r=0; r<rlen; r++) { - if(m1ret.sparseBlock[r]==null && m2.sparseBlock[r]==null) + if(c.isEmpty(r) && b.isEmpty(r)) continue; - if(m2.sparseBlock[r]==null) + if( b.isEmpty(r) ) { - double[] values=m1ret.sparseBlock[r].getValueContainer(); - for(int i=0; i<m1ret.sparseBlock[r].size(); i++) + int apos = c.pos(r); + int alen = c.size(r); + double[] values=c.values(r); + for(int i=apos; i<apos+alen; i++) values[i]=op.fn.execute(values[i], 0); }else { int estimateSize=0; - if(m1ret.sparseBlock[r]!=null) - estimateSize+=m1ret.sparseBlock[r].size(); - if(m2.sparseBlock[r]!=null) - estimateSize+=m2.sparseBlock[r].size(); + if( !c.isEmpty(r) ) + estimateSize+=c.size(r); + if( !b.isEmpty(r)) + estimateSize+=b.size(r); estimateSize=Math.min(clen, estimateSize); //temp - SparseRow thisRow=m1ret.sparseBlock[r]; - m1ret.sparseBlock[r]=new SparseRow(estimateSize, clen); + SparseRow thisRow = c.get(r); + c.set(r, new SparseRow(estimateSize, clen)); if(thisRow!=null) { m1ret.nonZeros-=thisRow.size(); - mergeForSparseBinary(op, thisRow.getValueContainer(), - thisRow.getIndexContainer(), thisRow.size(), - m2.sparseBlock[r].getValueContainer(), - m2.sparseBlock[r].getIndexContainer(), m2.sparseBlock[r].size(), r, m1ret); + mergeForSparseBinary(op, thisRow.values(), thisRow.indexes(), 0, + thisRow.size(), b.values(r), b.indexes(r), b.pos(r), b.size(r), r, m1ret); - }else + } + else { - appendRightForSparseBinary(op, m2.sparseBlock[r].getValueContainer(), - m2.sparseBlock[r].getIndexContainer(), m2.sparseBlock[r].size(), 0, r, m1ret); + appendRightForSparseBinary(op, b.values(r), b.indexes(r), b.pos(r), b.size(r), 0, r, m1ret); } } } } else if(m1ret.sparseBlock==null) { - m1ret.sparseBlock=new SparseRow[rlen]; + m1ret.sparseBlock = SparseBlockFactory.createSparseBlock(rlen); + for(int r=0; r<rlen; r++) { - SparseRow brow = m2.sparseBlock[r]; - if( brow!=null && !brow.isEmpty() ) - { - m1ret.sparseBlock[r] = new SparseRow( brow.size(), clen ); - appendRightForSparseBinary(op, brow.getValueContainer(), brow.getIndexContainer(), brow.size(), 0, r, m1ret); + if( !b.isEmpty(r) ) { + SparseRow tmp = new SparseRow( b.size(r), clen ); + appendRightForSparseBinary(op, b.values(r), b.indexes(r), b.pos(r), b.size(r), 0, r, m1ret); + m1ret.sparseBlock.set(r, tmp); } } } else //that.sparseRows==null { - if( !(op.fn instanceof Plus || op.fn instanceof Minus || op.fn instanceof Or) ){ + if( !(op.fn instanceof Plus || op.fn instanceof Minus || op.fn instanceof Or) ) { for(int r=0; r<rlen; r++){ - SparseRow arow = m1ret.sparseBlock[r]; - if( arow!=null && !arow.isEmpty() ) + if( !c.isEmpty(r) ) { - int alen = arow.size(); - double[] avals = arow.getValueContainer(); + SparseRow tmp = c.get(r); + int alen = tmp.size(); + double[] avals = tmp.values(); for( int j=0; j<alen; j++ ) avals[j] = op.fn.execute(avals[j], 0); - arow.compact(); //handle removed entries (e.g., mult, and) + tmp.compact(); //handle removed entries (e.g., mult, and) + c.set(r, tmp); //NOTE: for left in-place, we cannot use append because it would create duplicates //appendLeftForSparseBinary(op, arow.getValueContainer(), arow.getIndexContainer(), arow.size(), 0, r, m1ret); @@ -1240,39 +1247,39 @@ public class LibMatrixBincell * @param result * @throws DMLRuntimeException */ - private static void mergeForSparseBinary(BinaryOperator op, double[] values1, int[] cols1, int size1, - double[] values2, int[] cols2, int size2, int resultRow, MatrixBlock result) + private static void mergeForSparseBinary(BinaryOperator op, double[] values1, int[] cols1, int pos1, int size1, + double[] values2, int[] cols2, int pos2, int size2, int resultRow, MatrixBlock result) throws DMLRuntimeException { int p1=0, p2=0, column; while( p1<size1 && p2< size2 ) { double value = 0; - if(cols1[p1]<cols2[p2]) + if(cols1[pos1+p1]<cols2[pos2+p2]) { - value = op.fn.execute(values1[p1], 0); - column = cols1[p1]; + value = op.fn.execute(values1[pos1+p1], 0); + column = cols1[pos1+p1]; p1++; } - else if(cols1[p1]==cols2[p2]) + else if(cols1[pos1+p1]==cols2[pos2+p2]) { - value = op.fn.execute(values1[p1], values2[p2]); - column = cols1[p1]; + value = op.fn.execute(values1[pos1+p1], values2[pos2+p2]); + column = cols1[pos1+p1]; p1++; p2++; } else { - value = op.fn.execute(0, values2[p2]); - column = cols2[p2]; + value = op.fn.execute(0, values2[pos2+p2]); + column = cols2[pos2+p2]; p2++; } result.appendValue(resultRow, column, value); } //add left over - appendLeftForSparseBinary(op, values1, cols1, size1, p1, resultRow, result); - appendRightForSparseBinary(op, values2, cols2, size2, p2, resultRow, result); + appendLeftForSparseBinary(op, values1, cols1, pos1, size1, p1, resultRow, result); + appendRightForSparseBinary(op, values2, cols2, pos2, size2, p2, resultRow, result); } /** @@ -1280,18 +1287,18 @@ public class LibMatrixBincell * @param op * @param values1 * @param cols1 + * @param pos1 * @param size1 * @param pos * @param resultRow * @param result * @throws DMLRuntimeException */ - private static void appendLeftForSparseBinary(BinaryOperator op, double[] values1, int[] cols1, int size1, + private static void appendLeftForSparseBinary(BinaryOperator op, double[] values1, int[] cols1, int pos1, int size1, int pos, int resultRow, MatrixBlock result) throws DMLRuntimeException { - for(int j=pos; j<size1; j++) - { + for(int j=pos1+pos; j<pos1+size1; j++) { double v = op.fn.execute(values1[j], 0); result.appendValue(resultRow, cols1[j], v); } @@ -1302,17 +1309,17 @@ public class LibMatrixBincell * @param op * @param values2 * @param cols2 + * @param pos2 * @param size2 * @param pos * @param resultRow * @param result * @throws DMLRuntimeException */ - private static void appendRightForSparseBinary(BinaryOperator op, double[] values2, int[] cols2, int size2, + private static void appendRightForSparseBinary(BinaryOperator op, double[] values2, int[] cols2, int pos2, int size2, int pos, int resultRow, MatrixBlock result) throws DMLRuntimeException { - for( int j=pos; j<size2; j++ ) - { + for( int j=pos2+pos; j<pos2+size2; j++ ) { double v = op.fn.execute(0, values2[j]); result.appendValue(resultRow, cols2[j], v); } http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8ba0fdcc/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDatagen.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDatagen.java b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDatagen.java index 96b929f..dcaaf1a 100644 --- a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDatagen.java +++ b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDatagen.java @@ -671,7 +671,7 @@ public class LibMatrixDatagen // irrelevant but we need to ensure consistency with MR) boolean localSparse = MatrixBlock.evalSparseFormatInMemory(blockrows, blockcols, nnzInBlocks[blockID] ); //(long)(sparsity*blockrows*blockcols)); if ( localSparse ) { - SparseRow[] c = out.sparseBlock; + SparseBlock c = out.sparseBlock; int idx = 0; // takes values in range [1, brlen*bclen] (both ends including) int ridx=0, cidx=0; // idx translates into (ridx, cidx) entry within the block @@ -692,9 +692,8 @@ public class LibMatrixDatagen ridx = (idx-1)/blockcols; cidx = (idx-1)%blockcols; double val = min + (range * valuePRNG.nextDouble()); - if( c[rowoffset+ridx]==null ) - c[rowoffset+ridx]=new SparseRow(estimatedNNzsPerRow, clen); - c[rowoffset+ridx].append(coloffset+cidx, val); + c.allocate(rowoffset+ridx, estimatedNNzsPerRow, clen); + c.append(rowoffset+ridx, coloffset+cidx, val); } } else { @@ -716,14 +715,13 @@ public class LibMatrixDatagen * */ // In this case, entire matrix is in sparse format but the current block is dense - SparseRow[] c = out.sparseBlock; + SparseBlock c = out.sparseBlock; for(int ii=0; ii < blockrows; ii++) { for(int jj=0; jj < blockcols; jj++) { if(nnzPRNG.nextDouble() <= sparsity) { double val = min + (range * valuePRNG.nextDouble()); - if( c[ii+rowoffset]==null ) - c[ii+rowoffset]=new SparseRow(estimatedNNzsPerRow, clen); - c[ii+rowoffset].append(jj+coloffset, val); + c.allocate(ii+rowoffset, estimatedNNzsPerRow, clen); + c.append(ii+rowoffset, jj+coloffset, val); } } }
