blob: c4bc715ffc87de9cc8c869ee0c5f2512c5da09d3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sysds.test.component.compress.offset;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.math3.util.Precision;
import org.apache.sysds.runtime.compress.colgroup.offset.AOffset;
import org.apache.sysds.runtime.compress.colgroup.offset.OffsetFactory.OFF_TYPE;
import org.apache.sysds.runtime.data.SparseBlock;
import org.apache.sysds.runtime.matrix.data.MatrixBlock;
import org.apache.sysds.test.TestUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(value = Parameterized.class)
public abstract class OffsetTestPreAggregateSparse {
protected static final Log LOG = LogFactory.getLog(OffsetTestPreAggregateSparse.class.getName());
protected static final double eps = 0.00001;
protected final int[] data;
protected final AOffset a;
protected final MatrixBlock leftM;
// sum of indexes row 1.
protected final double[] s;
@Parameters
public static Collection<Object[]> data() {
ArrayList<Object[]> tests = new ArrayList<>();
// It is assumed that the input is in sorted order, all values are positive and there are no duplicates.
// note that each tests allocate an matrix of two rows, and the last value length.
// therefore don't make it to large.
for(OFF_TYPE t : OFF_TYPE.values()) {
tests.add(new Object[] {new int[] {1, 2}, t});
tests.add(new Object[] {new int[] {2, 142}, t});
tests.add(new Object[] {new int[] {142, 421}, t});
tests.add(new Object[] {new int[] {1, 1023}, t});
tests.add(new Object[] {new int[] {1023, 1024}, t});
tests.add(new Object[] {new int[] {1023}, t});
tests.add(new Object[] {new int[] {0, 1, 2, 3, 4, 5}, t});
tests.add(new Object[] {new int[] {0}, t});
tests.add(new Object[] {new int[] {500}, t});
tests.add(new Object[] {new int[] {1442}, t});
tests.add(new Object[] {new int[] {0, 256}, t});
tests.add(new Object[] {new int[] {0, 254}, t});
tests.add(new Object[] {new int[] {0, 256 * 2}, t});
tests.add(new Object[] {new int[] {0, 255 * 2}, t});
tests.add(new Object[] {new int[] {0, 254 * 2}, t});
tests.add(new Object[] {new int[] {0, 510, 765}, t});
tests.add(new Object[] {new int[] {0, 254 * 3}, t});
tests.add(new Object[] {new int[] {0, 255, 255 * 2, 255 * 3}, t});
tests.add(new Object[] {new int[] {0, 255 * 2, 255 * 3}, t});
tests.add(new Object[] {new int[] {0, 255 * 2, 255 * 3, 255 * 10}, t});
tests.add(new Object[] {new int[] {0, 255 * 3}, t});
tests.add(new Object[] {new int[] {0, 255 * 4}, t});
tests.add(new Object[] {new int[] {0, 256 * 3}, t});
tests.add(new Object[] {new int[] {255 * 3, 255 * 5}, t});
tests.add(new Object[] {new int[] {0, 1, 2, 3, 255 * 4, 1500}, t});
tests.add(new Object[] {new int[] {0, 1, 2, 3, 4, 5}, t});
tests.add(new Object[] {new int[] {0, 1, 2, 3, 4, 5, 125, 142, 161, 1661, 2314}, t});
tests.add(new Object[] {new int[] {4, 6, 11, 14, 24, 34, 38, 40, 43, 46, 47, 52, 53, 64, 69, 70, 71, 72, 76,
77, 80, 83, 94, 109, 112, 114, 125, 133, 138, 142, 144, 147, 158, 159, 162, 167, 171, 177, 186, 198, 203,
204, 207, 209, 212, 219, 221, 224, 225, 227, 229, 231, 234, 242, 252, 253, 255, 257, 263, 271, 276, 277,
288, 296, 297, 300, 306, 313, 320, 321, 336, 358, 365, 385, 387, 391, 397, 399, 408, 414, 416, 417, 419,
425, 429, 438, 441, 445, 459, 477, 482, 483, 499}, t});
}
return tests;
}
public OffsetTestPreAggregateSparse(int[] data, OFF_TYPE type) {
this.data = data;
this.a = OffsetTestUtil.getOffset(data, type);
this.leftM = TestUtils.generateTestMatrixBlock(2, data[data.length - 1] + 100, 100, 200, 0.35, 23152);
this.s = sumIndexes();
}
@Test
public void preAggByteMapFirstRow() {
preAggMapRow(0);
}
@Test
public void preAggByteMapSecondRow() {
preAggMapRow(1);
}
protected abstract void preAggMapRow(int row);
protected void verifyPreAggMapRow(double[] preAV, int row) {
if(preAV[0] != s[row]) {
fail("\nThe preaggregate result is not the sum! : " + a.getClass().getSimpleName() + " " + preAV[0] + " vs "
+ s[row] + "\n full agg: " + Arrays.toString(preAV));
}
}
@Test(expected = NotImplementedException.class)
public abstract void preAggMapAllRows();
protected void verifyPreAggMapAllRow(double[] preAV) {
if(preAV[1] != 0)
fail("\naggregate to wrong index");
if(preAV[3] != 0)
fail("\naggregate to wrong index");
if(!Precision.equals(preAV[0], s[0], eps))
fail("\nThe preaggregate result is not the sum!: " + preAV[0] + "vs" + s[0]);
if(!Precision.equals(preAV[2], s[1], eps))
fail("\nThe preaggregate result is not the sum!: " + preAV[2] + "vs" + s[1]);
}
private final double[] sumIndexes() {
double[] ret = new double[leftM.getNumRows()];
SparseBlock sb = leftM.getSparseBlock();
for(int j = 0; j < leftM.getNumRows(); j++) {
if(sb.isEmpty(j))
continue;
final int apos = sb.pos(j);
final int alen = sb.size(j) + apos;
final int[] aix = sb.indexes(j);
final double[] avals = sb.values(j);
int dx = 0;
for(int i = apos; i < alen && dx < data.length; i++) {
while(dx < data.length && data[dx] < aix[i])
dx++;
if(dx < data.length && data[dx] == aix[i])
ret[j] += avals[i];
}
}
return ret;
}
}