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 2015/11/23 04:52:59 UTC

[4/8] incubator-systemml git commit: New cp unary/binary guarded dense/sparse output conversion, for kmeans

New cp unary/binary guarded dense/sparse output conversion, for kmeans

By default we estimate the output sparsity on each operation, allocate
the right output, execute the operation, and only check for explicit
dense/sparse conversion if the optimizer reflects this in the memory
estimates used for operator selection. This leads to issues with certain
binary/unary operations, resulting in wrong output format (e.g.,
mistakenly dense) and thus affects performance of subsequent operations.
For example, P=ppred(D, minD, "<="); is estimated as dense although it
should be sparse for sufficiently many clusters. This change adds a
guarded sparse/dense format check (incl conversion if necessary) to all
binary and unary cp instructions. The additional memory requirements of
a potential format change are guarded by the released memory of all
inputs (if sufficiently large).

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

Branch: refs/heads/master
Commit: cc4aae71f082e727f29f8753588f8b77757ae854
Parents: 3adca72
Author: Matthias Boehm <mb...@us.ibm.com>
Authored: Sat Nov 21 00:21:23 2015 -0800
Committer: Matthias Boehm <mb...@us.ibm.com>
Committed: Sun Nov 22 19:37:17 2015 -0800

----------------------------------------------------------------------
 .../cp/ComputationCPInstruction.java            | 27 ++++++++++++++++++++
 .../cp/MatrixBuiltinCPInstruction.java          | 19 +++++++++-----
 .../cp/MatrixMatrixArithmeticCPInstruction.java | 13 +++++++---
 .../cp/MatrixMatrixBuiltinCPInstruction.java    | 22 +++++++++-------
 .../cp/MatrixMatrixRelationalCPInstruction.java | 19 +++++++++-----
 .../cp/MatrixScalarBuiltinCPInstruction.java    | 14 +++++++---
 .../cp/ScalarMatrixArithmeticCPInstruction.java | 14 +++++++---
 .../cp/ScalarMatrixRelationalCPInstruction.java | 14 +++++++---
 8 files changed, 104 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/cc4aae71/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ComputationCPInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ComputationCPInstruction.java b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ComputationCPInstruction.java
index 0f6b225..ddd49ac 100644
--- a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ComputationCPInstruction.java
+++ b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ComputationCPInstruction.java
@@ -17,6 +17,8 @@
 
 package com.ibm.bi.dml.runtime.instructions.cp;
 
+import com.ibm.bi.dml.hops.OptimizerUtils;
+import com.ibm.bi.dml.runtime.matrix.data.MatrixBlock;
 import com.ibm.bi.dml.runtime.matrix.operators.Operator;
 
 public abstract class ComputationCPInstruction extends CPInstruction 
@@ -45,4 +47,29 @@ public abstract class ComputationCPInstruction extends CPInstruction
 	public String getOutputVariableName() {
 		return output.getName();
 	}
+	
+	/**
+	 * 
+	 * @param in1
+	 * @param out
+	 * @return
+	 */
+	protected boolean checkGuardedRepresentationChange( MatrixBlock in1, MatrixBlock out ) {
+		return checkGuardedRepresentationChange(in1, null, out);
+	}
+	
+	/**
+	 * 
+	 * @param in1
+	 * @param in2
+	 * @param out
+	 * @return
+	 */
+	protected boolean checkGuardedRepresentationChange( MatrixBlock in1, MatrixBlock in2, MatrixBlock out )
+	{
+		double memDense = OptimizerUtils.estimateSize(out.getNumRows(), out.getNumColumns());
+		double memIn1 = (in1 != null) ? in1.getSizeInMemory() : 0;
+		double memIn2 = (in2 != null) ? in2.getSizeInMemory() : 0;
+		return ( memDense < memIn1 + memIn2 );	
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/cc4aae71/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixBuiltinCPInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixBuiltinCPInstruction.java b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixBuiltinCPInstruction.java
index 2b95254..face2db 100644
--- a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixBuiltinCPInstruction.java
+++ b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixBuiltinCPInstruction.java
@@ -39,19 +39,24 @@ public class MatrixBuiltinCPInstruction extends BuiltinUnaryCPInstruction
 	{	
 		UnaryOperator u_op = (UnaryOperator) _optr;
 		String output_name = output.getName();
-		MatrixBlock resultBlock = null;
 		
 		String opcode = getOpcode();
 		if(LibCommonsMath.isSupportedUnaryOperation(opcode)) {
-			resultBlock = LibCommonsMath.unaryOperations((MatrixObject)ec.getVariable(input1.getName()),getOpcode());
-			ec.setMatrixOutput(output_name, resultBlock);
+			MatrixBlock retBlock = LibCommonsMath.unaryOperations((MatrixObject)ec.getVariable(input1.getName()),getOpcode());
+			ec.setMatrixOutput(output_name, retBlock);
 		}
 		else {
-			MatrixBlock matBlock = ec.getMatrixInput(input1.getName());
-			resultBlock = (MatrixBlock) (matBlock.unaryOperations(u_op, new MatrixBlock()));
-			
-			ec.setMatrixOutput(output_name, resultBlock);
+			MatrixBlock inBlock = ec.getMatrixInput(input1.getName());
+			MatrixBlock retBlock = (MatrixBlock) (inBlock.unaryOperations(u_op, new MatrixBlock()));
+		
 			ec.releaseMatrixInput(input1.getName());
+			
+			// Ensure right dense/sparse output representation (guarded by released input memory)
+			if( checkGuardedRepresentationChange(inBlock, retBlock) ) {
+	 			retBlock.examSparsity();
+	 		}
+			
+			ec.setMatrixOutput(output_name, retBlock);
 		}		
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/cc4aae71/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixArithmeticCPInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixArithmeticCPInstruction.java b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixArithmeticCPInstruction.java
index ba9c845..e262dff 100644
--- a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixArithmeticCPInstruction.java
+++ b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixArithmeticCPInstruction.java
@@ -42,18 +42,23 @@ public class MatrixMatrixArithmeticCPInstruction extends ArithmeticBinaryCPInstr
 		throws DMLRuntimeException, DMLUnsupportedOperationException
 	{
 		// Read input matrices
-        MatrixBlock matBlock1 = ec.getMatrixInput(input1.getName());
-        MatrixBlock matBlock2 = ec.getMatrixInput(input2.getName());
+        MatrixBlock inBlock1 = ec.getMatrixInput(input1.getName());
+        MatrixBlock inBlock2 = ec.getMatrixInput(input2.getName());
 		
 		// Perform computation using input matrices, and produce the result matrix
 		BinaryOperator bop = (BinaryOperator) _optr;
-		MatrixBlock soresBlock = (MatrixBlock) (matBlock1.binaryOperations (bop, matBlock2, new MatrixBlock()));
+		MatrixBlock retBlock = (MatrixBlock) (inBlock1.binaryOperations (bop, inBlock2, new MatrixBlock()));
 		
 		// Release the memory occupied by input matrices
 		ec.releaseMatrixInput(input1.getName());
 		ec.releaseMatrixInput(input2.getName());
 		
+		// Ensure right dense/sparse output representation (guarded by released input memory)
+		if( checkGuardedRepresentationChange(inBlock1, inBlock2, retBlock) ) {
+			retBlock.examSparsity();
+		}
+		
 		// Attach result matrix with MatrixObject associated with output_name
-		ec.setMatrixOutput(output.getName(), soresBlock);
+		ec.setMatrixOutput(output.getName(), retBlock);
 	}
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/cc4aae71/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixBuiltinCPInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixBuiltinCPInstruction.java b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixBuiltinCPInstruction.java
index 374867d..2e452f5 100644
--- a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixBuiltinCPInstruction.java
+++ b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixBuiltinCPInstruction.java
@@ -41,8 +41,8 @@ public class MatrixMatrixBuiltinCPInstruction extends BuiltinBinaryCPInstruction
 	
 	@Override
 	public void processInstruction(ExecutionContext ec) 
-		throws DMLRuntimeException, DMLUnsupportedOperationException{
-
+		throws DMLRuntimeException, DMLUnsupportedOperationException
+	{
 		String opcode = getOpcode();
         
         if ( LibCommonsMath.isSupportedMatrixMatrixOperation(opcode) ) {
@@ -55,15 +55,19 @@ public class MatrixMatrixBuiltinCPInstruction extends BuiltinBinaryCPInstruction
 		String output_name = output.getName();
 		BinaryOperator bop = (BinaryOperator) _optr;
 		
-        MatrixBlock matBlock1 = ec.getMatrixInput(input1.getName());
-        MatrixBlock matBlock2 = ec.getMatrixInput(input2.getName());
-		
-        MatrixBlock resultBlock = (MatrixBlock) matBlock1.binaryOperations(bop, matBlock2, new MatrixBlock());
-		
-		ec.setMatrixOutput(output_name, resultBlock);
+		MatrixBlock inBlock1 = ec.getMatrixInput(input1.getName());
+		MatrixBlock inBlock2 = ec.getMatrixInput(input2.getName());
 		
+		MatrixBlock retBlock = (MatrixBlock) inBlock1.binaryOperations(bop, inBlock2, new MatrixBlock());
+	
 		ec.releaseMatrixInput(input1.getName());
 		ec.releaseMatrixInput(input2.getName());
+		
+		// Ensure right dense/sparse output representation (guarded by released input memory)
+		if( checkGuardedRepresentationChange(inBlock1, inBlock2, retBlock) ) {
+ 			retBlock.examSparsity();
+ 		}
+        
+		ec.setMatrixOutput(output_name, retBlock);
 	}
-	
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/cc4aae71/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixRelationalCPInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixRelationalCPInstruction.java b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixRelationalCPInstruction.java
index 1e4efaa..f19437f 100644
--- a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixRelationalCPInstruction.java
+++ b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixMatrixRelationalCPInstruction.java
@@ -39,17 +39,24 @@ public class MatrixMatrixRelationalCPInstruction extends RelationalBinaryCPInstr
 
 	@Override
 	public void processInstruction(ExecutionContext ec) 
-		throws DMLRuntimeException, DMLUnsupportedOperationException{
-        MatrixBlock matBlock1 = ec.getMatrixInput(input1.getName());
-        MatrixBlock matBlock2 = ec.getMatrixInput(input2.getName());
+		throws DMLRuntimeException, DMLUnsupportedOperationException
+	{
+        MatrixBlock inBlock1 = ec.getMatrixInput(input1.getName());
+        MatrixBlock inBlock2 = ec.getMatrixInput(input2.getName());
 		
 		String output_name = output.getName();
 		BinaryOperator bop = (BinaryOperator) _optr;
 		
-		MatrixBlock resultBlock = (MatrixBlock) matBlock1.binaryOperations(bop, matBlock2, new MatrixBlock());
-		
-		ec.setMatrixOutput(output_name, resultBlock);
+		MatrixBlock retBlock = (MatrixBlock) inBlock1.binaryOperations(bop, inBlock2, new MatrixBlock());
+
 		ec.releaseMatrixInput(input1.getName());
 		ec.releaseMatrixInput(input2.getName());
+		
+		// Ensure right dense/sparse output representation (guarded by released input memory)
+		if( checkGuardedRepresentationChange(inBlock1, inBlock2, retBlock) ) {
+ 			retBlock.examSparsity();
+ 		}
+		
+		ec.setMatrixOutput(output_name, retBlock);
 	}
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/cc4aae71/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixScalarBuiltinCPInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixScalarBuiltinCPInstruction.java b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixScalarBuiltinCPInstruction.java
index 02831e9..648df9c 100644
--- a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixScalarBuiltinCPInstruction.java
+++ b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/MatrixScalarBuiltinCPInstruction.java
@@ -45,15 +45,21 @@ public class MatrixScalarBuiltinCPInstruction extends BuiltinBinaryCPInstruction
 		CPOperand mat = ( input1.getDataType() == DataType.MATRIX ) ? input1 : input2;
 		CPOperand scalar = ( input1.getDataType() == DataType.MATRIX ) ? input2 : input1;
 		
-		MatrixBlock matBlock = ec.getMatrixInput(mat.getName());
+		MatrixBlock inBlock = ec.getMatrixInput(mat.getName());
 		ScalarObject constant = (ScalarObject) ec.getScalarInput(scalar.getName(), scalar.getValueType(), scalar.isLiteral());
 		
 		ScalarOperator sc_op = (ScalarOperator)	_optr;
 		sc_op.setConstant(constant.getDoubleValue());
 		
-		MatrixBlock resultBlock = (MatrixBlock) matBlock.scalarOperations(sc_op, new MatrixBlock());
-		
+		MatrixBlock retBlock = (MatrixBlock) inBlock.scalarOperations(sc_op, new MatrixBlock());
+
 		ec.releaseMatrixInput(mat.getName());
-		ec.setMatrixOutput(output.getName(), resultBlock);
+		
+		// Ensure right dense/sparse output representation (guarded by released input memory)
+		if( checkGuardedRepresentationChange(inBlock, retBlock) ) {
+ 			retBlock.examSparsity();
+ 		}
+		
+		ec.setMatrixOutput(output.getName(), retBlock);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/cc4aae71/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ScalarMatrixArithmeticCPInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ScalarMatrixArithmeticCPInstruction.java b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ScalarMatrixArithmeticCPInstruction.java
index f0ef4fb..fbe5bcf 100644
--- a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ScalarMatrixArithmeticCPInstruction.java
+++ b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ScalarMatrixArithmeticCPInstruction.java
@@ -25,7 +25,7 @@ import com.ibm.bi.dml.runtime.matrix.data.MatrixBlock;
 import com.ibm.bi.dml.runtime.matrix.operators.Operator;
 import com.ibm.bi.dml.runtime.matrix.operators.ScalarOperator;
 
-
+// TODO rename to MatrixScalar...
 public class ScalarMatrixArithmeticCPInstruction extends ArithmeticBinaryCPInstruction
 {
 	
@@ -45,15 +45,21 @@ public class ScalarMatrixArithmeticCPInstruction extends ArithmeticBinaryCPInstr
 		CPOperand mat = ( input1.getDataType() == DataType.MATRIX ) ? input1 : input2;
 		CPOperand scalar = ( input1.getDataType() == DataType.MATRIX ) ? input2 : input1;
 		
-		MatrixBlock matBlock = ec.getMatrixInput(mat.getName());
+		MatrixBlock inBlock = ec.getMatrixInput(mat.getName());
 		ScalarObject constant = (ScalarObject) ec.getScalarInput(scalar.getName(), scalar.getValueType(), scalar.isLiteral());
 
 		ScalarOperator sc_op = (ScalarOperator) _optr;
 		sc_op.setConstant(constant.getDoubleValue());
 		
-		MatrixBlock resultBlock = (MatrixBlock) matBlock.scalarOperations(sc_op, new MatrixBlock());
+		MatrixBlock retBlock = (MatrixBlock) inBlock.scalarOperations(sc_op, new MatrixBlock());
 		
 		ec.releaseMatrixInput(mat.getName());
-		ec.setMatrixOutput(output.getName(), resultBlock);
+		
+		// Ensure right dense/sparse output representation (guarded by released input memory)
+		if( checkGuardedRepresentationChange(inBlock, retBlock) ) {
+ 			retBlock.examSparsity();
+ 		}
+		
+		ec.setMatrixOutput(output.getName(), retBlock);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/cc4aae71/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ScalarMatrixRelationalCPInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ScalarMatrixRelationalCPInstruction.java b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ScalarMatrixRelationalCPInstruction.java
index e6cc354..2f19f10 100644
--- a/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ScalarMatrixRelationalCPInstruction.java
+++ b/src/main/java/com/ibm/bi/dml/runtime/instructions/cp/ScalarMatrixRelationalCPInstruction.java
@@ -25,7 +25,7 @@ import com.ibm.bi.dml.runtime.matrix.data.MatrixBlock;
 import com.ibm.bi.dml.runtime.matrix.operators.Operator;
 import com.ibm.bi.dml.runtime.matrix.operators.ScalarOperator;
 
-
+//TODO rename to MatrixScalar...
 public class ScalarMatrixRelationalCPInstruction extends RelationalBinaryCPInstruction
 {
 	
@@ -45,15 +45,21 @@ public class ScalarMatrixRelationalCPInstruction extends RelationalBinaryCPInstr
 		CPOperand mat = ( input1.getDataType() == DataType.MATRIX ) ? input1 : input2;
 		CPOperand scalar = ( input1.getDataType() == DataType.MATRIX ) ? input2 : input1;
 		
-		MatrixBlock matBlock = ec.getMatrixInput(mat.getName());
+		MatrixBlock inBlock = ec.getMatrixInput(mat.getName());
 		ScalarObject constant = (ScalarObject) ec.getScalarInput(scalar.getName(), scalar.getValueType(), scalar.isLiteral());
 		
 		ScalarOperator sc_op = (ScalarOperator) _optr;
 		sc_op.setConstant(constant.getDoubleValue());
 		
-		MatrixBlock resultBlock = (MatrixBlock) matBlock.scalarOperations(sc_op, new MatrixBlock());
+		MatrixBlock retBlock = (MatrixBlock) inBlock.scalarOperations(sc_op, new MatrixBlock());
 		
 		ec.releaseMatrixInput(mat.getName());
-		ec.setMatrixOutput(output.getName(), resultBlock);
+
+		// Ensure right dense/sparse output representation (guarded by released input memory)
+		if( checkGuardedRepresentationChange(inBlock, retBlock) ) {
+ 			retBlock.examSparsity();
+ 		}
+		
+		ec.setMatrixOutput(output.getName(), retBlock);
 	}
 }