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/05/27 21:33:24 UTC

[2/2] incubator-systemml git commit: [SYSTEMML-1592] Codegen cell/multiagg templates w/ sparse side inputs

[SYSTEMML-1592] Codegen cell/multiagg templates w/ sparse side inputs 

This patch extends the code generator cell and multi-aggregate templates
by abstract side inputs which allows us to directly pass sparse inputs
without the need to (necessarily) convert these inputs into dense
format, which incurs overhead for sequential allocation and conversion.

Note that we still use dense inputs for row and outer product templates
because these templates requires direct access to rows/columns of dense
arrays. The internal primitives for generated indexing operations are
accordingly generalized via type-dependent access functionality.


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

Branch: refs/heads/master
Commit: 14fd9da1bd040c5a41ee099d3ab155e469225405
Parents: 214b177
Author: Matthias Boehm <mb...@gmail.com>
Authored: Sat May 27 00:40:59 2017 -0700
Committer: Matthias Boehm <mb...@gmail.com>
Committed: Sat May 27 00:40:59 2017 -0700

----------------------------------------------------------------------
 .../sysml/hops/codegen/cplan/CNodeCell.java     |  3 +-
 .../sysml/hops/codegen/cplan/CNodeMultiAgg.java |  5 +-
 .../sysml/hops/codegen/cplan/CNodeTernary.java  |  4 +-
 .../sysml/hops/codegen/cplan/CNodeUnary.java    |  4 +-
 .../sysml/runtime/codegen/SpoofCellwise.java    | 44 +++++++--------
 .../runtime/codegen/SpoofMultiAggregate.java    | 12 ++---
 .../sysml/runtime/codegen/SpoofOperator.java    | 57 ++++++++++++++++++--
 .../runtime/codegen/SpoofOuterProduct.java      | 16 +++---
 .../sysml/runtime/codegen/SpoofRowwise.java     |  4 +-
 9 files changed, 99 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/14fd9da1/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeCell.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeCell.java b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeCell.java
index 1bbbd67..4d1c767 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeCell.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeCell.java
@@ -34,13 +34,14 @@ public class CNodeCell extends CNodeTpl
 			+ "import org.apache.sysml.runtime.codegen.SpoofCellwise;\n"
 			+ "import org.apache.sysml.runtime.codegen.SpoofCellwise.AggOp;\n"
 			+ "import org.apache.sysml.runtime.codegen.SpoofCellwise.CellType;\n"
+			+ "import org.apache.sysml.runtime.codegen.SpoofOperator.SideInput;\n"
 			+ "import org.apache.commons.math3.util.FastMath;\n"
 			+ "\n"
 			+ "public final class %TMP% extends SpoofCellwise {\n" 
 			+ "  public %TMP%() {\n"
 			+ "    super(CellType.%TYPE%, %AGG_OP%, %SPARSE_SAFE%);\n"
 			+ "  }\n"
-			+ "  protected double genexec( double a, double[][] b, double[] scalars, int m, int n, int rowIndex, int colIndex) { \n"
+			+ "  protected double genexec(double a, SideInput[] b, double[] scalars, int m, int n, int rowIndex, int colIndex) { \n"
 			+ "%BODY_dense%"
 			+ "    return %OUT%;\n"
 			+ "  }\n"

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/14fd9da1/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeMultiAgg.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeMultiAgg.java b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeMultiAgg.java
index aa84a00..5cfa7c4 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeMultiAgg.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeMultiAgg.java
@@ -32,16 +32,17 @@ public class CNodeMultiAgg extends CNodeTpl
 	private static final String TEMPLATE = 
 			  "package codegen;\n"
 			+ "import org.apache.sysml.runtime.codegen.LibSpoofPrimitives;\n"
-			+ "import org.apache.sysml.runtime.codegen.SpoofMultiAggregate;\n"
 			+ "import org.apache.sysml.runtime.codegen.SpoofCellwise;\n"
 			+ "import org.apache.sysml.runtime.codegen.SpoofCellwise.AggOp;\n"
+			+ "import org.apache.sysml.runtime.codegen.SpoofMultiAggregate;\n"
+			+ "import org.apache.sysml.runtime.codegen.SpoofOperator.SideInput;\n"
 			+ "import org.apache.commons.math3.util.FastMath;\n"
 			+ "\n"
 			+ "public final class %TMP% extends SpoofMultiAggregate { \n"
 			+ "  public %TMP%() {\n"
 			+ "    super(%AGG_OP%);\n"
 			+ "  }\n"
-			+ "  protected void genexec( double a, double[][] b, double[] scalars, double[] c, "
+			+ "  protected void genexec(double a, SideInput[] b, double[] scalars, double[] c, "
 					+ "int m, int n, int rowIndex, int colIndex) { \n"
 			+ "%BODY_dense%"
 			+ "  }\n"

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/14fd9da1/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTernary.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTernary.java b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTernary.java
index 2a868f8..0aee40a 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTernary.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTernary.java
@@ -55,8 +55,8 @@ public class CNodeTernary extends CNode
 					
 				case LOOKUP_RC1:
 					return sparse ?
-							"    double %TMP% = getValue(%IN1v%, rowIndex*%IN2%+%IN3%-1);\n" :	
-							"    double %TMP% = getValue(%IN1%, rowIndex*%IN2%+%IN3%-1);\n";	
+							"    double %TMP% = getValue(%IN1v%, %IN2%, rowIndex, %IN3%-1);\n" :	
+							"    double %TMP% = getValue(%IN1%, %IN2%, rowIndex, %IN3%-1);\n";	
 					
 				default: 
 					throw new RuntimeException("Invalid ternary type: "+this.toString());

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/14fd9da1/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 7808421..b9c7cbe 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
@@ -74,9 +74,9 @@ public class CNodeUnary extends CNode
 			    case LOOKUP_R:
 			    	return "    double %TMP% = getValue(%IN1%, rowIndex);\n";
 			    case LOOKUP_C:
-			    	return "    double %TMP% = getValue(%IN1%, colIndex);\n";
+			    	return "    double %TMP% = getValue(%IN1%, n, 0, colIndex);\n";
 			    case LOOKUP_RC:
-			    	return "    double %TMP% = getValue(%IN1%, rowIndex*n+colIndex);\n";	
+			    	return "    double %TMP% = getValue(%IN1%, n, rowIndex, colIndex);\n";	
 				case LOOKUP0:
 					return "    double %TMP% = %IN1%[0];\n" ;
 				case POW2:

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/14fd9da1/src/main/java/org/apache/sysml/runtime/codegen/SpoofCellwise.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/codegen/SpoofCellwise.java b/src/main/java/org/apache/sysml/runtime/codegen/SpoofCellwise.java
index fe23a04..eb45cc4 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/SpoofCellwise.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/SpoofCellwise.java
@@ -113,7 +113,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		}
 		
 		//input preparation
-		double[][] b = prepInputMatrices(inputs);
+		SideInput[] b = prepInputMatricesAbstract(inputs);
 		double[] scalars = prepInputScalars(scalarObjects);
 		final int m = inputs.get(0).getNumRows();
 		final int n = inputs.get(0).getNumColumns();
@@ -189,7 +189,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		}
 		
 		//input preparation
-		double[][] b = prepInputMatrices(inputs);
+		SideInput[] b = prepInputMatricesAbstract(inputs);
 		double[] scalars = prepInputScalars(scalarObjects);
 		final int m = inputs.get(0).getNumRows();
 		final int n = inputs.get(0).getNumColumns();
@@ -239,7 +239,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		out.examSparsity();
 	}
 	
-	private long executeDense(double[] a, double[][] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private long executeDense(double[] a, SideInput[] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		double[] c = out.getDenseBlock();
@@ -256,7 +256,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return -1;
 	}
 	
-	private double executeDenseAndAgg(double[] a, double[][] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) throws DMLRuntimeException 
+	private double executeDenseAndAgg(double[] a, SideInput[] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) throws DMLRuntimeException 
 	{
 		//numerically stable aggregation for sum/sum_sq
 		if( _aggOp == AggOp.SUM || _aggOp == AggOp.SUM_SQ )
@@ -265,7 +265,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 			return executeDenseAggMxx(a, b, scalars, m, n, sparseSafe, rl, ru);
 	}
 	
-	private long executeSparse(SparseBlock sblock, double[][] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private long executeSparse(SparseBlock sblock, SideInput[] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		if( sparseSafe && sblock == null )
@@ -287,7 +287,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return -1;
 	}
 	
-	private double executeSparseAndAgg(SparseBlock sblock, double[][] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private double executeSparseAndAgg(SparseBlock sblock, SideInput[] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		if( sparseSafe && sblock == null )
@@ -299,7 +299,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 			return executeSparseAggMxx(sblock, b, scalars, m, n, sparseSafe, rl, ru);
 	}
 	
-	private long executeSparseNoAggSparse(SparseBlock sblock, double[][] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private long executeSparseNoAggSparse(SparseBlock sblock, SideInput[] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		//note: sequential scan algorithm for both sparse-safe and -unsafe 
@@ -335,7 +335,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return lnnz;
 	}
 	
-	private long executeSparseNoAggDense(SparseBlock sblock, double[][] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private long executeSparseNoAggDense(SparseBlock sblock, SideInput[] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		//note: sequential scan algorithm for both sparse-safe and -unsafe 
@@ -368,7 +368,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return lnnz;
 	}
 	
-	private long executeSparseRowAggSum(SparseBlock sblock, double[][] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private long executeSparseRowAggSum(SparseBlock sblock, SideInput[] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		KahanFunction kplus = (KahanFunction) getAggFunction();
@@ -406,7 +406,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return lnnz;
 	}
 	
-	private long executeSparseRowAggMxx(SparseBlock sblock, double[][] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private long executeSparseRowAggMxx(SparseBlock sblock, SideInput[] b, double[] scalars, MatrixBlock out, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		double initialVal = (_aggOp==AggOp.MIN) ? Double.MAX_VALUE : -Double.MAX_VALUE;
@@ -444,7 +444,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return lnnz;
 	}
 	
-	private double executeSparseAggSum(SparseBlock sblock, double[][] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private double executeSparseAggSum(SparseBlock sblock, SideInput[] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		KahanFunction kplus = (KahanFunction) getAggFunction();
@@ -478,7 +478,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return kbuff._sum;
 	}
 	
-	private double executeSparseAggMxx(SparseBlock sblock, double[][] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private double executeSparseAggMxx(SparseBlock sblock, SideInput[] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		double ret = (_aggOp==AggOp.MIN) ? Double.MAX_VALUE : -Double.MAX_VALUE;
@@ -513,7 +513,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return ret;
 	}
 	
-	private long executeDenseNoAgg(double[] a, double[][] b, double[] scalars, double[] c, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private long executeDenseNoAgg(double[] a, SideInput[] b, double[] scalars, double[] c, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		long lnnz = 0;
@@ -528,7 +528,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return lnnz;
 	}
 	
-	private long executeDenseRowAggSum(double[] a, double[][] b, double[] scalars, double[] c, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private long executeDenseRowAggSum(double[] a, SideInput[] b, double[] scalars, double[] c, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		KahanFunction kplus = (KahanFunction) getAggFunction();
@@ -546,7 +546,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return lnnz;
 	}
 	
-	private long executeDenseRowAggMxx(double[] a, double[][] b, double[] scalars, double[] c, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private long executeDenseRowAggMxx(double[] a, SideInput[] b, double[] scalars, double[] c, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		double initialVal = (_aggOp==AggOp.MIN) ? Double.MAX_VALUE : -Double.MAX_VALUE;
@@ -574,7 +574,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return lnnz;
 	}
 	
-	private double executeDenseAggSum(double[] a, double[][] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private double executeDenseAggSum(double[] a, SideInput[] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		KahanFunction kplus = (KahanFunction) getAggFunction();
@@ -589,7 +589,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		return kbuff._sum;
 	}
 	
-	private double executeDenseAggMxx(double[] a, double[][] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) 
+	private double executeDenseAggMxx(double[] a, SideInput[] b, double[] scalars, int m, int n, boolean sparseSafe, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		//safe aggregation for min/max w/ handling of zero entries
@@ -607,12 +607,12 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 	}
 	
 	
-	protected abstract double genexec( double a, double[][] b, double[] scalars, int m, int n, int rowIndex, int colIndex);
+	protected abstract double genexec( double a, SideInput[] b, double[] scalars, int m, int n, int rowIndex, int colIndex);
 	
 	private class ParAggTask implements Callable<Double> 
 	{
 		private final MatrixBlock _a;
-		private final double[][] _b;
+		private final SideInput[] _b;
 		private final double[] _scalars;
 		private final int _rlen;
 		private final int _clen;
@@ -620,7 +620,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		private final int _rl;
 		private final int _ru;
 
-		protected ParAggTask( MatrixBlock a, double[][] b, double[] scalars, 
+		protected ParAggTask( MatrixBlock a, SideInput[] b, double[] scalars, 
 				int rlen, int clen, boolean sparseSafe, int rl, int ru ) {
 			_a = a;
 			_b = b;
@@ -643,7 +643,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 	private class ParExecTask implements Callable<Long> 
 	{
 		private final MatrixBlock _a;
-		private final double[][] _b;
+		private final SideInput[] _b;
 		private final double[] _scalars;
 		private final MatrixBlock _c;
 		private final int _rlen;
@@ -652,7 +652,7 @@ public abstract class SpoofCellwise extends SpoofOperator implements Serializabl
 		private final int _rl;
 		private final int _ru;
 
-		protected ParExecTask( MatrixBlock a, double[][] b, double[] scalars, MatrixBlock c, 
+		protected ParExecTask( MatrixBlock a, SideInput[] b, double[] scalars, MatrixBlock c, 
 				int rlen, int clen, boolean sparseSafe, int rl, int ru ) {
 			_a = a;
 			_b = b;

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/14fd9da1/src/main/java/org/apache/sysml/runtime/codegen/SpoofMultiAggregate.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/codegen/SpoofMultiAggregate.java b/src/main/java/org/apache/sysml/runtime/codegen/SpoofMultiAggregate.java
index fd72631..faecd8c 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/SpoofMultiAggregate.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/SpoofMultiAggregate.java
@@ -88,7 +88,7 @@ public abstract class SpoofMultiAggregate extends SpoofOperator implements Seria
 		setInitialOutputValues(c);
 		
 		//input preparation
-		double[][] b = prepInputMatrices(inputs);
+		SideInput[] b = prepInputMatricesAbstract(inputs);
 		double[] scalars = prepInputScalars(scalarObjects);
 		final int m = inputs.get(0).getNumRows();
 		final int n = inputs.get(0).getNumColumns();
@@ -129,7 +129,7 @@ public abstract class SpoofMultiAggregate extends SpoofOperator implements Seria
 		out.examSparsity();	
 	}
 	
-	private void executeDense(double[] a, double[][] b, double[] scalars, double[] c, int m, int n, int rl, int ru) throws DMLRuntimeException 
+	private void executeDense(double[] a, SideInput[] b, double[] scalars, double[] c, int m, int n, int rl, int ru) throws DMLRuntimeException 
 	{
 		//core dense aggregation operation
 		for( int i=rl, ix=rl*n; i<ru; i++ ) { 
@@ -140,7 +140,7 @@ public abstract class SpoofMultiAggregate extends SpoofOperator implements Seria
 		}
 	}
 	
-	private void executeSparse(SparseBlock sblock, double[][] b, double[] scalars, double[] c, int m, int n, int rl, int ru) 
+	private void executeSparse(SparseBlock sblock, SideInput[] b, double[] scalars, double[] c, int m, int n, int rl, int ru) 
 		throws DMLRuntimeException 
 	{
 		//core dense aggregation operation
@@ -152,7 +152,7 @@ public abstract class SpoofMultiAggregate extends SpoofOperator implements Seria
 	}
 
 	
-	protected abstract void genexec( double a, double[][] b, double[] scalars, double[] c, int m, int n, int rowIndex, int colIndex);
+	protected abstract void genexec( double a, SideInput[] b, double[] scalars, double[] c, int m, int n, int rowIndex, int colIndex);
 	
 	
 	private void setInitialOutputValues(double[] c) {
@@ -229,14 +229,14 @@ public abstract class SpoofMultiAggregate extends SpoofOperator implements Seria
 	private class ParAggTask implements Callable<double[]> 
 	{
 		private final MatrixBlock _a;
-		private final double[][] _b;
+		private final SideInput[] _b;
 		private final double[] _scalars;
 		private final int _rlen;
 		private final int _clen;
 		private final int _rl;
 		private final int _ru;
 
-		protected ParAggTask( MatrixBlock a, double[][] b, double[] scalars, 
+		protected ParAggTask( MatrixBlock a, SideInput[] b, double[] scalars, 
 				int rlen, int clen, int rl, int ru ) {
 			_a = a;
 			_b = b;

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/14fd9da1/src/main/java/org/apache/sysml/runtime/codegen/SpoofOperator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/codegen/SpoofOperator.java b/src/main/java/org/apache/sysml/runtime/codegen/SpoofOperator.java
index ced10f9..9499319 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/SpoofOperator.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/SpoofOperator.java
@@ -57,15 +57,15 @@ public abstract class SpoofOperator implements Serializable
 		return execute(inputs, scalars);
 	}
 	
-	protected double[][] prepInputMatrices(ArrayList<MatrixBlock> inputs) {
-		return prepInputMatrices(inputs, 1, inputs.size()-1);
+	protected double[][] prepInputMatricesDense(ArrayList<MatrixBlock> inputs) {
+		return prepInputMatricesDense(inputs, 1, inputs.size()-1);
 	}
 	
-	protected double[][] prepInputMatrices(ArrayList<MatrixBlock> inputs, int offset) {
-		return prepInputMatrices(inputs, offset, inputs.size()-offset);
+	protected double[][] prepInputMatricesDense(ArrayList<MatrixBlock> inputs, int offset) {
+		return prepInputMatricesDense(inputs, offset, inputs.size()-offset);
 	}
 	
-	protected double[][] prepInputMatrices(ArrayList<MatrixBlock> inputs, int offset, int len) {
+	protected double[][] prepInputMatricesDense(ArrayList<MatrixBlock> inputs, int offset, int len) {
 		double[][] b = new double[len][]; 
 		for(int i=offset; i<offset+len; i++) {
 			//convert empty or sparse to dense temporary block (note: we don't do
@@ -85,6 +85,26 @@ public abstract class SpoofOperator implements Serializable
 		return b;
 	}
 	
+	protected SideInput[] prepInputMatricesAbstract(ArrayList<MatrixBlock> inputs) {
+		return prepInputMatricesAbstract(inputs, 1, inputs.size()-1);
+	}
+	
+	protected SideInput[] prepInputMatricesAbstract(ArrayList<MatrixBlock> inputs, int offset) {
+		return prepInputMatricesAbstract(inputs, offset, inputs.size()-offset);
+	}
+	
+	protected SideInput[] prepInputMatricesAbstract(ArrayList<MatrixBlock> inputs, int offset, int len) {
+		SideInput[] b = new SideInput[len]; 
+		for(int i=offset; i<offset+len; i++) {
+			if( inputs.get(i).isInSparseFormat() && inputs.get(i).isAllocated() )
+				b[i-offset] = new SideInput(null, inputs.get(i));
+			else
+				b[i-offset] = new SideInput(inputs.get(i).getDenseBlock(), null);
+		}
+		
+		return b;
+	}
+	
 	protected double[] prepInputScalars(ArrayList<ScalarObject> scalarObjects) {
 		double[] scalars = new double[scalarObjects.size()]; 
 		for(int i=0; i < scalarObjects.size(); i++)
@@ -94,7 +114,34 @@ public abstract class SpoofOperator implements Serializable
 	
 	//abstraction for safely accessing sideways matrices without the need 
 	//to allocate empty matrices as dense, see prepInputMatrices
+	
 	protected static double getValue(double[] data, int index) {
 		return (data!=null) ? data[index] : 0;
 	}
+	
+	protected static double getValue(double[] data, int n, int rowIndex, int colIndex) {
+		return (data!=null) ? data[rowIndex*n+colIndex] : 0;
+	}
+	
+	protected static double getValue(SideInput data, int rowIndex) {
+		//note: wrapper sideinput guaranteed to exist
+		return (data.dBlock!=null) ? data.dBlock[rowIndex] : 
+			(data.mBlock!=null) ? data.mBlock.quickGetValue(rowIndex, 0) : 0;
+	}
+	
+	protected static double getValue(SideInput data, int n, int rowIndex, int colIndex) {
+		//note: wrapper sideinput guaranteed to exist
+		return (data.dBlock!=null) ? data.dBlock[rowIndex*n+colIndex] : 
+			(data.mBlock!=null) ? data.mBlock.quickGetValue(rowIndex, colIndex) : 0;
+	}
+	
+	public static class SideInput {
+		private final double[] dBlock;
+		private final MatrixBlock mBlock;
+	
+		public SideInput(double[] ddata, MatrixBlock mdata) {
+			dBlock = ddata;
+			mBlock = mdata;
+		}
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/14fd9da1/src/main/java/org/apache/sysml/runtime/codegen/SpoofOuterProduct.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/codegen/SpoofOuterProduct.java b/src/main/java/org/apache/sysml/runtime/codegen/SpoofOuterProduct.java
index 15da6b9..64470ea 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/SpoofOuterProduct.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/SpoofOuterProduct.java
@@ -74,8 +74,8 @@ public abstract class SpoofOuterProduct extends SpoofOperator
 			throw new RuntimeException("Invalid input arguments.");
 		
 		//input preparation
-		double[][] ab = prepInputMatrices(inputs, 1, 2);
-		double[][] b = prepInputMatrices(inputs, 3);
+		double[][] ab = prepInputMatricesDense(inputs, 1, 2);
+		double[][] b = prepInputMatricesDense(inputs, 3);
 		double[] scalars = prepInputScalars(scalarObjects);
 		
 		//core sequential execute
@@ -103,8 +103,8 @@ public abstract class SpoofOuterProduct extends SpoofOperator
 			throw new RuntimeException("Invalid input arguments.");
 		
 		//input preparation
-		double[][] ab = prepInputMatrices(inputs, 1, 2);
-		double[][] b = prepInputMatrices(inputs, 3);
+		double[][] ab = prepInputMatricesDense(inputs, 1, 2);
+		double[][] b = prepInputMatricesDense(inputs, 3);
 		double[] scalars = prepInputScalars(scalarObjects);
 		
 		//core sequential execute
@@ -167,8 +167,8 @@ public abstract class SpoofOuterProduct extends SpoofOperator
 		}			
 		
 		//input preparation
-		double[][] ab = prepInputMatrices(inputs, 1, 2);
-		double[][] b = prepInputMatrices(inputs, 3);
+		double[][] ab = prepInputMatricesDense(inputs, 1, 2);
+		double[][] b = prepInputMatricesDense(inputs, 3);
 		double[] scalars = prepInputScalars(scalarObjects);
 				
 		//core sequential execute
@@ -238,8 +238,8 @@ public abstract class SpoofOuterProduct extends SpoofOperator
 		}	
 		
 		//input preparation
-		double[][] ab = prepInputMatrices(inputs, 1, 2);
-		double[][] b = prepInputMatrices(inputs, 3);
+		double[][] ab = prepInputMatricesDense(inputs, 1, 2);
+		double[][] b = prepInputMatricesDense(inputs, 3);
 		double[] scalars = prepInputScalars(scalarObjects);
 		
 		//core sequential execute

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/14fd9da1/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java b/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java
index 8b9fb4d..e793345 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java
@@ -93,7 +93,7 @@ public abstract class SpoofRowwise extends SpoofOperator
 		double[] c = out.getDenseBlock();
 		
 		//input preparation
-		double[][] b = prepInputMatrices(inputs);
+		double[][] b = prepInputMatricesDense(inputs);
 		double[] scalars = prepInputScalars(scalarObjects);
 		
 		//setup thread-local memory if necessary
@@ -133,7 +133,7 @@ public abstract class SpoofRowwise extends SpoofOperator
 		allocateOutputMatrix(m, n, out);
 		
 		//input preparation
-		double[][] b = prepInputMatrices(inputs);
+		double[][] b = prepInputMatricesDense(inputs);
 		double[] scalars = prepInputScalars(scalarObjects);
 		
 		//core parallel execute