You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@systemml.apache.org by mb...@apache.org on 2017/09/07 20:03:04 UTC

[1/2] systemml git commit: [SYSTEMML-1893] Performance sparse-dense binary cell operations

Repository: systemml
Updated Branches:
  refs/heads/master 772d9302d -> 137fbf18a


[SYSTEMML-1893] Performance sparse-dense binary cell operations

This patch improves performance of common sparse-dense binary cellwise
operations such as +, -, *, or axpy +- by avoiding two unnecessary scans
over the output matrix (for memset zero and recompute non-zeros).

For example, on a scenario of 100 iterations X + Y, where X is 10Kx10K,
sparsity=0.1 and Y is 10Kx10K dense, this patch improved performance
from 70.6s to 54.3s.


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

Branch: refs/heads/master
Commit: 6b1c6f065782190c84ee9461192b063b6ad19cf3
Parents: 772d930
Author: Matthias Boehm <mb...@gmail.com>
Authored: Wed Sep 6 14:48:21 2017 -0700
Committer: Matthias Boehm <mb...@gmail.com>
Committed: Thu Sep 7 13:02:43 2017 -0700

----------------------------------------------------------------------
 .../runtime/matrix/data/LibMatrixBincell.java   | 27 ++++++++++++--------
 1 file changed, 16 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/systemml/blob/6b1c6f06/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 9489225..1e2649d 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
@@ -321,8 +321,6 @@ public class LibMatrixBincell
 				
 				if( m1.sparse ) //SPARSE left
 				{
-					Arrays.fill(ret.denseBlock, 0, ret.denseBlock.length, 0); 
-					
 					if( m1.sparseBlock != null )
 					{
 						SparseBlock a = m1.sparseBlock;
@@ -349,6 +347,7 @@ public class LibMatrixBincell
 				}
 				
 				//2) process right input: op.fn (+,-,*), * only if dense
+				long lnnz = 0;
 				if( m2.sparse ) //SPARSE right
 				{				
 					if(m2.sparseBlock!=null)
@@ -364,20 +363,26 @@ public class LibMatrixBincell
 								for(int k = apos; k < apos+alen; k++) 
 									c[ix+aix[k]] = op.fn.execute(c[ix+aix[k]], avals[k]);
 							}
-						}	
+							//exploit temporal locality of rows
+							lnnz += ret.recomputeNonZeros(i, i, 0, clen-1);
+						}
 					}
 				}
 				else //DENSE right
 				{
-					if( !m2.isEmptyBlock(false) )
-						for( int i=0; i<m*n; i++ )
-							c[i] = op.fn.execute(c[i], m2.denseBlock[i]);
+					if( !m2.isEmptyBlock(false) ) {
+						double[] a = m2.denseBlock;
+						for( int i=0; i<m*n; i++ ) {
+							c[i] = op.fn.execute(c[i], a[i]);
+							lnnz += (c[i]!=0) ? 1 : 0;
+						}
+					}
 					else if(op.fn instanceof Multiply)
 						Arrays.fill(ret.denseBlock, 0, m*n, 0); 
 				}
-	
+				
 				//3) recompute nnz
-				ret.recomputeNonZeros();
+				ret.setNonZeros(lnnz);
 			}
 			else if( !ret.sparse && !m1.sparse && !m2.sparse 
 					&& m1.denseBlock!=null && m2.denseBlock!=null )
@@ -391,12 +396,12 @@ public class LibMatrixBincell
 				ValueFunction fn = op.fn;
 				
 				//compute dense-dense binary, maintain nnz on-the-fly
-				int nnz = 0;
+				int lnnz = 0;
 				for( int i=0; i<m*n; i++ ) {
 					c[i] = fn.execute(a[i], b[i]);
-					nnz += (c[i]!=0)? 1 : 0;
+					lnnz += (c[i]!=0)? 1 : 0;
 				}
-				ret.nonZeros = nnz;
+				ret.setNonZeros(lnnz);
 			}
 			else if( skipEmpty && (m1.sparse || m2.sparse) ) 
 			{


[2/2] systemml git commit: [SYSTEMML-1894] Performance log operations (replace FastMath by Math)

Posted by mb...@apache.org.
[SYSTEMML-1894] Performance log operations (replace FastMath by Math)

SystemML uses commons-math's FastMath instead of Math for certain
builtin operations due to performance and/or accuracy reasons. However,
recent experiments with jdk8 on different platforms showed that for log
operations this is meanwhile actually counter-productive. Hence, this
patch globally replaces FastMath.log with Math.log. 

On a scenario of 100 iterations of log(X), where X is a 10Kx10K dense
matrix, this patch improved performance from 413.1s to 319.8s.

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

Branch: refs/heads/master
Commit: 137fbf18ab61968fe3af1e386812e6ee51e98084
Parents: 6b1c6f0
Author: Matthias Boehm <mb...@gmail.com>
Authored: Thu Sep 7 13:02:10 2017 -0700
Committer: Matthias Boehm <mb...@gmail.com>
Committed: Thu Sep 7 13:02:45 2017 -0700

----------------------------------------------------------------------
 .../sysml/hops/codegen/cplan/CNodeBinary.java   |  4 +-
 .../sysml/hops/codegen/cplan/CNodeUnary.java    |  4 +-
 .../runtime/codegen/LibSpoofPrimitives.java     |  8 ++--
 .../sysml/runtime/functionobjects/Builtin.java  | 44 +++++++-------------
 .../runtime/matrix/data/LibMatrixMult.java      | 12 +++---
 5 files changed, 30 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/systemml/blob/137fbf18/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
index 4bbf205..926dd4d 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
@@ -176,9 +176,9 @@ public class CNodeBinary extends CNode
 				case MAX:
 					return "    double %TMP% = (%IN1% >= %IN2%) ? %IN1% : %IN2%;\n";
 				case LOG:
-					return "    double %TMP% = FastMath.log(%IN1%)/FastMath.log(%IN2%);\n";
+					return "    double %TMP% = Math.log(%IN1%)/Math.log(%IN2%);\n";
 				case LOG_NZ:
-					return "    double %TMP% = (%IN1% == 0) ? 0 : FastMath.log(%IN1%)/FastMath.log(%IN2%);\n";	
+					return "    double %TMP% = (%IN1% == 0) ? 0 : Math.log(%IN1%)/Math.log(%IN2%);\n";	
 				case POW:
 					return "    double %TMP% = Math.pow(%IN1%, %IN2%);\n";
 				case MINUS1_MULT:

http://git-wip-us.apache.org/repos/asf/systemml/blob/137fbf18/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
index 02f00b8..a4aa093 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
@@ -108,7 +108,7 @@ public class CNodeUnary extends CNode
 				case SQRT:
 					return "    double %TMP% = Math.sqrt(%IN1%);\n";
 				case LOG:
-					return "    double %TMP% = FastMath.log(%IN1%);\n";
+					return "    double %TMP% = Math.log(%IN1%);\n";
 				case ROUND: 
 					return "    double %TMP% = Math.round(%IN1%);\n";
 				case CEIL:
@@ -122,7 +122,7 @@ public class CNodeUnary extends CNode
 				case SIGMOID:
 					return "    double %TMP% = 1 / (1 + FastMath.exp(-%IN1%));\n";
 				case LOG_NZ:
-					return "    double %TMP% = (%IN1%==0) ? 0 : FastMath.log(%IN1%);\n";
+					return "    double %TMP% = (%IN1%==0) ? 0 : Math.log(%IN1%);\n";
 					
 				default: 
 					throw new RuntimeException("Invalid unary type: "+this.toString());

http://git-wip-us.apache.org/repos/asf/systemml/blob/137fbf18/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java b/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
index eed8cb3..e061064 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
@@ -832,25 +832,25 @@ public class LibSpoofPrimitives
 	
 	public static void vectLogAdd(double[] a, double[] c, int ai, int ci, int len) {
 		for( int j = ai; j < ai+len; j++, ci++)
-			c[ci] += FastMath.log(a[j]);
+			c[ci] += Math.log(a[j]);
 	}
 
 	public static void vectLogAdd(double[] a, double[] c, int[] aix, int ai, int ci, int alen, int len) {
 		for( int j = ai; j < ai+alen; j++ )
-			c[ci + aix[j]] += FastMath.log(a[j]);
+			c[ci + aix[j]] += Math.log(a[j]);
 	}
 	
 	public static double[] vectLogWrite(double[] a, int ai, int len) {
 		double[] c = allocVector(len, false);
 		for( int j = 0; j < len; j++, ai++)
-			c[j] = FastMath.log(a[ai]);
+			c[j] = Math.log(a[ai]);
 		return c;
 	}
 
 	public static double[] vectLogWrite(double[] a, int[] aix, int ai, int alen, int len) {
 		double[] c = allocVector(len, true, Double.NEGATIVE_INFINITY);
 		for( int j = ai; j < ai+alen; j++ )
-			c[aix[j]] = FastMath.log(a[j]);
+			c[aix[j]] = Math.log(a[j]);
 		return c;
 	}
 	

http://git-wip-us.apache.org/repos/asf/systemml/blob/137fbf18/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java b/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
index 41388a1..753e494 100644
--- a/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
+++ b/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java
@@ -284,12 +284,12 @@ public class Builtin extends ValueFunction
 			case ATAN:   return Math.atan(in); //faster in Math
 			case CEIL:   return FASTMATH ? FastMath.ceil(in) : Math.ceil(in);
 			case FLOOR:  return FASTMATH ? FastMath.floor(in) : Math.floor(in);
-			case LOG:    return FASTMATH ? FastMath.log(in) : Math.log(in);		
-			case LOG_NZ: return (in==0) ? 0 : FASTMATH ? FastMath.log(in) : Math.log(in);
-			case ABS:    return Math.abs(in); //no need for FastMath			
-			case SIGN:	 return FASTMATH ? FastMath.signum(in) : Math.signum(in);			
-			case SQRT:   return Math.sqrt(in); //faster in Math		
-			case EXP:    return FASTMATH ? FastMath.exp(in) : Math.exp(in);		
+			case LOG:    return Math.log(in); //faster in Math
+			case LOG_NZ: return (in==0) ? 0 : Math.log(in); //faster in Math
+			case ABS:    return Math.abs(in); //no need for FastMath
+			case SIGN:	 return FASTMATH ? FastMath.signum(in) : Math.signum(in);
+			case SQRT:   return Math.sqrt(in); //faster in Math
+			case EXP:    return FASTMATH ? FastMath.exp(in) : Math.exp(in);
 			case ROUND: return Math.round(in); //no need for FastMath
 			
 			case PLOGP:
@@ -297,8 +297,8 @@ public class Builtin extends ValueFunction
 					return 0.0;
 				else if (in < 0)
 					return Double.NaN;
-				else
-					return (in * (FASTMATH ? FastMath.log(in) : Math.log(in)));
+				else //faster in Math
+					return in * Math.log(in);
 			
 			case SPROP:
 				//sample proportion: P*(1-P)
@@ -375,17 +375,11 @@ public class Builtin extends ValueFunction
 			}
 			// *** END HACK ***
 		case LOG:
-			//if ( in1 <= 0 )
-			//	throw new DMLRuntimeException("Builtin.execute(): logarithm can be computed only for non-negative numbers.");
-			if( FASTMATH )
-				return (FastMath.log(in1)/FastMath.log(in2)); 
-			else
-				return (Math.log(in1)/Math.log(in2)); 
+			//faster in Math
+			return (Math.log(in1)/Math.log(in2)); 
 		case LOG_NZ:
-			if( FASTMATH )
-				return (in1==0) ? 0 : (FastMath.log(in1)/FastMath.log(in2)); 
-			else
-				return (in1==0) ? 0 : (Math.log(in1)/Math.log(in2)); 
+			//faster in Math
+			return (in1==0) ? 0 : (Math.log(in1)/Math.log(in2)); 
 		
 			
 		default:
@@ -436,17 +430,11 @@ public class Builtin extends ValueFunction
 		case MININDEX: return (in1 <= in2) ? 1 : 0;
 		
 		case LOG:
-			//if ( in1 <= 0 )
-			//	throw new DMLRuntimeException("Builtin.execute(): logarithm can be computed only for non-negative numbers.");
-			if( FASTMATH )
-				return (FastMath.log(in1)/FastMath.log(in2));
-			else
-				return (Math.log(in1)/Math.log(in2));
+			//faster in Math
+			return Math.log(in1)/Math.log(in2);
 		case LOG_NZ:
-			if( FASTMATH )
-				return (in1==0) ? 0 : (FastMath.log(in1)/FastMath.log(in2)); 
-			else
-				return (in1==0) ? 0 : (Math.log(in1)/Math.log(in2)); 
+			//faster in Math
+			return (in1==0) ? 0 : Math.log(in1)/Math.log(in2);
 		
 				
 		

http://git-wip-us.apache.org/repos/asf/systemml/blob/137fbf18/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 fd9742e..116c8a8 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
@@ -2684,7 +2684,7 @@ public class LibMatrixMult
 						double wij = w[ix+j];
 						if( wij != 0 ) {
 							double uvij = dotProduct(u, v, uix, vix, cd);
-							wceval += wij * FastMath.log(uvij + eps);
+							wceval += wij * Math.log(uvij + eps);
 						}
 					}
 		}
@@ -2723,7 +2723,7 @@ public class LibMatrixMult
 					int k = wpos + curk[i-bi];
 					for( ; k<wpos+wlen && wix[k]<bjmin; k++ ) {
 						double uvij = dotProduct(u, v, uix, wix[k]*cd, cd);
-						wceval += wval[k] * FastMath.log(uvij + eps);	
+						wceval += wval[k] * Math.log(uvij + eps);
 					}
 					curk[i-bi] = k - wpos;
 				}
@@ -2752,7 +2752,7 @@ public class LibMatrixMult
 					double[] wval = w.values(i);
 					for( int k=wpos; k<wpos+wlen; k++ ) {
 						double uvij = dotProductGeneric(mU, mV, i, wix[k], cd);
-						wceval += wval[k] * FastMath.log(uvij + eps);	
+						wceval += wval[k] * Math.log(uvij + eps);
 					}
 				}	
 		}
@@ -2765,7 +2765,7 @@ public class LibMatrixMult
 					double wij = w[ix];
 					if( wij != 0 ) {
 						double uvij = dotProductGeneric(mU, mV, i, j, cd);
-						wceval += wij * FastMath.log(uvij + eps);	
+						wceval += wij * Math.log(uvij + eps);
 					}
 				}
 		}
@@ -3322,7 +3322,7 @@ public class LibMatrixMult
 				1 / (1 + FastMath.exp(-uvij));
 				
 		//compute weighted output
-		return wij * ((flaglog) ? FastMath.log(cval) : cval);
+		return wij * ((flaglog) ? Math.log(cval) : cval);
 	}
 
 	private static double wsigmoid( final double wij, MatrixBlock u, MatrixBlock v, final int uix, final int vix, final boolean flagminus, final boolean flaglog, final int len )
@@ -3336,7 +3336,7 @@ public class LibMatrixMult
 				1 / (1 + FastMath.exp(-uvij));
 				
 		//compute weighted output
-		return wij * ((flaglog) ? FastMath.log(cval) : cval);
+		return wij * ((flaglog) ? Math.log(cval) : cval);
 	}
 
 	private static void wdivmm( final double wij, double[] u, double[] v, double[] c, final int uix, final int vix, final boolean left, final boolean mult, final boolean minus, final int len )