// @java.file.header
/* _________ _____ __________________ _____
* __ ____/___________(_)______ /__ ____/______ ____(_)_______
* _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
* / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
* \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
*/
/*
* 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.ignite.ml.math.impls.matrix;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.internal.util.IgniteUtils;
import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.ml.math.Matrix;
import org.apache.ignite.ml.math.StorageConstants;
import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
import org.apache.ignite.ml.math.impls.MathTestConstants;
import org.apache.ignite.ml.math.impls.storage.matrix.SparseDistributedMatrixStorage;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.apache.ignite.testframework.junits.common.GridCommonTest;
import static org.apache.ignite.ml.math.impls.MathTestConstants.UNEXPECTED_VAL;
/**
* Tests for {@link SparseDistributedMatrix}.
*/
@GridCommonTest(group = "Distributed Models")
public class SparseDistributedMatrixTest extends GridCommonAbstractTest {
/** Number of nodes in grid */
private static final int NODE_COUNT = 3;
/** Cache name. */
private static final String CACHE_NAME = "test-cache";
/** Precision. */
private static final double PRECISION = 0.0;
/** Grid instance. */
private Ignite ignite;
/** Matrix rows */
private final int rows = MathTestConstants.STORAGE_SIZE;
/** Matrix cols */
private final int cols = MathTestConstants.STORAGE_SIZE;
/** Matrix for tests */
private SparseDistributedMatrix cacheMatrix;
/**
* Default constructor.
*/
public SparseDistributedMatrixTest() {
super(false);
}
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
for (int i = 1; i <= NODE_COUNT; i++)
startGrid(i);
}
/** {@inheritDoc} */
@Override protected void afterTestsStopped() throws Exception {
stopAllGrids();
}
/**
* {@inheritDoc}
*/
@Override protected void beforeTest() throws Exception {
ignite = grid(NODE_COUNT);
ignite.configuration().setPeerClassLoadingEnabled(true);
}
/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
ignite.destroyCache(CACHE_NAME);
if (cacheMatrix != null) {
cacheMatrix.destroy();
cacheMatrix = null;
}
}
/** */
public void testGetSet() throws Exception {
IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
cacheMatrix = new SparseDistributedMatrix(rows, cols, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
double v = Math.random();
cacheMatrix.set(i, j, v);
assertEquals("Unexpected value for matrix element["+ i +" " + j + "]", v, cacheMatrix.get(i, j), PRECISION);
}
}
}
/** */
public void testExternalize() throws IOException, ClassNotFoundException {
IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
cacheMatrix = new SparseDistributedMatrix(rows, cols, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
cacheMatrix.set(1, 1, 1.0);
ByteArrayOutputStream byteArrOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objOutputStream = new ObjectOutputStream(byteArrOutputStream);
objOutputStream.writeObject(cacheMatrix);
ByteArrayInputStream byteArrInputStream = new ByteArrayInputStream(byteArrOutputStream.toByteArray());
ObjectInputStream objInputStream = new ObjectInputStream(byteArrInputStream);
SparseDistributedMatrix objRestored = (SparseDistributedMatrix)objInputStream.readObject();
assertTrue(MathTestConstants.VAL_NOT_EQUALS, cacheMatrix.equals(objRestored));
assertEquals(MathTestConstants.VAL_NOT_EQUALS, objRestored.get(1, 1), 1.0, PRECISION);
}
/** Test simple math. */
public void testMath() {
IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
cacheMatrix = new SparseDistributedMatrix(rows, cols, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
initMtx(cacheMatrix);
cacheMatrix.assign(2.0);
for (int i = 0; i < cacheMatrix.rowSize(); i++)
for (int j = 0; j < cacheMatrix.columnSize(); j++)
assertEquals(UNEXPECTED_VAL, 2.0, cacheMatrix.get(i, j), PRECISION);
cacheMatrix.plus(3.0);
for (int i = 0; i < cacheMatrix.rowSize(); i++)
for (int j = 0; j < cacheMatrix.columnSize(); j++)
assertEquals(UNEXPECTED_VAL, 5.0, cacheMatrix.get(i, j), PRECISION);
cacheMatrix.times(2.0);
for (int i = 0; i < cacheMatrix.rowSize(); i++)
for (int j = 0; j < cacheMatrix.columnSize(); j++)
assertEquals(UNEXPECTED_VAL, 10.0, cacheMatrix.get(i, j), PRECISION);
cacheMatrix.divide(10.0);
for (int i = 0; i < cacheMatrix.rowSize(); i++)
for (int j = 0; j < cacheMatrix.columnSize(); j++)
assertEquals(UNEXPECTED_VAL, 1.0, cacheMatrix.get(i, j), PRECISION);
assertEquals(UNEXPECTED_VAL, cacheMatrix.rowSize() * cacheMatrix.columnSize(), cacheMatrix.sum(), PRECISION);
}
/** */
public void testMinMax() {
IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
cacheMatrix = new SparseDistributedMatrix(rows, cols, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
for (int i = 0; i < cacheMatrix.rowSize(); i++)
for (int j = 0; j < cacheMatrix.columnSize(); j++)
cacheMatrix.set(i, j, i * cols + j + 1);
assertEquals(UNEXPECTED_VAL, 1.0, cacheMatrix.minValue(), PRECISION);
assertEquals(UNEXPECTED_VAL, rows * cols, cacheMatrix.maxValue(), PRECISION);
for (int i = 0; i < cacheMatrix.rowSize(); i++)
for (int j = 0; j < cacheMatrix.columnSize(); j++)
cacheMatrix.set(i, j, -1.0 * (i * cols + j + 1));
assertEquals(UNEXPECTED_VAL, -rows * cols, cacheMatrix.minValue(), PRECISION);
assertEquals(UNEXPECTED_VAL, -1.0, cacheMatrix.maxValue(), PRECISION);
for (int i = 0; i < cacheMatrix.rowSize(); i++)
for (int j = 0; j < cacheMatrix.columnSize(); j++)
cacheMatrix.set(i, j, i * cols + j);
assertEquals(UNEXPECTED_VAL, 1.0, cacheMatrix.minValue(), PRECISION);
assertEquals(UNEXPECTED_VAL, rows * cols - 1.0, cacheMatrix.maxValue(), PRECISION);
}
/** */
public void testMap() {
IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
cacheMatrix = new SparseDistributedMatrix(rows, cols, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
initMtx(cacheMatrix);
cacheMatrix.map(i -> 100.0);
for (int i = 0; i < cacheMatrix.rowSize(); i++)
for (int j = 0; j < cacheMatrix.columnSize(); j++)
assertEquals(UNEXPECTED_VAL, 100.0, cacheMatrix.get(i, j), PRECISION);
}
/** */
public void testCopy() {
IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
cacheMatrix = new SparseDistributedMatrix(rows, cols, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
try {
cacheMatrix.copy();
fail("UnsupportedOperationException expected.");
}
catch (UnsupportedOperationException e) {
return;
}
fail("UnsupportedOperationException expected.");
}
/** */
public void testCacheBehaviour(){
IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
SparseDistributedMatrix cacheMatrix1 = new SparseDistributedMatrix(rows, cols, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
SparseDistributedMatrix cacheMatrix2 = new SparseDistributedMatrix(rows, cols, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
initMtx(cacheMatrix1);
initMtx(cacheMatrix2);
Collection<String> cacheNames = ignite.cacheNames();
assert cacheNames.contains(SparseDistributedMatrixStorage.ML_CACHE_NAME);
IgniteCache<IgniteBiTuple<Integer, IgniteUuid>, Object> cache = ignite.getOrCreateCache(SparseDistributedMatrixStorage.ML_CACHE_NAME);
Set<IgniteBiTuple<Integer, IgniteUuid>> keySet1 = buildKeySet(cacheMatrix1);
Set<IgniteBiTuple<Integer, IgniteUuid>> keySet2 = buildKeySet(cacheMatrix2);
assert cache.containsKeys(keySet1);
assert cache.containsKeys(keySet2);
cacheMatrix2.destroy();
assert cache.containsKeys(keySet1);
assert !cache.containsKeys(keySet2);
cacheMatrix1.destroy();
assert !cache.containsKeys(keySet1);
}
/** */
public void testLike() {
IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
cacheMatrix = new SparseDistributedMatrix(rows, cols, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
assertNotNull(cacheMatrix.like(1, 1));
}
/** */
public void testLikeVector() {
IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
cacheMatrix = new SparseDistributedMatrix(rows, cols, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
try {
cacheMatrix.likeVector(1);
fail("UnsupportedOperationException expected.");
}
catch (UnsupportedOperationException e) {
return;
}
fail("UnsupportedOperationException expected.");
}
/** */
private void initMtx(Matrix m) {
for (int i = 0; i < m.rowSize(); i++)
for (int j = 0; j < m.columnSize(); j++)
m.set(i, j, 1.0);
}
/** Build key set for SparseDistributedMatrix. */
private Set<IgniteBiTuple<Integer, IgniteUuid>> buildKeySet(SparseDistributedMatrix m){
Set<IgniteBiTuple<Integer, IgniteUuid>> set = new HashSet<>();
SparseDistributedMatrixStorage storage = (SparseDistributedMatrixStorage)m.getStorage();
IgniteUuid uuid = storage.getUUID();
int size = storage.storageMode() == StorageConstants.ROW_STORAGE_MODE ? storage.rowSize() : storage.columnSize();
for (int i = 0; i < size; i++)
set.add(new IgniteBiTuple<>(i, uuid));
return set;
}
}