Repository: systemml Updated Branches: refs/heads/master db0207900 -> f296f8f51
[SYSTEMML-2479] Extended sampling-based sparsity estimator, misc fixes Closes #828. Project: http://git-wip-us.apache.org/repos/asf/systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/f296f8f5 Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/f296f8f5 Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/f296f8f5 Branch: refs/heads/master Commit: f296f8f51e990ad6c2c3db9f9e5b2fc8e8108611 Parents: db02079 Author: Johanna Sommer <joha...@mail-sommer.com> Authored: Tue Aug 14 23:19:11 2018 -0700 Committer: Matthias Boehm <mboe...@gmail.com> Committed: Tue Aug 14 23:19:19 2018 -0700 ---------------------------------------------------------------------- .../sysml/hops/estim/EstimatorBitsetMM.java | 2 +- .../sysml/hops/estim/EstimatorDensityMap.java | 2 +- .../hops/estim/EstimatorMatrixHistogram.java | 26 +++--- .../sysml/hops/estim/EstimatorSample.java | 96 +++++++++++++++++--- .../instructions/gpu/DnnGPUInstruction.java | 2 +- .../functions/estim/OpElemWTest.java | 37 +++----- .../functions/estim/SquaredProductTest.java | 2 +- .../functions/estim/ZPackageSuite.java | 2 + 8 files changed, 117 insertions(+), 52 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/systemml/blob/f296f8f5/src/main/java/org/apache/sysml/hops/estim/EstimatorBitsetMM.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/estim/EstimatorBitsetMM.java b/src/main/java/org/apache/sysml/hops/estim/EstimatorBitsetMM.java index 16a8a3a..aacbf29 100644 --- a/src/main/java/org/apache/sysml/hops/estim/EstimatorBitsetMM.java +++ b/src/main/java/org/apache/sysml/hops/estim/EstimatorBitsetMM.java @@ -50,7 +50,7 @@ public class EstimatorBitsetMM extends SparsityEstimator if (!root.getLeft().isLeaf()) estim(root.getLeft()); // obtain synopsis if (!root.getRight().isLeaf()) - estim(root.getLeft()); // obtain synopsis + estim(root.getRight()); // obtain synopsis BitsetMatrix m1Map = !root.getLeft().isLeaf() ? (BitsetMatrix) root.getLeft().getSynopsis() : new BitsetMatrix1(root.getLeft().getData()); BitsetMatrix m2Map = !root.getRight().isLeaf() ? (BitsetMatrix) root.getRight().getSynopsis() : http://git-wip-us.apache.org/repos/asf/systemml/blob/f296f8f5/src/main/java/org/apache/sysml/hops/estim/EstimatorDensityMap.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/estim/EstimatorDensityMap.java b/src/main/java/org/apache/sysml/hops/estim/EstimatorDensityMap.java index b6fca0f..3206ab6 100644 --- a/src/main/java/org/apache/sysml/hops/estim/EstimatorDensityMap.java +++ b/src/main/java/org/apache/sysml/hops/estim/EstimatorDensityMap.java @@ -58,7 +58,7 @@ public class EstimatorDensityMap extends SparsityEstimator if( !root.getLeft().isLeaf() ) estim(root.getLeft()); //obtain synopsis if( !root.getRight().isLeaf() ) - estim(root.getLeft()); //obtain synopsis + estim(root.getRight()); //obtain synopsis DensityMap m1Map = !root.getLeft().isLeaf() ? (DensityMap)root.getLeft().getSynopsis() : new DensityMap(root.getLeft().getData(), _b); http://git-wip-us.apache.org/repos/asf/systemml/blob/f296f8f5/src/main/java/org/apache/sysml/hops/estim/EstimatorMatrixHistogram.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/estim/EstimatorMatrixHistogram.java b/src/main/java/org/apache/sysml/hops/estim/EstimatorMatrixHistogram.java index 26b3df0..cd4b397 100644 --- a/src/main/java/org/apache/sysml/hops/estim/EstimatorMatrixHistogram.java +++ b/src/main/java/org/apache/sysml/hops/estim/EstimatorMatrixHistogram.java @@ -58,7 +58,7 @@ public class EstimatorMatrixHistogram extends SparsityEstimator if( !root.getLeft().isLeaf() ) estim(root.getLeft()); //obtain synopsis if( !root.getRight().isLeaf() ) - estim(root.getLeft()); //obtain synopsis + estim(root.getRight()); //obtain synopsis MatrixHistogram h1 = !root.getLeft().isLeaf() ? (MatrixHistogram)root.getLeft().getSynopsis() : new MatrixHistogram(root.getLeft().getData(), _useExcepts); @@ -105,21 +105,21 @@ public class EstimatorMatrixHistogram extends SparsityEstimator case MM: return estimInternMM(h1, h2); case MULT: { - final long N1 = h1.getNonZeros(); - final long N2 = h2.getNonZeros(); + final double N1 = h1.getNonZeros(); + final double N2 = h2.getNonZeros(); final long scale = IntStream.range(0, h1.getCols()) .mapToLong(j -> (long)h1.cNnz[j] * h2.cNnz[j]).sum(); return IntStream.range(0, h1.getRows()) - .mapToLong(i -> (long)h1.rNnz[i] * h2.rNnz[i] * scale / N1 / N2) //collisions + .mapToDouble(i -> (long)h1.rNnz[i] * h2.rNnz[i] * scale / N1 / N2) //collisions .sum() / msize; } case PLUS: { - final long N1 = h1.getNonZeros(); - final long N2 = h2.getNonZeros(); + final double N1 = h1.getNonZeros(); + final double N2 = h2.getNonZeros(); final long scale = IntStream.range(0, h1.getCols()) .mapToLong(j -> (long)h1.cNnz[j] * h2.cNnz[j]).sum(); return IntStream.range(0, h1.getRows()) - .mapToLong(i -> (long)h1.rNnz[i] + h2.rNnz[i] //all minus collisions + .mapToDouble(i -> (long)h1.rNnz[i] + h2.rNnz[i] //all minus collisions - (long)h1.rNnz[i] * h2.rNnz[i] * scale / N1 / N2) .sum() / msize; } @@ -356,12 +356,12 @@ public class EstimatorMatrixHistogram extends SparsityEstimator } private static MatrixHistogram deriveMultHistogram(MatrixHistogram h1, MatrixHistogram h2) { - final long N1 = h1.getNonZeros(); - final long N2 = h2.getNonZeros(); - final long scaler = IntStream.range(0, h1.getCols()) - .mapToLong(j -> (long)h1.cNnz[j] * h2.cNnz[j]).sum(); - final long scalec = IntStream.range(0, h1.getRows()) - .mapToLong(j -> (long)h1.rNnz[j] * h2.rNnz[j]).sum(); + final double N1 = h1.getNonZeros(); + final double N2 = h2.getNonZeros(); + final double scaler = IntStream.range(0, h1.getCols()) + .mapToDouble(j -> (long)h1.cNnz[j] * h2.cNnz[j]).sum(); + final double scalec = IntStream.range(0, h1.getRows()) + .mapToDouble(j -> (long)h1.rNnz[j] * h2.rNnz[j]).sum(); int rMaxNnz = 0, cMaxNnz = 0; Random rn = new Random(); int[] rNnz = new int[h1.getRows()]; http://git-wip-us.apache.org/repos/asf/systemml/blob/f296f8f5/src/main/java/org/apache/sysml/hops/estim/EstimatorSample.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/estim/EstimatorSample.java b/src/main/java/org/apache/sysml/hops/estim/EstimatorSample.java index 1df23dd..faf7d0e 100644 --- a/src/main/java/org/apache/sysml/hops/estim/EstimatorSample.java +++ b/src/main/java/org/apache/sysml/hops/estim/EstimatorSample.java @@ -63,27 +63,89 @@ public class EstimatorSample extends SparsityEstimator @Override public double estim(MatrixBlock m1, MatrixBlock m2) { - //get sampled indexes - int k = m1.getNumColumns(); - int[] ix = UtilFunctions.getSortedSampleIndexes( - k, (int)Math.max(k*_frac, 1)); - //compute output sparsity - int[] cnnz = computeColumnNnz(m1, ix); - long nnzOut = 0; - for(int i=0; i<ix.length; i++) - nnzOut = Math.max(nnzOut, cnnz[i] * m2.recomputeNonZeros(ix[i], ix[i])); - return OptimizerUtils.getSparsity( - m1.getNumRows(), m2.getNumColumns(), nnzOut); + return estim(m1, m2, OpCode.MM); } @Override public double estim(MatrixBlock m1, MatrixBlock m2, OpCode op) { - throw new NotImplementedException(); + switch(op) { + case MM: { + int k = m1.getNumColumns(); + int[] ix = UtilFunctions.getSortedSampleIndexes( + k, (int)Math.max(k*_frac, 1)); + int[] cnnz = computeColumnNnz(m1, ix); + long nnzOut = 0; + for(int i=0; i<ix.length; i++) + nnzOut = Math.max(nnzOut, cnnz[i] * m2.recomputeNonZeros(ix[i], ix[i])); + return OptimizerUtils.getSparsity( + m1.getNumRows(), m2.getNumColumns(), nnzOut); + } + case MULT: { + int k = Math.max(m1.getNumColumns(), m1.getNumRows()); + int[] ix = UtilFunctions.getSortedSampleIndexes( + k, (int)Math.max(k*_frac, 1)); + double spOut = 0; + if( m1.getNumColumns() > m1.getNumRows() ) { + int[] cnnz1 = computeColumnNnz(m1, ix); + int[] cnnz2 = computeColumnNnz(m2, ix); + for(int i=0; i<ix.length; i++) + spOut += (double)cnnz1[i]/m1.getNumRows() + * (double)cnnz2[i]/m1.getNumRows(); + } + else { + int[] rnnz1 = computeRowNnz(m1, ix); + int[] rnnz2 = computeRowNnz(m2, ix); + for(int i=0; i<ix.length; i++) + spOut += (double)rnnz1[i]/m1.getNumColumns() + * (double)rnnz2[i]/m1.getNumColumns(); + } + return spOut/ix.length; + } + case PLUS: { + int k = Math.max(m1.getNumColumns(), m1.getNumRows()); + int[] ix = UtilFunctions.getSortedSampleIndexes( + k, (int)Math.max(k*_frac, 1)); + double spOut = 0; + if( m1.getNumColumns() > m1.getNumRows() ) { + int[] cnnz1 = computeColumnNnz(m1, ix); + int[] cnnz2 = computeColumnNnz(m2, ix); + for(int i=0; i<ix.length; i++) { + spOut += (double)cnnz1[i]/m1.getNumRows() + + (double)cnnz2[i]/m1.getNumRows() + - (double)cnnz1[i]/m1.getNumRows() + * (double)cnnz2[i]/m1.getNumRows(); + } + } + else { + int[] rnnz1 = computeRowNnz(m1, ix); + int[] rnnz2 = computeRowNnz(m2, ix); + for(int i=0; i<ix.length; i++) { + spOut += (double)rnnz1[i]/m1.getNumColumns() + + (double)rnnz2[i]/m1.getNumColumns() + - (double)rnnz1[i]/m1.getNumColumns() + * (double)rnnz2[i]/m1.getNumColumns(); + } + } + return spOut/ix.length; + } + case RBIND: + case CBIND: + case EQZERO: + case NEQZERO: + case TRANS: + case DIAG: + case RESHAPE: + MatrixCharacteristics mc1 = m1.getMatrixCharacteristics(); + MatrixCharacteristics mc2 = m2.getMatrixCharacteristics(); + return OptimizerUtils.getSparsity(estimExactMetaData(mc1, mc2, op)); + default: + throw new NotImplementedException(); + } } @Override public double estim(MatrixBlock m, OpCode op) { - throw new NotImplementedException(); + return estim(m, null, op); } private int[] computeColumnNnz(MatrixBlock in, int[] ix) { @@ -113,4 +175,12 @@ public class EstimatorSample extends SparsityEstimator ret[i] = nnz[ix[i]]; return ret; } + + private int[] computeRowNnz(MatrixBlock in, int[] ix) { + //copy nnz into reduced vector + int[] ret = new int[ix.length]; + for(int i=0; i<ix.length; i++) + ret[i] = (int) in.recomputeNonZeros(ix[i], ix[i]); + return ret; + } } http://git-wip-us.apache.org/repos/asf/systemml/blob/f296f8f5/src/main/java/org/apache/sysml/runtime/instructions/gpu/DnnGPUInstruction.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/gpu/DnnGPUInstruction.java b/src/main/java/org/apache/sysml/runtime/instructions/gpu/DnnGPUInstruction.java index 8d89032..e774dcd 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/gpu/DnnGPUInstruction.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/gpu/DnnGPUInstruction.java @@ -577,7 +577,7 @@ public class DnnGPUInstruction extends GPUInstruction { } private void processNesterovUpdateInstruction(ExecutionContext ec) { - GPUStatistics.incrementNoOfExecutedGPUInst();; + GPUStatistics.incrementNoOfExecutedGPUInst(); MatrixObject input = getMatrixInputForGPUInstruction(ec, _input1.getName()); MatrixObject v = getMatrixInputForGPUInstruction(ec, _input2.getName()); MatrixObject v_prev = getMatrixInputForGPUInstruction(ec, _input3.getName()); http://git-wip-us.apache.org/repos/asf/systemml/blob/f296f8f5/src/test/java/org/apache/sysml/test/integration/functions/estim/OpElemWTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/sysml/test/integration/functions/estim/OpElemWTest.java b/src/test/java/org/apache/sysml/test/integration/functions/estim/OpElemWTest.java index 7867f26..69a7325 100644 --- a/src/test/java/org/apache/sysml/test/integration/functions/estim/OpElemWTest.java +++ b/src/test/java/org/apache/sysml/test/integration/functions/estim/OpElemWTest.java @@ -27,6 +27,7 @@ import org.apache.sysml.hops.estim.EstimatorBasicWorst; import org.apache.sysml.hops.estim.EstimatorBitsetMM; import org.apache.sysml.hops.estim.EstimatorDensityMap; import org.apache.sysml.hops.estim.EstimatorMatrixHistogram; +import org.apache.sysml.hops.estim.EstimatorSample; import org.apache.sysml.hops.estim.SparsityEstimator; import org.apache.sysml.hops.estim.SparsityEstimator.OpCode; import org.apache.sysml.runtime.functionobjects.Multiply; @@ -42,16 +43,9 @@ public class OpElemWTest extends AutomatedTestBase { private final static int m = 1600; private final static int n = 700; - private final static double[] sparsity = new double[]{0.1, 0.04}; + private final static double[] sparsity = new double[]{0.2, 0.4}; private final static OpCode mult = OpCode.MULT; private final static OpCode plus = OpCode.PLUS; -// private final static OpCode rbind = OpCode.RBIND; -// private final static OpCode cbind = OpCode.CBIND; -// private final static OpCode eqzero = OpCode.EQZERO; -// private final static OpCode diag = OpCode.DIAG; -// private final static OpCode neqzero = OpCode.NEQZERO; -// private final static OpCode trans = OpCode.TRANS; -// private final static OpCode reshape = OpCode.RESHAPE; @Override public void setUp() { @@ -103,12 +97,12 @@ public class OpElemWTest extends AutomatedTestBase //Bitset @Test - public void testBitsetCasemult() { + public void testBitsetMult() { runSparsityEstimateTest(new EstimatorBitsetMM(), m, n, sparsity, mult); } @Test - public void testBitsetCaseplus() { + public void testBitsetPlus() { runSparsityEstimateTest(new EstimatorBitsetMM(), m, n, sparsity, plus); } /* @@ -117,23 +111,22 @@ public class OpElemWTest extends AutomatedTestBase public void testLGCasemult() { runSparsityEstimateTest(new EstimatorLayeredGraph(), m, k, n, sparsity, mult); } - + @Test public void testLGCaseplus() { runSparsityEstimateTest(new EstimatorLayeredGraph(), m, k, n, sparsity, plus); - } + }*/ //Sample @Test - public void testSampleCasemult() { - runSparsityEstimateTest(new EstimatorSample(), m, k, n, sparsity, mult); + public void testSampleMult() { + runSparsityEstimateTest(new EstimatorSample(), m, n, sparsity, mult); } - - @Test - public void testSampleCaseplus() { - runSparsityEstimateTest(new EstimatorSample(), m, k, n, sparsity, plus); - }*/ + @Test + public void testSamplePlus() { + runSparsityEstimateTest(new EstimatorSample(), m, n, sparsity, plus); + } private void runSparsityEstimateTest(SparsityEstimator estim, int m, int n, double[] sp, OpCode op) { MatrixBlock m1 = MatrixBlock.randOperations(m, n, sp[0], 1, 1, "uniform", 3); @@ -146,20 +139,20 @@ public class OpElemWTest extends AutomatedTestBase bOp = new BinaryOperator(Multiply.getMultiplyFnObject()); m1.binaryOperations(bOp, m2, m3); est = estim.estim(m1, m2, op); - System.out.println(m3.getSparsity()); System.out.println(est); + System.out.println(m3.getSparsity()); break; case PLUS: bOp = new BinaryOperator(Plus.getPlusFnObject()); m1.binaryOperations(bOp, m2, m3); est = estim.estim(m1, m2, op); - System.out.println(m3.getSparsity()); System.out.println(est); + System.out.println(m3.getSparsity()); break; default: throw new NotImplementedException(); } //compare estimated and real sparsity - TestUtils.compareScalars(est, m3.getSparsity(), (estim instanceof EstimatorBasicWorst) ? 5e-1 : 1e-3); + TestUtils.compareScalars(est, m3.getSparsity(), (estim instanceof EstimatorBasicWorst) ? 5e-1 : 5e-3); } } http://git-wip-us.apache.org/repos/asf/systemml/blob/f296f8f5/src/test/java/org/apache/sysml/test/integration/functions/estim/SquaredProductTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/sysml/test/integration/functions/estim/SquaredProductTest.java b/src/test/java/org/apache/sysml/test/integration/functions/estim/SquaredProductTest.java index 917764b..cd423af 100644 --- a/src/test/java/org/apache/sysml/test/integration/functions/estim/SquaredProductTest.java +++ b/src/test/java/org/apache/sysml/test/integration/functions/estim/SquaredProductTest.java @@ -146,7 +146,7 @@ public class SquaredProductTest extends AutomatedTestBase private void runSparsityEstimateTest(SparsityEstimator estim, int m, int k, int n, double[] sp) { MatrixBlock m1 = MatrixBlock.randOperations(m, k, sp[0], 1, 1, "uniform", 3); - MatrixBlock m2 = MatrixBlock.randOperations(k, n, sp[1], 1, 1, "uniform", 3); + MatrixBlock m2 = MatrixBlock.randOperations(k, n, sp[1], 1, 1, "uniform", 7); MatrixBlock m3 = m1.aggregateBinaryOperations(m1, m2, new MatrixBlock(), InstructionUtils.getMatMultOperator(1)); http://git-wip-us.apache.org/repos/asf/systemml/blob/f296f8f5/src/test_suites/java/org/apache/sysml/test/integration/functions/estim/ZPackageSuite.java ---------------------------------------------------------------------- diff --git a/src/test_suites/java/org/apache/sysml/test/integration/functions/estim/ZPackageSuite.java b/src/test_suites/java/org/apache/sysml/test/integration/functions/estim/ZPackageSuite.java index 2760063..3cf152b 100644 --- a/src/test_suites/java/org/apache/sysml/test/integration/functions/estim/ZPackageSuite.java +++ b/src/test_suites/java/org/apache/sysml/test/integration/functions/estim/ZPackageSuite.java @@ -26,7 +26,9 @@ import org.junit.runners.Suite; * won't run two of them at once. */ @RunWith(Suite.class) @Suite.SuiteClasses({ + OpBindChainTest.class, OpBindTest.class, + OpElemWChainTest.class, OpElemWTest.class, OpSingleTest.class, OuterProductTest.class,