Repository: incubator-systemml
Updated Branches:
  refs/heads/master b0d3c6c85 -> 71013e758


[SYSTEMML-774] Robustness thread-unsafe default sparse blocks

Closes #186.


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

Branch: refs/heads/master
Commit: 8cb28b82a8b74aad7c318d252698ce438508f338
Parents: 01d9fdb
Author: Nakul Jindal <[email protected]>
Authored: Sat Jul 16 17:17:32 2016 -0700
Committer: Matthias Boehm <[email protected]>
Committed: Sat Jul 16 17:17:32 2016 -0700

----------------------------------------------------------------------
 .../sysml/runtime/io/MatrixReaderFactory.java   | 14 +++---
 .../sysml/runtime/matrix/data/LibMatrixAgg.java | 14 +++---
 .../sysml/runtime/matrix/data/LibMatrixDNN.java | 41 ++++++++++++-----
 .../runtime/matrix/data/LibMatrixDatagen.java   | 11 +++--
 .../runtime/matrix/data/LibMatrixMult.java      | 47 +++++++++++++++-----
 .../runtime/matrix/data/LibMatrixReorg.java     |  2 +-
 .../sysml/runtime/matrix/data/MatrixBlock.java  | 21 +++++++++
 7 files changed, 114 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8cb28b82/src/main/java/org/apache/sysml/runtime/io/MatrixReaderFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/io/MatrixReaderFactory.java 
b/src/main/java/org/apache/sysml/runtime/io/MatrixReaderFactory.java
index 8da8fd7..f019107 100644
--- a/src/main/java/org/apache/sysml/runtime/io/MatrixReaderFactory.java
+++ b/src/main/java/org/apache/sysml/runtime/io/MatrixReaderFactory.java
@@ -24,6 +24,8 @@ import org.apache.sysml.conf.ConfigurationManager;
 import org.apache.sysml.runtime.DMLRuntimeException;
 import org.apache.sysml.runtime.matrix.data.CSVFileFormatProperties;
 import org.apache.sysml.runtime.matrix.data.InputInfo;
+import org.apache.sysml.runtime.matrix.data.MatrixBlock;
+import org.apache.sysml.runtime.matrix.data.SparseBlock;
 
 /**
  * 
@@ -44,14 +46,14 @@ public class MatrixReaderFactory
                
                if( iinfo == InputInfo.TextCellInputInfo || iinfo == 
InputInfo.MatrixMarketInputInfo )
                {
-                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS)
 )
+                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS)
 && MatrixBlock.DEFAULT_SPARSEBLOCK == SparseBlock.Type.MCSR )
                                reader = new ReaderTextCellParallel( iinfo );
                        else
                                reader = new ReaderTextCell( iinfo );   
                }
                else if( iinfo == InputInfo.CSVInputInfo )
                {
-                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS)
 )
+                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS)
 && MatrixBlock.DEFAULT_SPARSEBLOCK == SparseBlock.Type.MCSR )
                                reader = new ReaderTextCSVParallel(new 
CSVFileFormatProperties());
                        else
                                reader = new ReaderTextCSV(new 
CSVFileFormatProperties());
@@ -59,7 +61,7 @@ public class MatrixReaderFactory
                else if( iinfo == InputInfo.BinaryCellInputInfo ) 
                        reader = new ReaderBinaryCell();
                else if( iinfo == InputInfo.BinaryBlockInputInfo ) {
-                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_BINARYFORMATS)
 )
+                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_BINARYFORMATS)
 && MatrixBlock.DEFAULT_SPARSEBLOCK == SparseBlock.Type.MCSR )
                                reader = new ReaderBinaryBlockParallel( false );
                        else
                                reader = new ReaderBinaryBlock( false );
@@ -89,13 +91,13 @@ public class MatrixReaderFactory
                InputInfo iinfo = props.inputInfo;
 
                if( iinfo == InputInfo.TextCellInputInfo || iinfo == 
InputInfo.MatrixMarketInputInfo ) {
-                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS)
 )
+                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS)
 && MatrixBlock.DEFAULT_SPARSEBLOCK == SparseBlock.Type.MCSR )
                                reader = new ReaderTextCellParallel( iinfo );
                        else
                                reader = new ReaderTextCell( iinfo );
                }
                else if( iinfo == InputInfo.CSVInputInfo ) {
-                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS)
 )
+                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_TEXTFORMATS)
 && MatrixBlock.DEFAULT_SPARSEBLOCK == SparseBlock.Type.MCSR )
                                reader = new ReaderTextCSVParallel( 
props.formatProperties!=null ? (CSVFileFormatProperties)props.formatProperties 
: new CSVFileFormatProperties());
                        else
                                reader = new ReaderTextCSV( 
props.formatProperties!=null ? (CSVFileFormatProperties)props.formatProperties 
: new CSVFileFormatProperties());
@@ -103,7 +105,7 @@ public class MatrixReaderFactory
                else if( iinfo == InputInfo.BinaryCellInputInfo ) 
                        reader = new ReaderBinaryCell();
                else if( iinfo == InputInfo.BinaryBlockInputInfo ) {
-                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_BINARYFORMATS)
 )
+                       if( 
ConfigurationManager.getCompilerConfigFlag(ConfigType.PARALLEL_CP_READ_BINARYFORMATS)
 && MatrixBlock.DEFAULT_SPARSEBLOCK == SparseBlock.Type.MCSR )
                                reader = new ReaderBinaryBlockParallel( 
props.localFS );
                        else
                                reader = new ReaderBinaryBlock( props.localFS );

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8cb28b82/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 21c40e6..1dc6a3c 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
@@ -230,7 +230,8 @@ public class LibMatrixAgg
        {
                //fall back to sequential version if necessary
                if(    k <= 1 || (long)in.rlen*in.clen < PAR_NUMCELL_THRESHOLD 
|| in.rlen <= k
-                       || (!(uaop.indexFn instanceof ReduceCol) &&  
out.clen*8*k > PAR_INTERMEDIATE_SIZE_THRESHOLD ) ) {
+                       || (!(uaop.indexFn instanceof ReduceCol) &&  
out.clen*8*k > PAR_INTERMEDIATE_SIZE_THRESHOLD ) || 
+                       !out.isThreadSafe()) {
                        aggregateUnaryMatrix(in, out, uaop);
                        return;
                }
@@ -255,6 +256,8 @@ public class LibMatrixAgg
                        out.allocateDenseBlock();
                }
                
+               
+               
                //core multi-threaded unary aggregate computation
                //(currently: always parallelization over number of rows)
                try {
@@ -343,7 +346,7 @@ public class LibMatrixAgg
                
                //fall back to sequential if necessary or agg not supported
                if(    k <= 1 || (long)in.rlen*in.clen < PAR_NUMCELL_THRESHOLD 
|| in.rlen <= k
-                       || out.clen*8*k > PAR_INTERMEDIATE_SIZE_THRESHOLD || 
uaop == null ) {
+                       || out.clen*8*k > PAR_INTERMEDIATE_SIZE_THRESHOLD || 
uaop == null || !out.isThreadSafe()) {
                        return cumaggregateUnaryMatrix(in, out, uop);
                }
                
@@ -540,9 +543,12 @@ public class LibMatrixAgg
        public static void groupedAggregate(MatrixBlock groups, MatrixBlock 
target, MatrixBlock weights, MatrixBlock result, int numGroups, Operator op, 
int k) 
                throws DMLRuntimeException
        {
+               //preprocessing
+               result.sparse = false;  // Do not need to check for 
isThreadSafe, because dense is assumed to be thread safe
+               
                //fall back to sequential version if necessary
                boolean rowVector = (target.getNumRows()==1 && 
target.getNumColumns()>1);
-               if( k <= 1 || (long)target.rlen*target.clen < 
PAR_NUMCELL_THRESHOLD || rowVector || target.clen==1 ) {
+               if( k <= 1 || (long)target.rlen*target.clen < 
PAR_NUMCELL_THRESHOLD || rowVector || target.clen==1) {
                        groupedAggregate(groups, target, weights, result, 
numGroups, op);
                        return;
                }
@@ -551,8 +557,6 @@ public class LibMatrixAgg
                        throw new DMLRuntimeException("Invalid operator (" + op 
+ ") encountered while processing groupedAggregate.");
                }
                
-               //preprocessing
-               result.sparse = false;
                result.allocateDenseBlock();
                
                //core multi-threaded grouped aggregate computation

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8cb28b82/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDNN.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDNN.java 
b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDNN.java
index 3014b49..83f60ee 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDNN.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDNN.java
@@ -193,6 +193,10 @@ public class LibMatrixDNN {
                public void setReuseNonZeroedOutput(boolean 
reuseNonZeroedOutput) {
                        this.reuseNonZeroedOutput = reuseNonZeroedOutput;
                }
+
+               public boolean isOutputThreadSafe() {
+                       return output.isThreadSafe();
+               }
        }
        
        public static void conv2d_backward_filter(MatrixBlock input, 
MatrixBlock dout, MatrixBlock outputBlock, ConvolutionParameters params) throws 
DMLRuntimeException {
@@ -475,7 +479,7 @@ public class LibMatrixDNN {
                        }
                }
                else
-                       runParallelConvTask(constrainedNumThreads, params.K, 
TaskType.LoopBasedConv2d, params);
+                       runConvTask(constrainedNumThreads, params.K, 
TaskType.LoopBasedConv2d, params);
        }
        
        public static void maxpooling_backward(MatrixBlock input, MatrixBlock 
dout, MatrixBlock outputBlock, ConvolutionParameters params) throws 
DMLRuntimeException {
@@ -508,7 +512,7 @@ public class LibMatrixDNN {
                        }
                }
                else {
-                       runParallelConvTask(constrainedNumThreads, params.C, 
TaskType.MaxPooling_Backward, params);
+                       runConvTask(constrainedNumThreads, params.C, 
TaskType.MaxPooling_Backward, params);
                }
        }
        
@@ -815,7 +819,7 @@ public class LibMatrixDNN {
                        }
                }
                else {
-                       runParallelConvTask(constrainedNumThreads, params.C, 
TaskType.MaxPooling_Forward, params);
+                       runConvTask(constrainedNumThreads, params.C, 
TaskType.MaxPooling_Forward, params);
                }
                outputBlock.setNonZeros(params.outputNNZ.get());
        }
@@ -872,7 +876,7 @@ public class LibMatrixDNN {
                        }
                }
                else {
-                       runParallelConvTask(constrainedNumThreads, 1, 
TaskType.Rotate180, params);
+                       runConvTask(constrainedNumThreads, 1, 
TaskType.Rotate180, params);
                }
                outputBlock.setNonZeros(input.getNonZeros()); // As number of 
non-zeros doesnot change for rotate180
        }
@@ -914,7 +918,7 @@ public class LibMatrixDNN {
                        }
                }
                else {
-                       runParallelConvTask(constrainedNumThreads, 1, 
TaskType.ReshapeCol, params);
+                       runConvTask(constrainedNumThreads, 1, 
TaskType.ReshapeCol, params);
                }
                outputBlock.setNonZeros(input.getNonZeros()); // As number of 
non-zeros doesnot change for reshape_col
        }
@@ -945,7 +949,25 @@ public class LibMatrixDNN {
                return ret;
        }
        
-       private static void runParallelConvTask(int constrainedNumThreads, int 
Z, TaskType type, ConvolutionParameters params) throws DMLRuntimeException {
+       private static void runConvTask(int constrainedNumThreads, int Z, 
TaskType type, ConvolutionParameters params) throws DMLRuntimeException {
+               if (params.isOutputThreadSafe() && constrainedNumThreads > 1) {
+                       runParallelConvTask(constrainedNumThreads, Z, type, 
params);
+               } else {
+                       runSequentialConvTask(Z, type, params);
+               }
+       }
+       
+       private static void runSequentialConvTask(int Z, TaskType type, 
ConvolutionParameters params) throws DMLRuntimeException {
+               ConvTask task = new ConvTask(0, params.N, 0, Z, type, params);
+               try {
+                       task.call();
+               } catch (Exception e) {
+                       throw new DMLRuntimeException("Error while executing 
single-threaded " + type.name(), e);
+               }
+       }
+       
+       private static void runParallelConvTask(int constrainedNumThreads, int 
Z, TaskType type,
+                       ConvolutionParameters params) throws 
DMLRuntimeException {
                ArrayList<ConvTask> tasks = new ArrayList<ConvTask>();
                int [] taskSizes = getTaskSize(constrainedNumThreads, params.N, 
Z);
                for (int n = 0; n < params.N; n += taskSizes[0]) {
@@ -967,7 +989,6 @@ public class LibMatrixDNN {
                } catch (ExecutionException e) {
                        throw new DMLRuntimeException("Error while executing 
multi-threaded " + type.name(), e);
                }
-               
        }
        
        private static class ConvTask implements Callable<Object> {
@@ -1085,7 +1106,7 @@ public class LibMatrixDNN {
                        }
                }
                else {
-                       runParallelConvTask(constrainedNumThreads, params.C, 
TaskType.Im2Col, params);
+                       runConvTask(constrainedNumThreads, params.C, 
TaskType.Im2Col, params);
                }
                outputBlock.setNonZeros(params.outputNNZ.get());
        }
@@ -1106,7 +1127,7 @@ public class LibMatrixDNN {
                }
                else {
                        // Parallel col2im
-                       runParallelConvTask(constrainedNumThreads, params.C, 
TaskType.Col2Im, params);
+                       runConvTask(constrainedNumThreads, params.C, 
TaskType.Col2Im, params);
                }
        }
        
@@ -1207,4 +1228,4 @@ public class LibMatrixDNN {
                
                params.outputNNZ.addAndGet(tmpNNZ);
        }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8cb28b82/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 b3f27ea..19b2dff 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
@@ -391,14 +391,19 @@ public class LibMatrixDatagen
                final long estnnz = ((min==0.0 && max==0.0) ? 0 : 
(long)(sparsity * rows * cols));
                boolean lsparse = MatrixBlock.evalSparseFormatInMemory( rows, 
cols, estnnz );
                
-               //fallback to sequential if single rowblock or too few cells
-               if( k<=1 || (rows <= rpb && lsparse) || (long)rows*cols < 
PAR_NUMCELL_THRESHOLD  ) {
+               //fallback to sequential if single rowblock or too few cells or 
if MatrixBlock is not thread safe
+               if( k<=1 || (rows <= rpb && lsparse) || (long)rows*cols < 
PAR_NUMCELL_THRESHOLD) {
                        generateRandomMatrix(out, rgen, nnzInBlocks, bigrand, 
bSeed);
                        return;
                }
 
                out.reset(rows, cols, lsparse);
                
+               if (!out.isThreadSafe()) {
+                       generateRandomMatrix(out, rgen, nnzInBlocks, bigrand, 
bSeed);
+                       return;
+               }
+               
                //special case shortcuts for efficiency
                if ( rgen._pdf.equalsIgnoreCase(RAND_PDF_UNIFORM)) {
                        if ( min == 0.0 && max == 0.0 ) { //all zeros
@@ -418,7 +423,7 @@ public class LibMatrixDatagen
                        out.allocateSparseRowsBlock();
                else
                        out.allocateDenseBlock();       
-               
+       
                int nrb = (int) Math.ceil((double)rows/rpb);
                int ncb = (int) Math.ceil((double)cols/cpb);
                

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8cb28b82/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java 
b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
index c875e45..e054dd8 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
@@ -176,6 +176,11 @@ public class LibMatrixMult
                else
                        ret.allocateSparseRowsBlock();
                
+               if (!ret.isThreadSafe()){
+                       matrixMult(m1, m2, ret);
+                       return;
+               }
+               
                //prepare row-upper for special cases of vector-matrix / 
matrix-matrix
                boolean pm2r = checkParMatrixMultRightInputRows(m1, m2, k);
                boolean pm2c = checkParMatrixMultRightInputCols(m1, m2, k, 
pm2r);
@@ -281,10 +286,13 @@ public class LibMatrixMult
                        return;
                }
 
+               //pre-processing
+               ret.sparse = false; // MatrixBlock is assumed to be thread safe 
if dense
+               
                //check too high additional memory requirements (fallback to 
sequential)
                //check too small workload in terms of flops (fallback to 
sequential too)
                if( 8L * mV.rlen * k > MEM_OVERHEAD_THRESHOLD 
-                       || 4L * mX.rlen * mX.clen < PAR_MINFLOP_THRESHOLD ) 
+                       || 4L * mX.rlen * mX.clen < PAR_MINFLOP_THRESHOLD) 
                { 
                        matrixMultChain(mX, mV, mW, ret, ct);
                        return;
@@ -293,7 +301,6 @@ public class LibMatrixMult
                //Timing time = new Timing(true);
                                
                //pre-processing
-               ret.sparse = false;
                ret.allocateDenseBlock();
                
                //core matrix mult chain computation
@@ -377,11 +384,14 @@ public class LibMatrixMult
                        return;
                }
                
+               // pre-processing
+               ret.sparse = false;     // MatrixBlock is assumed to be thread 
safe if dense
+               
                //check no parallelization benefit (fallback to sequential)
                //check too small workload in terms of flops (fallback to 
sequential too)
                if( ret.rlen == 1 
                        || leftTranspose && 1L * m1.rlen * m1.clen * m1.clen < 
PAR_MINFLOP_THRESHOLD
-                       || !leftTranspose && 1L * m1.clen * m1.rlen * m1.rlen < 
PAR_MINFLOP_THRESHOLD ) 
+                       || !leftTranspose && 1L * m1.clen * m1.rlen * m1.rlen < 
PAR_MINFLOP_THRESHOLD) 
                { 
                        matrixMultTransposeSelf(m1, ret, leftTranspose);
                        return;
@@ -391,7 +401,6 @@ public class LibMatrixMult
                
                //pre-processing
                m1 = prepMatrixMultTransposeSelfInput(m1, leftTranspose);
-               ret.sparse = false;
                ret.allocateDenseBlock();
        
                //core multi-threaded matrix mult computation
@@ -476,6 +485,9 @@ public class LibMatrixMult
                if( pm1.isEmptyBlock(false) || m2.isEmptyBlock(false) )
                        return;
 
+               //pre-processing
+               ret1.sparse = false;    // MatrixBlock is assumed to be thread 
safe if dense
+
                //check no parallelization benefit (fallback to sequential)
                if (pm1.rlen == 1) {
                        matrixMultPermute(pm1, m2, ret1, ret2);
@@ -485,7 +497,6 @@ public class LibMatrixMult
                //Timing time = new Timing(true);
                
                //allocate first output block (second allocated if needed)
-               ret1.sparse = false;
                ret1.allocateDenseBlock();
                
                try
@@ -572,7 +583,7 @@ public class LibMatrixMult
                }
                
                //check no parallelization benefit (fallback to sequential)
-               if (mX.rlen == 1) {
+               if (mX.rlen == 1 || !ret.isThreadSafe()) {
                        matrixMultWSLoss(mX, mU, mV, mW, ret, wt);
                        return;
                }
@@ -658,8 +669,11 @@ public class LibMatrixMult
                        return; 
                }
 
+               //pre-processing
+               ret.sparse = mW.sparse;
+               
                //check no parallelization benefit (fallback to sequential)
-               if (mW.rlen == 1) {
+               if (mW.rlen == 1 || !ret.isThreadSafe()) {
                        matrixMultWSigmoid(mW, mU, mV, ret, wt);
                        return;
                }
@@ -667,7 +681,6 @@ public class LibMatrixMult
                //Timing time = new Timing(true);
 
                //pre-processing
-               ret.sparse = mW.sparse;
                ret.allocateDenseOrSparseBlock();
                
                try 
@@ -778,6 +791,11 @@ public class LibMatrixMult
                ret.sparse = wt.isBasic()?mW.sparse:false;
                ret.allocateDenseOrSparseBlock();
 
+               if (!ret.isThreadSafe()){
+                       matrixMultWDivMM(mW, mU, mV, mX, ret, wt);
+                       return;
+               }
+               
                try 
                {                       
                        ExecutorService pool = Executors.newFixedThreadPool(k);
@@ -876,6 +894,11 @@ public class LibMatrixMult
                ret.sparse = false;
                ret.allocateDenseBlock();
                
+               if (!ret.isThreadSafe()){
+                       matrixMultWCeMM(mW, mU, mV, eps, ret, wt);
+                       return;
+               }
+               
                try 
                {                       
                        ExecutorService pool = Executors.newFixedThreadPool(k);
@@ -954,9 +977,12 @@ public class LibMatrixMult
                        ret.examSparsity(); //turn empty dense into sparse
                        return; 
                }
-
+               
+               //pre-processing
+               ret.sparse = mW.sparse;
+               
                //check no parallelization benefit (fallback to sequential)
-               if (mW.rlen == 1) {
+               if (mW.rlen == 1 || !ret.isThreadSafe()) {
                        matrixMultWuMM(mW, mU, mV, ret, wt, fn);
                        return;
                }
@@ -964,7 +990,6 @@ public class LibMatrixMult
                //Timing time = new Timing(true);
 
                //pre-processing
-               ret.sparse = mW.sparse;
                ret.allocateDenseOrSparseBlock();
                
                try 

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8cb28b82/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixReorg.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixReorg.java 
b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixReorg.java
index c1b859f..c5674bb 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixReorg.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixReorg.java
@@ -187,7 +187,7 @@ public class LibMatrixReorg
                //redirect small or special cases to sequential execution
                if( in.isEmptyBlock(false) || (in.rlen * in.clen < 
PAR_NUMCELL_THRESHOLD)
                        || (SHALLOW_DENSE_VECTOR_TRANSPOSE && !in.sparse && 
!out.sparse && (in.rlen==1 || in.clen==1) )
-                       || (in.sparse && !out.sparse && in.rlen==1) || 
out.sparse )
+                       || (in.sparse && !out.sparse && in.rlen==1) || 
out.sparse || !out.isThreadSafe())
                {
                        return transpose(in, out);
                }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/8cb28b82/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java 
b/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
index 9b40cbd..cfff1f8 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
@@ -6133,6 +6133,27 @@ public class MatrixBlock extends MatrixValue implements 
CacheBlock, Externalizab
                return (MatrixBlock) block;
        }
        
+       /**
+        * Whether concurrent modification operations are allowed
+        * This method is to be used by methods that attempt to do a task 
concurrently,
+        * like in {@link LibMatrixDatagen#generateRandomMatrix(MatrixBlock, 
RandomMatrixGenerator, long[], Well1024a, long, int)}
+        * @return
+        */
+       public boolean isThreadSafe() {
+               if (sparse){
+                       if (sparseBlock == null){
+                               // It is assumed that MCSR is the only safe 
sparse block implementation available.
+                               return DEFAULT_SPARSEBLOCK == 
SparseBlock.Type.MCSR;
+                       } 
+                       else {
+                               return sparseBlock.isThreadSafe();      
+                       }
+               } 
+               else {
+                       return true;
+               }
+       }
+       
        public void print()
        {
                System.out.println("sparse = "+sparse);

Reply via email to