[SYSTEMDS-2615] Compressed Binary Cell Operations
Basic Compressed Binary Cell Operation.
Will fail in most cases, because the implementation is not finished.
diff --git a/src/main/java/org/apache/sysds/hops/rewrite/ProgramRewriter.java b/src/main/java/org/apache/sysds/hops/rewrite/ProgramRewriter.java
index 87df183..a225047 100644
--- a/src/main/java/org/apache/sysds/hops/rewrite/ProgramRewriter.java
+++ b/src/main/java/org/apache/sysds/hops/rewrite/ProgramRewriter.java
@@ -52,7 +52,6 @@
private ArrayList<HopRewriteRule> _dagRuleSet = null;
private ArrayList<StatementBlockRewriteRule> _sbRuleSet = null;
-
public ProgramRewriter() {
// by default which is used during initial compile
// apply all (static and dynamic) rewrites
diff --git a/src/main/java/org/apache/sysds/runtime/compress/AbstractCompressedMatrixBlock.java b/src/main/java/org/apache/sysds/runtime/compress/AbstractCompressedMatrixBlock.java
index 01b5b9b..9eeaf8f 100644
--- a/src/main/java/org/apache/sysds/runtime/compress/AbstractCompressedMatrixBlock.java
+++ b/src/main/java/org/apache/sysds/runtime/compress/AbstractCompressedMatrixBlock.java
@@ -35,6 +35,8 @@
import org.apache.sysds.runtime.instructions.cp.ScalarObject;
import org.apache.sysds.runtime.instructions.spark.data.IndexedMatrixValue;
import org.apache.sysds.runtime.matrix.data.CTableMap;
+import org.apache.sysds.runtime.matrix.data.LibMatrixBincell;
+import org.apache.sysds.runtime.matrix.data.LibMatrixBincell.BinaryAccessType;
import org.apache.sysds.runtime.matrix.data.MatrixBlock;
import org.apache.sysds.runtime.matrix.data.MatrixIndexes;
import org.apache.sysds.runtime.matrix.data.MatrixValue;
@@ -60,7 +62,6 @@
protected List<ColGroup> _colGroups;
-
/**
* Constructor for building an empty Compressed Matrix block object.
*/
@@ -130,22 +131,69 @@
@Override
public MatrixBlock unaryOperations(UnaryOperator op, MatrixValue result) {
printDecompressWarning("unaryOperations");
- MatrixBlock tmp = decompress();
+ MatrixBlock tmp = decompress();
return tmp.unaryOperations(op, result);
}
@Override
public MatrixBlock binaryOperations(BinaryOperator op, MatrixValue thatValue, MatrixValue result) {
- printDecompressWarning("binaryOperations", (MatrixBlock) thatValue);
- MatrixBlock left = decompress();
+
+ MatrixBlock that = getUncompressed(thatValue);
+
+ if(!LibMatrixBincell.isValidDimensionsBinary(this, that)) {
+ throw new RuntimeException("Block sizes are not matched for binary " + "cell operations: " + this.rlen + "x"
+ + this.clen + " vs " + that.getNumRows() + "x" + that.getNumColumns());
+ }
+
MatrixBlock right = getUncompressed(thatValue);
- return left.binaryOperations(op, right, result);
+
+ CompressedMatrixBlock ret = null;
+ if(result == null || !(result instanceof CompressedMatrixBlock))
+ ret = new CompressedMatrixBlock(getNumRows(), getNumColumns(), sparse);
+ else {
+ ret = (CompressedMatrixBlock) result;
+ ret.reset(rlen, clen);
+ }
+
+ // MatrixBlock ret = (MatrixBlock) result;
+ bincellOp(right, ret, op);
+ return ret;
}
+ /**
+ * matrix-matrix binary operations, MM, MV
+ *
+ * @param m2 input matrix 2
+ * @param ret result matrix
+ * @param op binary operator
+ */
+ private void bincellOp(MatrixBlock m2, CompressedMatrixBlock ret, BinaryOperator op) {
+
+
+ BinaryAccessType atype = LibMatrixBincell.getBinaryAccessType((MatrixBlock) this, m2);
+ if(atype == BinaryAccessType.MATRIX_COL_VECTOR // MATRIX - VECTOR
+ || atype == BinaryAccessType.MATRIX_ROW_VECTOR) {
+ binaryMV(m2, ret, op, atype);
+ }
+ else if(atype == BinaryAccessType.OUTER_VECTOR_VECTOR) // VECTOR - VECTOR
+ {
+ binaryVV(m2, ret, op, atype);
+ }
+ else {
+ binaryMM(m2, ret, op);
+ }
+ }
+
+ protected abstract void binaryMV(MatrixBlock m2, CompressedMatrixBlock ret, BinaryOperator op, BinaryAccessType atype );
+
+ protected abstract void binaryVV(MatrixBlock m2, CompressedMatrixBlock ret, BinaryOperator op, BinaryAccessType atype );
+
+ protected abstract void binaryMM(MatrixBlock m2, CompressedMatrixBlock ret, BinaryOperator op);
+
@Override
public MatrixBlock binaryOperationsInPlace(BinaryOperator op, MatrixValue thatValue) {
printDecompressWarning("binaryOperationsInPlace", (MatrixBlock) thatValue);
- MatrixBlock left = decompress();
+ MatrixBlock left = decompress();
MatrixBlock right = getUncompressed(thatValue);
left.binaryOperationsInPlace(op, right);
return this;
@@ -251,10 +299,11 @@
return super.cmOperations(op);
ColGroup grp = _colGroups.get(0);
MatrixBlock vals = grp.getValuesAsBlock();
- if(grp instanceof ColGroupValue){
+ if(grp instanceof ColGroupValue) {
int[] counts = ((ColGroupValue) grp).getCounts();
- return vals.cmOperations(op, getCountsAsBlock( counts));
- }else{
+ return vals.cmOperations(op, getCountsAsBlock(counts));
+ }
+ else {
return vals.cmOperations(op);
}
}
@@ -305,7 +354,7 @@
if(right == null && grp instanceof ColGroupValue) {
MatrixBlock vals = grp.getValuesAsBlock();
- int[] counts = ((ColGroupValue)grp).getCounts();
+ int[] counts = ((ColGroupValue) grp).getCounts();
double[] data = (vals.getDenseBlock() != null) ? vals.getDenseBlockValues() : null;
SortUtils.sortByValue(0, vals.getNumRows(), data, counts);
MatrixBlock counts2 = getCountsAsBlock(counts);
@@ -497,17 +546,20 @@
return isCompressed((MatrixBlock) mVal) ? ((CompressedMatrixBlock) mVal).decompress() : (MatrixBlock) mVal;
}
- private void printDecompressWarning(String operation) {
+ protected void printDecompressWarning(String operation) {
LOG.warn("Operation '" + operation + "' not supported yet - decompressing for ULA operations.");
-
+
}
- private void printDecompressWarning(String operation, MatrixBlock m2) {
+ protected void printDecompressWarning(String operation, MatrixBlock m2) {
if(isCompressed(m2)) {
LOG.warn("Operation '" + operation + "' not supported yet - decompressing for ULA operations.");
}
- }
+ else {
+ LOG.warn("Operation '" + operation + "' not supported yet - decompressing'");
+ }
+ }
@Override
public boolean isShallowSerialize() {
diff --git a/src/main/java/org/apache/sysds/runtime/compress/CompressedMatrixBlock.java b/src/main/java/org/apache/sysds/runtime/compress/CompressedMatrixBlock.java
index d7a99bc..6fef4b5 100644
--- a/src/main/java/org/apache/sysds/runtime/compress/CompressedMatrixBlock.java
+++ b/src/main/java/org/apache/sysds/runtime/compress/CompressedMatrixBlock.java
@@ -34,6 +34,8 @@
import java.util.concurrent.Future;
import org.apache.commons.lang.NotImplementedException;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.sysds.hops.OptimizerUtils;
@@ -60,12 +62,15 @@
import org.apache.sysds.runtime.functionobjects.KahanFunction;
import org.apache.sysds.runtime.functionobjects.KahanPlus;
import org.apache.sysds.runtime.functionobjects.KahanPlusSq;
+import org.apache.sysds.runtime.functionobjects.Mean;
import org.apache.sysds.runtime.functionobjects.Multiply;
import org.apache.sysds.runtime.functionobjects.ReduceAll;
import org.apache.sysds.runtime.functionobjects.ReduceCol;
+import org.apache.sysds.runtime.functionobjects.ReduceRow;
import org.apache.sysds.runtime.instructions.cp.KahanObject;
import org.apache.sysds.runtime.matrix.data.IJV;
import org.apache.sysds.runtime.matrix.data.LibMatrixBincell;
+import org.apache.sysds.runtime.matrix.data.LibMatrixBincell.BinaryAccessType;
import org.apache.sysds.runtime.matrix.data.LibMatrixReorg;
import org.apache.sysds.runtime.matrix.data.MatrixBlock;
import org.apache.sysds.runtime.matrix.data.MatrixIndexes;
@@ -73,6 +78,7 @@
import org.apache.sysds.runtime.matrix.operators.AggregateBinaryOperator;
import org.apache.sysds.runtime.matrix.operators.AggregateUnaryOperator;
import org.apache.sysds.runtime.matrix.operators.BinaryOperator;
+import org.apache.sysds.runtime.matrix.operators.LeftScalarOperator;
import org.apache.sysds.runtime.matrix.operators.ScalarOperator;
import org.apache.sysds.runtime.util.CommonThreadPool;
@@ -412,6 +418,42 @@
}
+ protected void binaryMV(MatrixBlock m2, CompressedMatrixBlock ret, BinaryOperator op, BinaryAccessType aType ){
+ if(aType == BinaryAccessType.MATRIX_COL_VECTOR){
+ throw new NotImplementedException("Binary Matrix Col Vector operations are not implemented CLA");
+ }else if(aType== BinaryAccessType.MATRIX_ROW_VECTOR){
+ // Apply the operation to each of the column groups.
+ // Most implementations will only modify metadata.
+ ArrayList<ColGroup> newColGroups = new ArrayList<>();
+
+ for(ColGroup grp : _colGroups) {
+ if(grp instanceof ColGroupUncompressed){
+ LOG.error("NOT HANDLING UNCOMPRESSED IN BINARY MV");
+ }else{
+
+ if(grp.getNumCols() == 1){
+ ScalarOperator sop = new LeftScalarOperator(op.fn, m2.getValue(0, grp.getColIndices()[0]),1);
+ newColGroups.add(grp.scalarOperation(sop));
+ }else{
+ throw new NotImplementedException("Cocoded columns (nr cols:" + grp.getNumCols() + ") groupType: not implemented for Binary Matrix Row Vector operations");
+ }
+ }
+ // newColGroups.add(grp.binaryMVR(m2, op));
+ }
+ ret._colGroups = newColGroups;
+ // ret.setNonZeros(rlen * clen);
+ // throw new NotImplementedException("Binary Matrix Row Vector operations are not implemented CLA");
+ }
+ }
+
+ protected void binaryVV(MatrixBlock m2, CompressedMatrixBlock ret, BinaryOperator op, BinaryAccessType aType ){
+ throw new NotImplementedException("Binary Vector Vector operations are not implemented");
+ }
+
+ protected void binaryMM(MatrixBlock m2, CompressedMatrixBlock ret, BinaryOperator op){
+ throw new NotImplementedException("Binary Matrix Matrix operations are not implemented");
+ }
+
@Override
public MatrixBlock append(MatrixBlock that, MatrixBlock ret) {
@@ -621,9 +663,6 @@
}
}
- if(LOG.isDebugEnabled())
- LOG.debug("Compressed MM in " + time.stop());
-
return ret;
}
@@ -759,6 +798,21 @@
ret.quickSetValue(i, 0, builtin.execute(ret.quickGetValue(i, 0), 0));
}
+ // special handling of mean
+ if(op.aggOp.increOp.fn instanceof Mean) {
+ if(op.indexFn instanceof ReduceAll)
+ ret.quickSetValue(0, 0, ret.quickGetValue(0, 0) / (getNumColumns() * getNumRows()));
+ else if(op.indexFn instanceof ReduceCol) {
+ for(int i = 0; i < getNumRows(); i++) {
+ ret.quickSetValue(i, 0, ret.quickGetValue(i, 0) / getNumColumns());
+ }
+ }
+ else if(op.indexFn instanceof ReduceRow)
+ for(int i = 0; i < getNumColumns(); i++) {
+ ret.quickSetValue(0, i, ret.quickGetValue(0, i) / getNumRows());
+ }
+ }
+
// drop correction if necessary
if(op.aggOp.existsCorrection() && inCP)
ret.dropLastRowsOrColumns(op.aggOp.correction);
@@ -946,7 +1000,7 @@
}
private static void rightMultByVector(List<ColGroup> groups, MatrixBlock vect, MatrixBlock ret, int rl, int ru) {
- ColGroupValue.setupThreadLocalMemory(getMaxNumValues(groups));
+ ColGroupValue.setupThreadLocalMemory(getMaxNumValues(groups).getLeft());
// boolean cacheDDC1 = ru - rl > CompressionSettings.BITMAP_BLOCK_SZ * 2;
@@ -992,6 +1046,7 @@
private static void leftMultByVectorTranspose(List<ColGroup> colGroups, MatrixBlock vector, MatrixBlock result,
boolean doTranspose, boolean allocTmp) {
// transpose vector if required
+ LOG.debug("Left Mult vector Transpose " + vector.getClass());
MatrixBlock rowVector = vector;
if(doTranspose) {
rowVector = new MatrixBlock(1, vector.getNumRows(), false);
@@ -1003,13 +1058,21 @@
result.allocateDenseBlock();
// setup memory pool for reuse
- if(allocTmp)
- ColGroupValue.setupThreadLocalMemory(getMaxNumValues(colGroups));
+ if(allocTmp){
+ Pair<Integer, List<Integer>> v = getMaxNumValues(colGroups);
+ ColGroupValue.setupThreadLocalMemory(v.getLeft());
+ for(int i = 0; i< colGroups.size(); i++){
+ colGroups.get(i).leftMultByRowVector(rowVector, result, v.getRight().get(i));
+ }
+ }
+ else
+ {
+ for(ColGroup grp : colGroups) {
+ grp.leftMultByRowVector(rowVector, result, -1);
+ }
+ }
// delegate matrix-vector operation to each column group
- for(ColGroup grp : colGroups) {
- grp.leftMultByRowVector(rowVector, result);
- }
// post-processing
if(allocTmp)
@@ -1092,7 +1155,7 @@
tmpret.allocateDenseBlock();
// setup memory pool for reuse
- ColGroupValue.setupThreadLocalMemory(getMaxNumValues(groups));
+ ColGroupValue.setupThreadLocalMemory(getMaxNumValues(groups).getLeft());
// approach: for each colgroup, extract uncompressed columns one at-a-time
// vector-matrix multiplies against remaining col groups
@@ -1154,12 +1217,19 @@
return grpParts;
}
- private static int getMaxNumValues(List<ColGroup> groups) {
+ private static Pair<Integer, List<Integer>> getMaxNumValues(List<ColGroup> groups) {
int numVals = 1;
+ List<Integer> numValues = new ArrayList<>(groups.size());
+ int nr;
for(ColGroup grp : groups)
- if(grp instanceof ColGroupValue)
- numVals = Math.max(numVals, ((ColGroupValue) grp).getNumValues());
- return numVals;
+ if(grp instanceof ColGroupValue){
+ nr = ((ColGroupValue) grp).getNumValues();
+ numValues.add(nr);
+ numVals = Math.max(numVals, nr);
+ } else{
+ numValues.add(-1);
+ }
+ return new ImmutablePair<>(numVals, numValues);
}
public boolean hasUncompressedColGroup() {
@@ -1189,10 +1259,11 @@
public Object call() {
// setup memory pool for reuse
try {
- ColGroupValue.setupThreadLocalMemory(getMaxNumValues(_groups));
- // delegate matrix-vector operation to each column group
- for(ColGroup grp : _groups)
- grp.leftMultByRowVector(_vect, _ret);
+ Pair<Integer, List<Integer>> v = getMaxNumValues(_groups);
+ ColGroupValue.setupThreadLocalMemory(v.getLeft());
+ for(int i = 0; i< _groups.size(); i++){
+ _groups.get(i).leftMultByRowVector(_vect, _ret, v.getRight().get(i));
+ }
ColGroupValue.cleanupThreadLocalMemory();
}
diff --git a/src/main/java/org/apache/sysds/runtime/compress/CompressionSettingsBuilder.java b/src/main/java/org/apache/sysds/runtime/compress/CompressionSettingsBuilder.java
index 02620d0..aea15f0 100644
--- a/src/main/java/org/apache/sysds/runtime/compress/CompressionSettingsBuilder.java
+++ b/src/main/java/org/apache/sysds/runtime/compress/CompressionSettingsBuilder.java
@@ -33,7 +33,7 @@
private double samplingRatio = 1.0;
private boolean allowSharedDictionary = false;
private boolean transposeInput = true;
- private boolean skipList = true;
+ private boolean skipList = false;
private int seed = -1;
private boolean investigateEstimate = false;
private boolean lossy = false;
diff --git a/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroup.java b/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroup.java
index a3f6781..b150a57 100644
--- a/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroup.java
+++ b/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroup.java
@@ -264,10 +264,11 @@
* Multiply the slice of the matrix that this column group represents by a row vector on the left (the original
* column vector is assumed to be transposed already i.e. its size now is 1xn).
*
- * @param vector row vector
- * @param result matrix block result
+ * @param vector row vector
+ * @param result matrix block result
+ * @param numVals The Number of values contained in the Column.
*/
- public abstract void leftMultByRowVector(MatrixBlock vector, MatrixBlock result);
+ public abstract void leftMultByRowVector(MatrixBlock vector, MatrixBlock result, int numVals);
/**
* Perform the specified scalar operation directly on the compressed column group, without decompressing individual
@@ -278,6 +279,8 @@
*/
public abstract ColGroup scalarOperation(ScalarOperator op);
+ // public abstract ColGroup binaryMVR(MatrixBlock m2, BinaryOperator op);
+
/**
* Unary Aggregate operator, since aggregate operators require new object output, the output becomes an uncompressed
* matrix.
diff --git a/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupDDC.java b/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupDDC.java
index 5116c74..a3c7487 100644
--- a/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupDDC.java
+++ b/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupDDC.java
@@ -173,9 +173,9 @@
}
}
- protected final void postScaling(double[] vals, double[] c) {
+ protected final void postScaling(double[] vals, double[] c, int numVals) {
final int ncol = getNumCols();
- final int numVals = getNumValues();
+ // final int numVals = getNumValues();
if(_dict instanceof QDictionary) {
QDictionary d = (QDictionary) _dict;
@@ -248,10 +248,10 @@
}
@Override
- public void leftMultByRowVector(MatrixBlock vector, MatrixBlock result) {
+ public void leftMultByRowVector(MatrixBlock vector, MatrixBlock result, int numVals) {
double[] a = ColGroupConverter.getDenseVector(vector);
double[] c = result.getDenseBlockValues();
- final int numVals = getNumValues();
+ numVals = (numVals == -1) ? getNumValues(): numVals;
if(8 * numVals < _numRows) {
// iterative over codes and pre-aggregate inputs per code (guaranteed <=255)
@@ -263,7 +263,7 @@
vals[index] += a[i];
}
}
- postScaling(vals, c);
+ postScaling(vals, c, numVals);
}
else {
// iterate over codes, compute all, and add to the result
diff --git a/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupOLE.java b/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupOLE.java
index 8dda7f7..e7bf0d2 100644
--- a/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupOLE.java
+++ b/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupOLE.java
@@ -379,12 +379,12 @@
}
@Override
- public void leftMultByRowVector(MatrixBlock vector, MatrixBlock result) {
+ public void leftMultByRowVector(MatrixBlock vector, MatrixBlock result, int numVals) {
double[] a = ColGroupConverter.getDenseVector(vector);
double[] c = result.getDenseBlockValues();
final int blksz = CompressionSettings.BITMAP_BLOCK_SZ;
final int numCols = getNumCols();
- final int numVals = getNumValues();
+ // final int numVals = getNumValues();
final double[] values = getValues();
if(numVals >= 1 && _numRows > blksz) {
@@ -633,7 +633,7 @@
int[] ret = allocIVector(numVals, rl == 0);
final int blksz = CompressionSettings.BITMAP_BLOCK_SZ;
- if(rl > 0) { // rl aligned with blksz
+ if(rl > 0 && _skipList != null) { // rl aligned with blksz
int rskip = (_numRows / 2 / blksz) * blksz;
for(int k = 0; k < numVals; k++) {
diff --git a/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupRLE.java b/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupRLE.java
index 315e3e7..b27ec8e 100644
--- a/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupRLE.java
+++ b/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupRLE.java
@@ -358,11 +358,11 @@
}
@Override
- public void leftMultByRowVector(MatrixBlock vector, MatrixBlock result) {
+ public void leftMultByRowVector(MatrixBlock vector, MatrixBlock result, int numVals) {
double[] a = ColGroupConverter.getDenseVector(vector);
double[] c = result.getDenseBlockValues();
final int numCols = getNumCols();
- final int numVals = getNumValues();
+ // final int numVals = getNumValues();
final double[] values = getValues();
if(numVals >= 1 && _numRows > CompressionSettings.BITMAP_BLOCK_SZ) {
diff --git a/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupUncompressed.java b/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupUncompressed.java
index db6d4d0..74660a1 100644
--- a/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupUncompressed.java
+++ b/src/main/java/org/apache/sysds/runtime/compress/colgroup/ColGroupUncompressed.java
@@ -274,7 +274,7 @@
}
@Override
- public void leftMultByRowVector(MatrixBlock vector, MatrixBlock result) {
+ public void leftMultByRowVector(MatrixBlock vector, MatrixBlock result, int numVals) {
MatrixBlock pret = new MatrixBlock(1, _colIndexes.length, false);
LibMatrixMult.matrixMult(vector, _data, pret);
@@ -292,18 +292,18 @@
// throw new NotImplementedException();
// }
- public void leftMultByRowVector(MatrixBlock vector, MatrixBlock result, int k) {
- MatrixBlock pret = new MatrixBlock(1, _colIndexes.length, false);
- LibMatrixMult.matrixMult(vector, _data, pret, k);
+ // public void leftMultByRowVector(MatrixBlock vector, MatrixBlock result) {
+ // MatrixBlock pret = new MatrixBlock(1, _colIndexes.length, false);
+ // LibMatrixMult.matrixMult(vector, _data, pret, k);
- // copying partialResult to the proper indices of the result
- if(!pret.isEmptyBlock(false)) {
- double[] rsltArr = result.getDenseBlockValues();
- for(int colIx = 0; colIx < _colIndexes.length; colIx++)
- rsltArr[_colIndexes[colIx]] = pret.quickGetValue(0, colIx);
- result.recomputeNonZeros();
- }
- }
+ // // copying partialResult to the proper indices of the result
+ // if(!pret.isEmptyBlock(false)) {
+ // double[] rsltArr = result.getDenseBlockValues();
+ // for(int colIx = 0; colIx < _colIndexes.length; colIx++)
+ // rsltArr[_colIndexes[colIx]] = pret.quickGetValue(0, colIx);
+ // result.recomputeNonZeros();
+ // }
+ // }
@Override
public ColGroup scalarOperation(ScalarOperator op) {
diff --git a/src/main/java/org/apache/sysds/runtime/controlprogram/parfor/opt/CostEstimatorHops.java b/src/main/java/org/apache/sysds/runtime/controlprogram/parfor/opt/CostEstimatorHops.java
index eb70d0c..2d68ef2 100644
--- a/src/main/java/org/apache/sysds/runtime/controlprogram/parfor/opt/CostEstimatorHops.java
+++ b/src/main/java/org/apache/sysds/runtime/controlprogram/parfor/opt/CostEstimatorHops.java
@@ -31,6 +31,7 @@
public class CostEstimatorHops extends CostEstimator
{
+
public static final double DEFAULT_MEM_SP = 20*1024*1024;
private OptTreePlanMappingAbstract _map = null;