You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/08/25 08:39:53 UTC

[11/18] ignite git commit: ignite-5280 SparseDistributedMatrix refactoring

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/CacheUtils.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/CacheUtils.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/CacheUtils.java
deleted file mode 100644
index 2c519f0..0000000
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/CacheUtils.java
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * 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;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.function.BinaryOperator;
-import javax.cache.Cache;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.cache.affinity.Affinity;
-import org.apache.ignite.cache.query.ScanQuery;
-import org.apache.ignite.cluster.ClusterGroup;
-import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.internal.processors.cache.CacheEntryImpl;
-import org.apache.ignite.internal.util.typedef.internal.A;
-import org.apache.ignite.lang.IgniteBiTuple;
-import org.apache.ignite.lang.IgniteCallable;
-import org.apache.ignite.lang.IgnitePredicate;
-import org.apache.ignite.lang.IgniteRunnable;
-import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.ml.math.KeyMapper;
-import org.apache.ignite.ml.math.ValueMapper;
-import org.apache.ignite.ml.math.functions.IgniteBiFunction;
-import org.apache.ignite.ml.math.functions.IgniteConsumer;
-import org.apache.ignite.ml.math.functions.IgniteDoubleFunction;
-import org.apache.ignite.ml.math.functions.IgniteFunction;
-import org.apache.ignite.ml.math.impls.matrix.BlockEntry;
-import org.apache.ignite.ml.math.impls.storage.matrix.BlockMatrixKey;
-
-/**
- * Distribution-related misc. support.
- *
- * TODO: IGNITE-5102, fix sparse key filters.
- */
-public class CacheUtils {
-    /**
-     * Cache entry support.
-     *
-     * @param <K>
-     * @param <V>
-     */
-    public static class CacheEntry<K, V> {
-        /** */
-        private Cache.Entry<K, V> entry;
-        /** */
-        private IgniteCache<K, V> cache;
-
-        /**
-         * @param entry Original cache entry.
-         * @param cache Cache instance.
-         */
-        CacheEntry(Cache.Entry<K, V> entry, IgniteCache<K, V> cache) {
-            this.entry = entry;
-            this.cache = cache;
-        }
-
-        /**
-         *
-         *
-         */
-        public Cache.Entry<K, V> entry() {
-            return entry;
-        }
-
-        /**
-         *
-         *
-         */
-        public IgniteCache<K, V> cache() {
-            return cache;
-        }
-    }
-
-    /**
-     * Gets local Ignite instance.
-     */
-    public static Ignite ignite() {
-        return Ignition.localIgnite();
-    }
-
-    /**
-     * @param cacheName Cache name.
-     * @param k Key into the cache.
-     * @param <K> Key type.
-     * @return Cluster group for given key.
-     */
-    public static <K> ClusterGroup groupForKey(String cacheName, K k) {
-        return ignite().cluster().forNode(ignite().affinity(cacheName).mapKeyToNode(k));
-    }
-
-    /**
-     * @param cacheName Cache name.
-     * @param keyMapper {@link KeyMapper} to validate cache key.
-     * @param valMapper {@link ValueMapper} to obtain double value for given cache key.
-     * @param <K> Cache key object type.
-     * @param <V> Cache value object type.
-     * @return Sum of the values obtained for valid keys.
-     */
-    public static <K, V> double sum(String cacheName, KeyMapper<K> keyMapper, ValueMapper<V> valMapper) {
-        Collection<Double> subSums = fold(cacheName, (CacheEntry<K, V> ce, Double acc) -> {
-            if (keyMapper.isValid(ce.entry().getKey())) {
-                double v = valMapper.toDouble(ce.entry().getValue());
-
-                return acc == null ? v : acc + v;
-            }
-            else
-                return acc;
-        });
-
-        return sum(subSums);
-    }
-
-    /**
-     * @param matrixUuid Matrix UUID.
-     * @return Sum obtained using sparse logic.
-     */
-    @SuppressWarnings("unchecked")
-    public static <K, V> double sparseSum(IgniteUuid matrixUuid, String cacheName) {
-        A.notNull(matrixUuid, "matrixUuid");
-        A.notNull(cacheName, "cacheName");
-
-        Collection<Double> subSums = fold(cacheName, (CacheEntry<K, V> ce, Double acc) -> {
-            V v = ce.entry().getValue();
-
-            double sum = 0.0;
-
-            if (v instanceof Map) {
-                Map<Integer, Double> map = (Map<Integer, Double>)v;
-
-                sum = sum(map.values());
-            }
-            else if (v instanceof BlockEntry) {
-                BlockEntry be = (BlockEntry)v;
-
-                sum = be.sum();
-            }
-            else
-                throw new UnsupportedOperationException();
-
-            return acc == null ? sum : acc + sum;
-        }, key -> {
-            if (key instanceof BlockMatrixKey)
-                return ((BlockMatrixKey)key).matrixId().equals(matrixUuid);
-            else if (key instanceof IgniteBiTuple)
-                return ((IgniteBiTuple<Integer, IgniteUuid>)key).get2().equals(matrixUuid);
-            else
-                throw new UnsupportedOperationException();
-        });
-
-        return sum(subSums);
-    }
-
-    /**
-     * @param c {@link Collection} of double values to sum.
-     * @return Sum of the values.
-     */
-    private static double sum(Collection<Double> c) {
-        double sum = 0.0;
-
-        for (double d : c)
-            sum += d;
-
-        return sum;
-    }
-
-    /**
-     * @param cacheName Cache name.
-     * @param keyMapper {@link KeyMapper} to validate cache key.
-     * @param valMapper {@link ValueMapper} to obtain double value for given cache key.
-     * @param <K> Cache key object type.
-     * @param <V> Cache value object type.
-     * @return Minimum value for valid keys.
-     */
-    public static <K, V> double min(String cacheName, KeyMapper<K> keyMapper, ValueMapper<V> valMapper) {
-        Collection<Double> mins = fold(cacheName, (CacheEntry<K, V> ce, Double acc) -> {
-            if (keyMapper.isValid(ce.entry().getKey())) {
-                double v = valMapper.toDouble(ce.entry().getValue());
-
-                if (acc == null)
-                    return v;
-                else
-                    return Math.min(acc, v);
-            }
-            else
-                return acc;
-        });
-
-        return Collections.min(mins);
-    }
-
-    /**
-     * @param matrixUuid Matrix UUID.
-     * @return Minimum value obtained using sparse logic.
-     */
-    @SuppressWarnings("unchecked")
-    public static <K, V> double sparseMin(IgniteUuid matrixUuid, String cacheName) {
-        A.notNull(matrixUuid, "matrixUuid");
-        A.notNull(cacheName, "cacheName");
-
-        Collection<Double> mins = fold(cacheName, (CacheEntry<K, V> ce, Double acc) -> {
-            V v = ce.entry().getValue();
-
-            double min;
-
-            if (v instanceof Map) {
-                Map<Integer, Double> map = (Map<Integer, Double>)v;
-
-                min = Collections.min(map.values());
-            }
-            else if (v instanceof BlockEntry) {
-                BlockEntry be = (BlockEntry)v;
-
-                min = be.minValue();
-            }
-            else
-                throw new UnsupportedOperationException();
-
-            if (acc == null)
-                return min;
-            else
-                return Math.min(acc, min);
-
-        }, key -> {
-            if (key instanceof BlockMatrixKey)
-                return ((BlockMatrixKey)key).matrixId().equals(matrixUuid);
-            else if (key instanceof IgniteBiTuple)
-                return ((IgniteBiTuple<Integer, IgniteUuid>)key).get2().equals(matrixUuid);
-            else
-                throw new UnsupportedOperationException();
-        });
-
-        return Collections.min(mins);
-    }
-
-    /**
-     * @param matrixUuid Matrix UUID.
-     * @return Maximum value obtained using sparse logic.
-     */
-    @SuppressWarnings("unchecked")
-    public static <K, V> double sparseMax(IgniteUuid matrixUuid, String cacheName) {
-        A.notNull(matrixUuid, "matrixUuid");
-        A.notNull(cacheName, "cacheName");
-
-        Collection<Double> maxes = fold(cacheName, (CacheEntry<K, V> ce, Double acc) -> {
-            V v = ce.entry().getValue();
-
-            double max;
-
-            if (v instanceof Map) {
-                Map<Integer, Double> map = (Map<Integer, Double>)v;
-
-                max = Collections.max(map.values());
-            }
-            else if (v instanceof BlockEntry) {
-                BlockEntry be = (BlockEntry)v;
-
-                max = be.maxValue();
-            }
-            else
-                throw new UnsupportedOperationException();
-
-            if (acc == null)
-                return max;
-            else
-                return Math.max(acc, max);
-
-        }, key -> {
-            if (key instanceof BlockMatrixKey)
-                return ((BlockMatrixKey)key).matrixId().equals(matrixUuid);
-            else if (key instanceof IgniteBiTuple)
-                return ((IgniteBiTuple<Integer, IgniteUuid>)key).get2().equals(matrixUuid);
-            else
-                throw new UnsupportedOperationException();
-        });
-
-        return Collections.max(maxes);
-    }
-
-    /**
-     * @param cacheName Cache name.
-     * @param keyMapper {@link KeyMapper} to validate cache key.
-     * @param valMapper {@link ValueMapper} to obtain double value for given cache key.
-     * @param <K> Cache key object type.
-     * @param <V> Cache value object type.
-     * @return Maximum value for valid keys.
-     */
-    public static <K, V> double max(String cacheName, KeyMapper<K> keyMapper, ValueMapper<V> valMapper) {
-        Collection<Double> maxes = fold(cacheName, (CacheEntry<K, V> ce, Double acc) -> {
-            if (keyMapper.isValid(ce.entry().getKey())) {
-                double v = valMapper.toDouble(ce.entry().getValue());
-
-                if (acc == null)
-                    return v;
-                else
-                    return Math.max(acc, v);
-            }
-            else
-                return acc;
-        });
-
-        return Collections.max(maxes);
-    }
-
-    /**
-     * @param cacheName Cache name.
-     * @param keyMapper {@link KeyMapper} to validate cache key.
-     * @param valMapper {@link ValueMapper} to obtain double value for given cache key.
-     * @param mapper Mapping {@link IgniteFunction}.
-     * @param <K> Cache key object type.
-     * @param <V> Cache value object type.
-     */
-    public static <K, V> void map(String cacheName, KeyMapper<K> keyMapper, ValueMapper<V> valMapper,
-        IgniteFunction<Double, Double> mapper) {
-        foreach(cacheName, (CacheEntry<K, V> ce) -> {
-            K k = ce.entry().getKey();
-
-            if (keyMapper.isValid(k))
-                // Actual assignment.
-                ce.cache().put(k, valMapper.fromDouble(mapper.apply(valMapper.toDouble(ce.entry().getValue()))));
-        });
-    }
-
-    /**
-     * @param matrixUuid Matrix UUID.
-     * @param mapper Mapping {@link IgniteFunction}.
-     */
-    @SuppressWarnings("unchecked")
-    public static <K, V> void sparseMap(IgniteUuid matrixUuid, IgniteDoubleFunction<Double> mapper, String cacheName) {
-        A.notNull(matrixUuid, "matrixUuid");
-        A.notNull(cacheName, "cacheName");
-        A.notNull(mapper, "mapper");
-
-        foreach(cacheName, (CacheEntry<K, V> ce) -> {
-            K k = ce.entry().getKey();
-
-            V v = ce.entry().getValue();
-
-            if (v instanceof Map) {
-                Map<Integer, Double> map = (Map<Integer, Double>)v;
-
-                for (Map.Entry<Integer, Double> e : (map.entrySet()))
-                    e.setValue(mapper.apply(e.getValue()));
-
-            }
-            else if (v instanceof BlockEntry) {
-                BlockEntry be = (BlockEntry)v;
-
-                be.map(mapper);
-            }
-            else
-                throw new UnsupportedOperationException();
-
-            ce.cache().put(k, v);
-        }, key -> {
-            if (key instanceof BlockMatrixKey)
-                return ((BlockMatrixKey)key).matrixId().equals(matrixUuid);
-            else if (key instanceof IgniteBiTuple)
-                return ((IgniteBiTuple<Integer, IgniteUuid>)key).get2().equals(matrixUuid);
-            else
-                throw new UnsupportedOperationException();
-        });
-    }
-
-    /**
-     * @param cacheName Cache name.
-     * @param fun An operation that accepts a cache entry and processes it.
-     * @param <K> Cache key object type.
-     * @param <V> Cache value object type.
-     */
-    public static <K, V> void foreach(String cacheName, IgniteConsumer<CacheEntry<K, V>> fun) {
-        foreach(cacheName, fun, null);
-    }
-
-    /**
-     * @param cacheName Cache name.
-     * @param fun An operation that accepts a cache entry and processes it.
-     * @param keyFilter Cache keys filter.
-     * @param <K> Cache key object type.
-     * @param <V> Cache value object type.
-     */
-    public static <K, V> void foreach(String cacheName, IgniteConsumer<CacheEntry<K, V>> fun,
-        IgnitePredicate<K> keyFilter) {
-        bcast(cacheName, () -> {
-            Ignite ignite = Ignition.localIgnite();
-            IgniteCache<K, V> cache = ignite.getOrCreateCache(cacheName);
-
-            int partsCnt = ignite.affinity(cacheName).partitions();
-
-            // Use affinity in filter for scan query. Otherwise we accept consumer in each node which is wrong.
-            Affinity affinity = ignite.affinity(cacheName);
-            ClusterNode locNode = ignite.cluster().localNode();
-
-            // Iterate over all partitions. Some of them will be stored on that local node.
-            for (int part = 0; part < partsCnt; part++) {
-                int p = part;
-
-                // Iterate over given partition.
-                // Query returns an empty cursor if this partition is not stored on this node.
-                for (Cache.Entry<K, V> entry : cache.query(new ScanQuery<K, V>(part, (k, v) -> affinity.mapPartitionToNode(p) == locNode && (keyFilter == null || keyFilter.apply(k)))))
-                    fun.accept(new CacheEntry<>(entry, cache));
-            }
-        });
-    }
-
-    /**
-     * <b>Currently fold supports only commutative operations.<b/>
-     *
-     * @param cacheName Cache name.
-     * @param folder Fold function operating over cache entries.
-     * @param <K> Cache key object type.
-     * @param <V> Cache value object type.
-     * @param <A> Fold result type.
-     * @return Fold operation result.
-     */
-    public static <K, V, A> Collection<A> fold(String cacheName, IgniteBiFunction<CacheEntry<K, V>, A, A> folder) {
-        return fold(cacheName, folder, null);
-    }
-
-    /**
-     * <b>Currently fold supports only commutative operations.<b/>
-     *
-     * @param cacheName Cache name.
-     * @param folder Fold function operating over cache entries.
-     * @param <K> Cache key object type.
-     * @param <V> Cache value object type.
-     * @param <A> Fold result type.
-     * @return Fold operation result.
-     */
-    public static <K, V, A> Collection<A> fold(String cacheName, IgniteBiFunction<CacheEntry<K, V>, A, A> folder,
-        IgnitePredicate<K> keyFilter) {
-        return bcast(cacheName, () -> {
-            Ignite ignite = Ignition.localIgnite();
-            IgniteCache<K, V> cache = ignite.getOrCreateCache(cacheName);
-
-            int partsCnt = ignite.affinity(cacheName).partitions();
-
-            // Use affinity in filter for ScanQuery. Otherwise we accept consumer in each node which is wrong.
-            Affinity affinity = ignite.affinity(cacheName);
-            ClusterNode locNode = ignite.cluster().localNode();
-
-            A a = null;
-
-            // Iterate over all partitions. Some of them will be stored on that local node.
-            for (int part = 0; part < partsCnt; part++) {
-                int p = part;
-
-                // Iterate over given partition.
-                // Query returns an empty cursor if this partition is not stored on this node.
-                for (Cache.Entry<K, V> entry : cache.query(new ScanQuery<K, V>(part,
-                    (k, v) -> affinity.mapPartitionToNode(p) == locNode && (keyFilter == null || keyFilter.apply(k)))))
-                    a = folder.apply(new CacheEntry<>(entry, cache), a);
-            }
-
-            return a;
-        });
-    }
-
-    /**
-     * Distributed version of fold operation.
-     *
-     * @param cacheName Cache name.
-     * @param folder Folder.
-     * @param keyFilter Key filter.
-     * @param accumulator Accumulator.
-     * @param zeroVal Zero value.
-     */
-    public static <K, V, A> A distributedFold(String cacheName, IgniteBiFunction<Cache.Entry<K, V>, A, A> folder,
-        IgnitePredicate<K> keyFilter, BinaryOperator<A> accumulator, A zeroVal) {
-        return sparseFold(cacheName, folder, keyFilter, accumulator, zeroVal, null, null, 0,
-            false);
-    }
-
-    /**
-     * Sparse version of fold. This method also applicable to sparse zeroes.
-     *
-     * @param cacheName Cache name.
-     * @param folder Folder.
-     * @param keyFilter Key filter.
-     * @param accumulator Accumulator.
-     * @param zeroVal Zero value.
-     * @param defVal Def value.
-     * @param defKey Def key.
-     * @param defValCnt Def value count.
-     * @param isNilpotent Is nilpotent.
-     */
-    private static <K, V, A> A sparseFold(String cacheName, IgniteBiFunction<Cache.Entry<K, V>, A, A> folder,
-        IgnitePredicate<K> keyFilter, BinaryOperator<A> accumulator, A zeroVal, V defVal, K defKey, long defValCnt,
-        boolean isNilpotent) {
-
-        A defRes = zeroVal;
-
-        if (!isNilpotent)
-            for (int i = 0; i < defValCnt; i++)
-                defRes = folder.apply(new CacheEntryImpl<>(defKey, defVal), defRes);
-
-        Collection<A> totalRes = bcast(cacheName, () -> {
-            Ignite ignite = Ignition.localIgnite();
-            IgniteCache<K, V> cache = ignite.getOrCreateCache(cacheName);
-
-            int partsCnt = ignite.affinity(cacheName).partitions();
-
-            // Use affinity in filter for ScanQuery. Otherwise we accept consumer in each node which is wrong.
-            Affinity affinity = ignite.affinity(cacheName);
-            ClusterNode locNode = ignite.cluster().localNode();
-
-            A a = zeroVal;
-
-            // Iterate over all partitions. Some of them will be stored on that local node.
-            for (int part = 0; part < partsCnt; part++) {
-                int p = part;
-
-                // Iterate over given partition.
-                // Query returns an empty cursor if this partition is not stored on this node.
-                for (Cache.Entry<K, V> entry : cache.query(new ScanQuery<K, V>(part,
-                    (k, v) -> affinity.mapPartitionToNode(p) == locNode && (keyFilter == null || keyFilter.apply(k)))))
-                    a = folder.apply(entry, a);
-            }
-
-            return a;
-        });
-        totalRes.add(defRes);
-        return totalRes.stream().reduce(zeroVal, accumulator);
-    }
-
-    /**
-     * @param cacheName Cache name.
-     * @param run {@link Runnable} to broadcast to cache nodes for given cache name.
-     */
-    public static void bcast(String cacheName, IgniteRunnable run) {
-        ignite().compute(ignite().cluster().forCacheNodes(cacheName)).broadcast(run);
-    }
-
-    /**
-     * @param cacheName Cache name.
-     * @param call {@link IgniteCallable} to broadcast to cache nodes for given cache name.
-     * @param <A> Type returned by the callable.
-     */
-    public static <A> Collection<A> bcast(String cacheName, IgniteCallable<A> call) {
-        return ignite().compute(ignite().cluster().forCacheNodes(cacheName)).broadcast(call);
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/CacheMatrix.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/CacheMatrix.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/CacheMatrix.java
index 7f00bcb..1f832bc 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/CacheMatrix.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/CacheMatrix.java
@@ -19,13 +19,13 @@ package org.apache.ignite.ml.math.impls.matrix;
 
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.ml.math.Matrix;
-import org.apache.ignite.ml.math.MatrixKeyMapper;
-import org.apache.ignite.ml.math.ValueMapper;
 import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.distributed.CacheUtils;
+import org.apache.ignite.ml.math.distributed.MatrixKeyMapper;
+import org.apache.ignite.ml.math.distributed.ValueMapper;
 import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
 import org.apache.ignite.ml.math.functions.IgniteDoubleFunction;
 import org.apache.ignite.ml.math.functions.IgniteFunction;
-import org.apache.ignite.ml.math.impls.CacheUtils;
 import org.apache.ignite.ml.math.impls.storage.matrix.CacheMatrixStorage;
 
 /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/DenseLocalOnHeapMatrix.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/DenseLocalOnHeapMatrix.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/DenseLocalOnHeapMatrix.java
index 393fff6..2376cbd 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/DenseLocalOnHeapMatrix.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/DenseLocalOnHeapMatrix.java
@@ -126,8 +126,8 @@ public class DenseLocalOnHeapMatrix extends AbstractMatrix implements OrderedMat
         return new DenseLocalOnHeapVector(crd);
     }
 
-    /** */
+    /** {@inheritDoc} */
     @Override public int accessMode() {
-        return ((ArrayMatrixStorage)getStorage()).accessMode();
+        return getStorage().accessMode();
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/SparseBlockDistributedMatrix.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/SparseBlockDistributedMatrix.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/SparseBlockDistributedMatrix.java
index b3481f9..1dcf1d8 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/SparseBlockDistributedMatrix.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/SparseBlockDistributedMatrix.java
@@ -29,11 +29,11 @@ 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.Vector;
+import org.apache.ignite.ml.math.distributed.CacheUtils;
+import org.apache.ignite.ml.math.distributed.keys.impl.BlockMatrixKey;
 import org.apache.ignite.ml.math.exceptions.CardinalityException;
 import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
 import org.apache.ignite.ml.math.functions.IgniteDoubleFunction;
-import org.apache.ignite.ml.math.impls.CacheUtils;
-import org.apache.ignite.ml.math.impls.storage.matrix.BlockMatrixKey;
 import org.apache.ignite.ml.math.impls.storage.matrix.BlockMatrixStorage;
 
 /**
@@ -101,10 +101,10 @@ public class SparseBlockDistributedMatrix extends AbstractMatrix implements Stor
         SparseBlockDistributedMatrix matrixA = this;
         SparseBlockDistributedMatrix matrixB = (SparseBlockDistributedMatrix)mtx;
 
-        String cacheName = BlockMatrixStorage.ML_BLOCK_CACHE_NAME;
+        String cacheName = this.storage().cacheName();
         SparseBlockDistributedMatrix matrixC = new SparseBlockDistributedMatrix(matrixA.rowSize(), matrixB.columnSize());
 
-        CacheUtils.bcast(BlockMatrixStorage.ML_BLOCK_CACHE_NAME, () -> {
+        CacheUtils.bcast(cacheName, () -> {
             Ignite ignite = Ignition.localIgnite();
             Affinity affinity = ignite.affinity(cacheName);
 
@@ -156,17 +156,17 @@ public class SparseBlockDistributedMatrix extends AbstractMatrix implements Stor
 
     /** {@inheritDoc} */
     @Override public double sum() {
-        return CacheUtils.sparseSum(getUUID(), BlockMatrixStorage.ML_BLOCK_CACHE_NAME);
+        return CacheUtils.sparseSum(getUUID(), this.storage().cacheName());
     }
 
     /** {@inheritDoc} */
     @Override public double maxValue() {
-        return CacheUtils.sparseMax(getUUID(), BlockMatrixStorage.ML_BLOCK_CACHE_NAME);
+        return CacheUtils.sparseMax(getUUID(), this.storage().cacheName());
     }
 
     /** {@inheritDoc} */
     @Override public double minValue() {
-        return CacheUtils.sparseMin(getUUID(), BlockMatrixStorage.ML_BLOCK_CACHE_NAME);
+        return CacheUtils.sparseMin(getUUID(), this.storage().cacheName());
     }
 
     /** {@inheritDoc} */
@@ -194,7 +194,7 @@ public class SparseBlockDistributedMatrix extends AbstractMatrix implements Stor
      * @return Matrix with mapped values.
      */
     private Matrix mapOverValues(IgniteDoubleFunction<Double> mapper) {
-        CacheUtils.sparseMap(getUUID(), mapper, BlockMatrixStorage.ML_BLOCK_CACHE_NAME);
+        CacheUtils.sparseMap(getUUID(), mapper, this.storage().cacheName());
 
         return this;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedMatrix.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedMatrix.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedMatrix.java
index a3a7df4..92d7c39 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedMatrix.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedMatrix.java
@@ -17,14 +17,22 @@
 
 package org.apache.ignite.ml.math.impls.matrix;
 
+import java.util.Collection;
+import java.util.Map;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.cache.affinity.Affinity;
+import org.apache.ignite.cluster.ClusterNode;
 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.Vector;
+import org.apache.ignite.ml.math.distributed.CacheUtils;
+import org.apache.ignite.ml.math.distributed.keys.RowColMatrixKey;
 import org.apache.ignite.ml.math.exceptions.CardinalityException;
 import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
 import org.apache.ignite.ml.math.functions.IgniteDoubleFunction;
-import org.apache.ignite.ml.math.impls.CacheUtils;
 import org.apache.ignite.ml.math.impls.storage.matrix.SparseDistributedMatrixStorage;
 
 /**
@@ -93,32 +101,63 @@ public class SparseDistributedMatrix extends AbstractMatrix implements StorageCo
         return mapOverValues(v -> v * x);
     }
 
-    /**
-     * TODO: IGNITE-5114, tmp naive implementation, WIP.
-     */
+
+    /** {@inheritDoc} */
     @Override public Matrix times(Matrix mtx) {
-        int cols = columnSize();
+        if (mtx == null)
+            throw new IllegalArgumentException("The matrix should be not null.");
+
+        if (columnSize() != mtx.rowSize())
+            throw new CardinalityException(columnSize(), mtx.rowSize());
+
+        SparseDistributedMatrix matrixA = this;
+        SparseDistributedMatrix matrixB = (SparseDistributedMatrix)mtx;
+
+        String cacheName = storage().cacheName();
+        SparseDistributedMatrix matrixC = new SparseDistributedMatrix(matrixA.rowSize(), matrixB.columnSize()
+            , getStorage().storageMode(), getStorage().isRandomAccess() ? RANDOM_ACCESS_MODE : SEQUENTIAL_ACCESS_MODE);
+
+        CacheUtils.bcast(cacheName, () -> {
+            Ignite ignite = Ignition.localIgnite();
+            Affinity affinity = ignite.affinity(cacheName);
+
+            IgniteCache<RowColMatrixKey, BlockEntry> cache = ignite.getOrCreateCache(cacheName);
+            ClusterNode locNode = ignite.cluster().localNode();
 
-        if (cols != mtx.rowSize())
-            throw new CardinalityException(cols, mtx.rowSize());
+            SparseDistributedMatrixStorage storageC = matrixC.storage();
 
-        int rows = rowSize();
+            Map<ClusterNode, Collection<RowColMatrixKey>> keysCToNodes = affinity.mapKeysToNodes(storageC.getAllKeys());
+            Collection<RowColMatrixKey> locKeys = keysCToNodes.get(locNode);
 
-        int mtxCols = mtx.columnSize();
+            boolean isRowMode = storageC.storageMode() == ROW_STORAGE_MODE;
 
-        Matrix res = like(rows, mtxCols);
+            if (locKeys == null)
+                return;
 
-        for (int x = 0; x < rows; x++)
-            for (int y = 0; y < mtxCols; y++) {
-                double sum = 0.0;
+            // compute Cij locally on each node
+            // TODO: IGNITE:5114, exec in parallel
+            locKeys.forEach(key -> {
+                int idx = key.index();
+                
+                if (isRowMode){
+                    Vector Aik = matrixA.getCol(idx);
 
-                for (int k = 0; k < cols; k++)
-                    sum += getX(x, k) * mtx.getX(k, y);
+                    for (int i = 0; i < columnSize(); i++) {
+                        Vector Bkj = matrixB.getRow(i);
+                        matrixC.set(idx, i, Aik.times(Bkj).sum());
+                    }
+                } else {
+                    Vector Bkj = matrixB.getRow(idx);
 
-                res.setX(x, y, sum);
-            }
+                    for (int i = 0; i < rowSize(); i++) {
+                        Vector Aik = matrixA.getCol(i);
+                        matrixC.set(idx, i, Aik.times(Bkj).sum());
+                    }
+                }
+            });
+        });
 
-        return res;
+        return matrixC;
     }
 
     /** {@inheritDoc} */
@@ -136,24 +175,24 @@ public class SparseDistributedMatrix extends AbstractMatrix implements StorageCo
      * @return Matrix with mapped values.
      */
     private Matrix mapOverValues(IgniteDoubleFunction<Double> mapper) {
-        CacheUtils.sparseMap(getUUID(), mapper, SparseDistributedMatrixStorage.ML_CACHE_NAME);
+        CacheUtils.sparseMap(getUUID(), mapper, storage().cacheName());
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public double sum() {
-        return CacheUtils.sparseSum(getUUID(), SparseDistributedMatrixStorage.ML_CACHE_NAME);
+        return CacheUtils.sparseSum(getUUID(), storage().cacheName());
     }
 
     /** {@inheritDoc} */
     @Override public double maxValue() {
-        return CacheUtils.sparseMax(getUUID(), SparseDistributedMatrixStorage.ML_CACHE_NAME);
+        return CacheUtils.sparseMax(getUUID(), storage().cacheName());
     }
 
     /** {@inheritDoc} */
     @Override public double minValue() {
-        return CacheUtils.sparseMin(getUUID(), SparseDistributedMatrixStorage.ML_CACHE_NAME);
+        return CacheUtils.sparseMin(getUUID(), storage().cacheName());
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BaseBlockMatrixKey.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BaseBlockMatrixKey.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BaseBlockMatrixKey.java
deleted file mode 100644
index 74ddfe5..0000000
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BaseBlockMatrixKey.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.storage.matrix;
-
-import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.ml.math.impls.matrix.SparseBlockDistributedMatrix;
-
-/**
- * Cache key for blocks in {@link SparseBlockDistributedMatrix}.
- */
-public interface BaseBlockMatrixKey {
-    /**
-     * @return block id.
-     */
-    public long blockId();
-
-    /**
-     * @return matrix id.
-     */
-    public IgniteUuid matrixId();
-
-    /**
-     * @return key affinity key.
-     */
-    public IgniteUuid affinityKey();
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BlockMatrixKey.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BlockMatrixKey.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BlockMatrixKey.java
deleted file mode 100644
index 3749f44..0000000
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BlockMatrixKey.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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.storage.matrix;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import org.apache.ignite.binary.BinaryObjectException;
-import org.apache.ignite.binary.BinaryRawReader;
-import org.apache.ignite.binary.BinaryRawWriter;
-import org.apache.ignite.binary.BinaryReader;
-import org.apache.ignite.binary.BinaryWriter;
-import org.apache.ignite.binary.Binarylizable;
-import org.apache.ignite.internal.binary.BinaryUtils;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.ml.math.impls.matrix.BlockEntry;
-import org.apache.ignite.ml.math.impls.matrix.SparseBlockDistributedMatrix;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Key implementation for {@link BlockEntry} using for {@link SparseBlockDistributedMatrix}.
- */
-public class BlockMatrixKey implements BaseBlockMatrixKey, Externalizable, Binarylizable {
-    /** */
-    private static final long serialVersionUID = 0L;
-    /** Block ID */
-    private long blockId;
-    /** Matrix ID */
-    private IgniteUuid matrixUuid;
-    /** Block affinity key. */
-    private IgniteUuid affinityKey;
-
-    /**
-     * Empty constructor required for {@link Externalizable}.
-     */
-    public BlockMatrixKey() {
-        // No-op.
-    }
-
-    /**
-     * Construct matrix block key.
-     *
-     * @param blockId Block id.
-     * @param matrixUuid Matrix uuid.
-     * @param affinityKey Affinity key.
-     */
-    public BlockMatrixKey(long blockId, IgniteUuid matrixUuid, @Nullable IgniteUuid affinityKey) {
-        assert blockId >= 0;
-        assert matrixUuid != null;
-
-        this.blockId = blockId;
-        this.matrixUuid = matrixUuid;
-        this.affinityKey = affinityKey;
-    }
-
-    /** {@inheritDoc} */
-    @Override public long blockId() {
-        return blockId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public IgniteUuid matrixId() {
-        return matrixUuid;
-    }
-
-    /** {@inheritDoc} */
-    @Override public IgniteUuid affinityKey() {
-        return affinityKey;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void writeExternal(ObjectOutput out) throws IOException {
-        U.writeGridUuid(out, matrixUuid);
-        U.writeGridUuid(out, affinityKey);
-        out.writeLong(blockId);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        matrixUuid = U.readGridUuid(in);
-        affinityKey = U.readGridUuid(in);
-        blockId = in.readLong();
-    }
-
-    /** {@inheritDoc} */
-    @Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
-        BinaryRawWriter out = writer.rawWriter();
-
-        BinaryUtils.writeIgniteUuid(out, matrixUuid);
-        BinaryUtils.writeIgniteUuid(out, affinityKey);
-        out.writeLong(blockId);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
-        BinaryRawReader in = reader.rawReader();
-
-        matrixUuid = BinaryUtils.readIgniteUuid(in);
-        affinityKey = BinaryUtils.readIgniteUuid(in);
-        blockId = in.readLong();
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        return matrixUuid.hashCode() + (int)(blockId ^ (blockId >>> 32));
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object obj) {
-        if (obj == this)
-            return true;
-
-        if (obj == null || obj.getClass() != getClass())
-            return false;
-
-        BlockMatrixKey that = (BlockMatrixKey)obj;
-
-        return blockId == that.blockId && matrixUuid.equals(that.matrixUuid) && F.eq(affinityKey, that.affinityKey);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return S.toString(BlockMatrixKey.class, this);
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BlockMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BlockMatrixStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BlockMatrixStorage.java
index 979f223..0f285c2 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BlockMatrixStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/BlockMatrixStorage.java
@@ -20,7 +20,7 @@ package org.apache.ignite.ml.math.impls.storage.matrix;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
-import java.util.Collection;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
@@ -37,7 +37,9 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.ml.math.MatrixStorage;
 import org.apache.ignite.ml.math.StorageConstants;
-import org.apache.ignite.ml.math.impls.CacheUtils;
+import org.apache.ignite.ml.math.distributed.CacheUtils;
+import org.apache.ignite.ml.math.distributed.DistributedStorage;
+import org.apache.ignite.ml.math.distributed.keys.impl.BlockMatrixKey;
 import org.apache.ignite.ml.math.impls.matrix.BlockEntry;
 import org.apache.ignite.ml.math.impls.matrix.SparseBlockDistributedMatrix;
 
@@ -46,9 +48,9 @@ import static org.apache.ignite.ml.math.impls.matrix.BlockEntry.MAX_BLOCK_SIZE;
 /**
  * Storage for {@link SparseBlockDistributedMatrix}.
  */
-public class BlockMatrixStorage extends CacheUtils implements MatrixStorage, StorageConstants {
+public class BlockMatrixStorage extends CacheUtils implements MatrixStorage, StorageConstants, DistributedStorage<BlockMatrixKey> {
     /** Cache name used for all instances of {@link BlockMatrixStorage}. */
-    public static final String ML_BLOCK_CACHE_NAME = "ML_BLOCK_SPARSE_MATRICES_CONTAINER";
+    private static final String CACHE_NAME = "ML_BLOCK_SPARSE_MATRICES_CONTAINER";
     /** */
     private int blocksInCol;
     /** */
@@ -129,6 +131,11 @@ public class BlockMatrixStorage extends CacheUtils implements MatrixStorage, Sto
     }
 
     /** {@inheritDoc} */
+    @Override public int accessMode() {
+        return RANDOM_ACCESS_MODE;
+    }
+
+    /** {@inheritDoc} */
     @Override public void writeExternal(ObjectOutput out) throws IOException {
         out.writeInt(rows);
         out.writeInt(cols);
@@ -256,12 +263,10 @@ public class BlockMatrixStorage extends CacheUtils implements MatrixStorage, Sto
         return getColForBlock(locBlock);
     }
 
-    /**
-     * Build a keyset for this matrix storage.
-     */
-    public Collection<BlockMatrixKey> getAllKeys() {
+    /** {@inheritDoc} */
+    @Override public Set<BlockMatrixKey> getAllKeys() {
         long maxBlockId = numberOfBlocks();
-        Collection<BlockMatrixKey> keys = new LinkedList<>();
+        Set<BlockMatrixKey> keys = new HashSet<>();
 
         for (long id = 0; id < maxBlockId; id++)
             keys.add(getCacheKey(id));
@@ -269,6 +274,11 @@ public class BlockMatrixStorage extends CacheUtils implements MatrixStorage, Sto
         return keys;
     }
 
+    /** {@inheritDoc} */
+    @Override public String cacheName() {
+        return CACHE_NAME;
+    }
+
     /** */
     private List<BlockEntry> getRowForBlock(long blockId) {
         List<BlockEntry> res = new LinkedList<>();
@@ -348,8 +358,8 @@ public class BlockMatrixStorage extends CacheUtils implements MatrixStorage, Sto
     private void matrixSet(int a, int b, double v) {
         long id = getBlockId(a, b);
         // Remote set on the primary node (where given row or column is stored locally).
-        ignite().compute(groupForKey(ML_BLOCK_CACHE_NAME, id)).run(() -> {
-            IgniteCache<BlockMatrixKey, BlockEntry> cache = Ignition.localIgnite().getOrCreateCache(ML_BLOCK_CACHE_NAME);
+        ignite().compute(groupForKey(CACHE_NAME, id)).run(() -> {
+            IgniteCache<BlockMatrixKey, BlockEntry> cache = Ignition.localIgnite().getOrCreateCache(CACHE_NAME);
 
             BlockMatrixKey key = getCacheKey(getBlockId(a, b));
 
@@ -396,8 +406,8 @@ public class BlockMatrixStorage extends CacheUtils implements MatrixStorage, Sto
      */
     private double matrixGet(int a, int b) {
         // Remote get from the primary node (where given row or column is stored locally).
-        return ignite().compute(groupForKey(ML_BLOCK_CACHE_NAME, getBlockId(a, b))).call(() -> {
-            IgniteCache<BlockMatrixKey, BlockEntry> cache = Ignition.localIgnite().getOrCreateCache(ML_BLOCK_CACHE_NAME);
+        return ignite().compute(groupForKey(CACHE_NAME, getBlockId(a, b))).call(() -> {
+            IgniteCache<BlockMatrixKey, BlockEntry> cache = Ignition.localIgnite().getOrCreateCache(CACHE_NAME);
 
             BlockMatrixKey key = getCacheKey(getBlockId(a, b));
 
@@ -433,7 +443,7 @@ public class BlockMatrixStorage extends CacheUtils implements MatrixStorage, Sto
         cfg.setCacheMode(CacheMode.PARTITIONED);
 
         // Random cache name.
-        cfg.setName(ML_BLOCK_CACHE_NAME);
+        cfg.setName(CACHE_NAME);
 
         return Ignition.localIgnite().getOrCreateCache(cfg);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/CacheMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/CacheMatrixStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/CacheMatrixStorage.java
index 05f3c21..fbad957 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/CacheMatrixStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/CacheMatrixStorage.java
@@ -22,10 +22,10 @@ import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.Ignition;
-import org.apache.ignite.ml.math.MatrixKeyMapper;
 import org.apache.ignite.ml.math.MatrixStorage;
 import org.apache.ignite.ml.math.StorageConstants;
-import org.apache.ignite.ml.math.ValueMapper;
+import org.apache.ignite.ml.math.distributed.MatrixKeyMapper;
+import org.apache.ignite.ml.math.distributed.ValueMapper;
 
 /**
  * Matrix storage based on arbitrary cache and key and value mapping functions.
@@ -118,6 +118,11 @@ public class CacheMatrixStorage<K, V> implements MatrixStorage {
     }
 
     /** {@inheritDoc} */
+    @Override public int accessMode() {
+        return StorageConstants.RANDOM_ACCESS_MODE;
+    }
+
+    /** {@inheritDoc} */
     @Override public void writeExternal(ObjectOutput out) throws IOException {
         out.writeInt(rows);
         out.writeInt(cols);

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/DenseOffHeapMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/DenseOffHeapMatrixStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/DenseOffHeapMatrixStorage.java
index 921544e..6749488 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/DenseOffHeapMatrixStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/DenseOffHeapMatrixStorage.java
@@ -123,6 +123,11 @@ public class DenseOffHeapMatrixStorage implements MatrixStorage {
     }
 
     /** {@inheritDoc} */
+    @Override public int accessMode() {
+        return StorageConstants.RANDOM_ACCESS_MODE;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean isArrayBased() {
         return false;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/DiagonalMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/DiagonalMatrixStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/DiagonalMatrixStorage.java
index d313c45..a0f102a 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/DiagonalMatrixStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/DiagonalMatrixStorage.java
@@ -84,6 +84,11 @@ public class DiagonalMatrixStorage implements MatrixStorage {
     }
 
     /** {@inheritDoc} */
+    @Override public int accessMode() {
+        return StorageConstants.RANDOM_ACCESS_MODE;
+    }
+
+    /** {@inheritDoc} */
     @Override public void writeExternal(ObjectOutput out) throws IOException {
         out.writeObject(diagonal);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/FunctionMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/FunctionMatrixStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/FunctionMatrixStorage.java
index ac7fa51..18cc108 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/FunctionMatrixStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/FunctionMatrixStorage.java
@@ -158,6 +158,11 @@ public class FunctionMatrixStorage implements MatrixStorage {
     }
 
     /** {@inheritDoc} */
+    @Override public int accessMode() {
+        return StorageConstants.RANDOM_ACCESS_MODE;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean equals(Object o) {
         if (this == o)
             return true;

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/MatrixDelegateStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/MatrixDelegateStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/MatrixDelegateStorage.java
index 7a9c2e5..7dc37cd 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/MatrixDelegateStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/MatrixDelegateStorage.java
@@ -130,6 +130,11 @@ public class MatrixDelegateStorage implements MatrixStorage {
     }
 
     /** {@inheritDoc} */
+    @Override public int accessMode() {
+        return dlg.accessMode();
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean isArrayBased() {
         return dlg.isArrayBased() && rowOff == 0 && colOff == 0;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/PivotedMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/PivotedMatrixStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/PivotedMatrixStorage.java
index 749a508..387b347 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/PivotedMatrixStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/PivotedMatrixStorage.java
@@ -165,6 +165,11 @@ public class PivotedMatrixStorage implements MatrixStorage {
     }
 
     /** {@inheritDoc} */
+    @Override public int accessMode() {
+        return sto.accessMode();
+    }
+
+    /** {@inheritDoc} */
     @Override public void writeExternal(ObjectOutput out) throws IOException {
         out.writeObject(sto);
         out.writeObject(rowPivot);

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/RandomMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/RandomMatrixStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/RandomMatrixStorage.java
index 1435629..56bd871 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/RandomMatrixStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/RandomMatrixStorage.java
@@ -156,6 +156,11 @@ public class RandomMatrixStorage implements MatrixStorage {
     }
 
     /** {@inheritDoc} */
+    @Override public int accessMode() {
+        return StorageConstants.RANDOM_ACCESS_MODE;
+    }
+
+    /** {@inheritDoc} */
     @Override public int hashCode() {
         int res = 1;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/SparseDistributedMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/SparseDistributedMatrixStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/SparseDistributedMatrixStorage.java
index 5716a1a..95852b7 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/SparseDistributedMatrixStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/SparseDistributedMatrixStorage.java
@@ -33,19 +33,21 @@ import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.CachePeekMode;
 import org.apache.ignite.cache.CacheWriteSynchronizationMode;
 import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.ml.math.MatrixStorage;
 import org.apache.ignite.ml.math.StorageConstants;
-import org.apache.ignite.ml.math.impls.CacheUtils;
+import org.apache.ignite.ml.math.distributed.CacheUtils;
+import org.apache.ignite.ml.math.distributed.DistributedStorage;
+import org.apache.ignite.ml.math.distributed.keys.RowColMatrixKey;
+import org.apache.ignite.ml.math.distributed.keys.impl.SparseMatrixKey;
 import org.apache.ignite.ml.math.impls.matrix.SparseDistributedMatrix;
 
 /**
  * {@link MatrixStorage} implementation for {@link SparseDistributedMatrix}.
  */
-public class SparseDistributedMatrixStorage extends CacheUtils implements MatrixStorage, StorageConstants {
+public class SparseDistributedMatrixStorage extends CacheUtils implements MatrixStorage, StorageConstants, DistributedStorage<RowColMatrixKey> {
     /** Cache name used for all instances of {@link SparseDistributedMatrixStorage}. */
-    public static final String ML_CACHE_NAME = "ML_SPARSE_MATRICES_CONTAINER";
+    private static final String CACHE_NAME = "ML_SPARSE_MATRICES_CONTAINER";
     /** Amount of rows in the matrix. */
     private int rows;
     /** Amount of columns in the matrix. */
@@ -59,7 +61,7 @@ public class SparseDistributedMatrixStorage extends CacheUtils implements Matrix
 
     /** Actual distributed storage. */
     private IgniteCache<
-        IgniteBiTuple<Integer, IgniteUuid> /* Row or column index with matrix uuid. */,
+        RowColMatrixKey /* Row or column index with matrix uuid. */,
         Map<Integer, Double> /* Map-based row or column. */
         > cache = null;
 
@@ -95,8 +97,8 @@ public class SparseDistributedMatrixStorage extends CacheUtils implements Matrix
     /**
      * Create new ML cache if needed.
      */
-    private IgniteCache<IgniteBiTuple<Integer, IgniteUuid>, Map<Integer, Double>> newCache() {
-        CacheConfiguration<IgniteBiTuple<Integer, IgniteUuid>, Map<Integer, Double>> cfg = new CacheConfiguration<>();
+    private IgniteCache<RowColMatrixKey, Map<Integer, Double>> newCache() {
+        CacheConfiguration<RowColMatrixKey, Map<Integer, Double>> cfg = new CacheConfiguration<>();
 
         // Write to primary.
         cfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.PRIMARY_SYNC);
@@ -114,24 +116,20 @@ public class SparseDistributedMatrixStorage extends CacheUtils implements Matrix
         cfg.setCacheMode(CacheMode.PARTITIONED);
 
         // Random cache name.
-        cfg.setName(ML_CACHE_NAME);
+        cfg.setName(CACHE_NAME);
 
         return Ignition.localIgnite().getOrCreateCache(cfg);
     }
 
     /**
      *
-     *
      */
-    public IgniteCache<IgniteBiTuple<Integer, IgniteUuid>, Map<Integer, Double>> cache() {
+    public IgniteCache<RowColMatrixKey, Map<Integer, Double>> cache() {
         return cache;
     }
 
-    /**
-     *
-     *
-     */
-    public int accessMode() {
+    /** {@inheritDoc} */
+    @Override public int accessMode() {
         return acsMode;
     }
 
@@ -160,8 +158,8 @@ public class SparseDistributedMatrixStorage extends CacheUtils implements Matrix
      */
     private double matrixGet(int a, int b) {
         // Remote get from the primary node (where given row or column is stored locally).
-        return ignite().compute(groupForKey(ML_CACHE_NAME, a)).call(() -> {
-            IgniteCache<IgniteBiTuple<Integer, IgniteUuid>, Map<Integer, Double>> cache = Ignition.localIgnite().getOrCreateCache(ML_CACHE_NAME);
+        return ignite().compute(groupForKey(CACHE_NAME, a)).call(() -> {
+            IgniteCache<RowColMatrixKey, Map<Integer, Double>> cache = Ignition.localIgnite().getOrCreateCache(CACHE_NAME);
 
             // Local get.
             Map<Integer, Double> map = cache.localPeek(getCacheKey(a), CachePeekMode.PRIMARY);
@@ -182,8 +180,8 @@ public class SparseDistributedMatrixStorage extends CacheUtils implements Matrix
      */
     private void matrixSet(int a, int b, double v) {
         // Remote set on the primary node (where given row or column is stored locally).
-        ignite().compute(groupForKey(ML_CACHE_NAME, a)).run(() -> {
-            IgniteCache<IgniteBiTuple<Integer, IgniteUuid>, Map<Integer, Double>> cache = Ignition.localIgnite().getOrCreateCache(ML_CACHE_NAME);
+        ignite().compute(groupForKey(CACHE_NAME, a)).run(() -> {
+            IgniteCache<RowColMatrixKey, Map<Integer, Double>> cache = Ignition.localIgnite().getOrCreateCache(CACHE_NAME);
 
             // Local get.
             Map<Integer, Double> map = cache.localPeek(getCacheKey(a), CachePeekMode.PRIMARY);
@@ -206,8 +204,8 @@ public class SparseDistributedMatrixStorage extends CacheUtils implements Matrix
     }
 
     /** Build cache key for row/column. */
-    private IgniteBiTuple<Integer, IgniteUuid> getCacheKey(int idx) {
-        return new IgniteBiTuple<>(idx, uuid);
+    public RowColMatrixKey getCacheKey(int idx) {
+        return new SparseMatrixKey(idx, uuid, null);
     }
 
     /** {@inheritDoc} */
@@ -272,7 +270,7 @@ public class SparseDistributedMatrixStorage extends CacheUtils implements Matrix
 
     /** Delete all data from cache. */
     @Override public void destroy() {
-        Set<IgniteBiTuple<Integer, IgniteUuid>> keyset = IntStream.range(0, rows).mapToObj(this::getCacheKey).collect(Collectors.toSet());
+        Set<RowColMatrixKey> keyset = IntStream.range(0, rows).mapToObj(this::getCacheKey).collect(Collectors.toSet());
 
         cache.clearAll(keyset);
     }
@@ -309,4 +307,16 @@ public class SparseDistributedMatrixStorage extends CacheUtils implements Matrix
     public IgniteUuid getUUID() {
         return uuid;
     }
+
+    /** {@inheritDoc} */
+    @Override public Set<RowColMatrixKey> getAllKeys() {
+        int range = stoMode == ROW_STORAGE_MODE ? rows : cols;
+
+        return IntStream.range(0, range).mapToObj(i -> new SparseMatrixKey(i, getUUID(), null)).collect(Collectors.toSet());
+    }
+
+    /** {@inheritDoc} */
+    @Override public String cacheName() {
+        return CACHE_NAME;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/SparseLocalOnHeapMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/SparseLocalOnHeapMatrixStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/SparseLocalOnHeapMatrixStorage.java
index 99ef6fc..5e68b6c 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/SparseLocalOnHeapMatrixStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/matrix/SparseLocalOnHeapMatrixStorage.java
@@ -75,10 +75,8 @@ public class SparseLocalOnHeapMatrixStorage implements MatrixStorage, StorageCon
         return stoMode;
     }
 
-    /**
-     * @return Matrix elements access mode.
-     */
-    public int getAccessMode() {
+    /** {@inheritDoc} */
+    @Override public int accessMode() {
         return acsMode;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/CacheVectorStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/CacheVectorStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/CacheVectorStorage.java
index c0c7152..c4bb995 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/CacheVectorStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/CacheVectorStorage.java
@@ -22,9 +22,9 @@ import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.Ignition;
-import org.apache.ignite.ml.math.ValueMapper;
-import org.apache.ignite.ml.math.VectorKeyMapper;
 import org.apache.ignite.ml.math.VectorStorage;
+import org.apache.ignite.ml.math.distributed.ValueMapper;
+import org.apache.ignite.ml.math.distributed.VectorKeyMapper;
 
 /**
  * Vector storage based on existing cache and index and value mapping functions.

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/CacheVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/CacheVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/CacheVector.java
index e0a1a9d..676f271 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/CacheVector.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/CacheVector.java
@@ -19,14 +19,14 @@ package org.apache.ignite.ml.math.impls.vector;
 
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.ml.math.Matrix;
-import org.apache.ignite.ml.math.ValueMapper;
 import org.apache.ignite.ml.math.Vector;
-import org.apache.ignite.ml.math.VectorKeyMapper;
+import org.apache.ignite.ml.math.distributed.CacheUtils;
+import org.apache.ignite.ml.math.distributed.ValueMapper;
+import org.apache.ignite.ml.math.distributed.VectorKeyMapper;
 import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
 import org.apache.ignite.ml.math.functions.IgniteBiFunction;
 import org.apache.ignite.ml.math.functions.IgniteDoubleFunction;
 import org.apache.ignite.ml.math.functions.IgniteFunction;
-import org.apache.ignite.ml.math.impls.CacheUtils;
 import org.apache.ignite.ml.math.impls.storage.vector.CacheVectorStorage;
 
 /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/CacheMatrixTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/CacheMatrixTest.java b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/CacheMatrixTest.java
index a7e9488..c6f6f86 100644
--- a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/CacheMatrixTest.java
+++ b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/CacheMatrixTest.java
@@ -24,7 +24,7 @@ import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.ml.math.ExternalizeTest;
 import org.apache.ignite.ml.math.IdentityValueMapper;
 import org.apache.ignite.ml.math.Matrix;
-import org.apache.ignite.ml.math.MatrixKeyMapper;
+import org.apache.ignite.ml.math.distributed.MatrixKeyMapper;
 import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
 import org.apache.ignite.ml.math.impls.MathTestConstants;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/MatrixKeyMapperForTests.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/MatrixKeyMapperForTests.java b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/MatrixKeyMapperForTests.java
index cfdd0f3..10e6e3f 100644
--- a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/MatrixKeyMapperForTests.java
+++ b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/MatrixKeyMapperForTests.java
@@ -16,7 +16,7 @@
  */
 package org.apache.ignite.ml.math.impls.matrix;
 
-import org.apache.ignite.ml.math.MatrixKeyMapper;
+import org.apache.ignite.ml.math.distributed.MatrixKeyMapper;
 
 /** */
 public class MatrixKeyMapperForTests implements MatrixKeyMapper<Integer> {

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedBlockMatrixTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedBlockMatrixTest.java b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedBlockMatrixTest.java
index 1228f05..56ff638 100644
--- a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedBlockMatrixTest.java
+++ b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedBlockMatrixTest.java
@@ -30,9 +30,10 @@ import org.apache.ignite.IgniteCache;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.distributed.DistributedStorage;
+import org.apache.ignite.ml.math.distributed.keys.impl.BlockMatrixKey;
 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.BlockMatrixKey;
 import org.apache.ignite.ml.math.impls.storage.matrix.BlockMatrixStorage;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.testframework.junits.common.GridCommonTest;
@@ -229,9 +230,9 @@ public class SparseDistributedBlockMatrixTest extends GridCommonAbstractTest {
 
         Collection<String> cacheNames = ignite.cacheNames();
 
-        assert cacheNames.contains(BlockMatrixStorage.ML_BLOCK_CACHE_NAME);
+        assert cacheNames.contains(((DistributedStorage)cacheMatrix1.getStorage()).cacheName());
 
-        IgniteCache<BlockMatrixKey, Object> cache = ignite.getOrCreateCache(BlockMatrixStorage.ML_BLOCK_CACHE_NAME);
+        IgniteCache<BlockMatrixKey, Object> cache = ignite.getOrCreateCache(((DistributedStorage)cacheMatrix1.getStorage()).cacheName());
 
         Set<BlockMatrixKey> keySet1 = buildKeySet(cacheMatrix1);
         Set<BlockMatrixKey> keySet2 = buildKeySet(cacheMatrix2);

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedMatrixTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedMatrixTest.java b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedMatrixTest.java
index 3fec83c..1955588 100644
--- a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedMatrixTest.java
+++ b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/SparseDistributedMatrixTest.java
@@ -23,16 +23,15 @@ import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.Map;
 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.distributed.DistributedStorage;
+import org.apache.ignite.ml.math.distributed.keys.RowColMatrixKey;
 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;
@@ -235,12 +234,12 @@ public class SparseDistributedMatrixTest extends GridCommonAbstractTest {
 
         Collection<String> cacheNames = ignite.cacheNames();
 
-        assert cacheNames.contains(SparseDistributedMatrixStorage.ML_CACHE_NAME);
+        assert cacheNames.contains(((DistributedStorage)cacheMatrix1.getStorage()).cacheName());
 
-        IgniteCache<IgniteBiTuple<Integer, IgniteUuid>, Map<Integer, Double>> cache = ignite.getOrCreateCache(SparseDistributedMatrixStorage.ML_CACHE_NAME);
+        IgniteCache<RowColMatrixKey, Map<Integer, Double>> cache = ignite.getOrCreateCache(((DistributedStorage)cacheMatrix1.getStorage()).cacheName());
 
-        Set<IgniteBiTuple<Integer, IgniteUuid>> keySet1 = buildKeySet(cacheMatrix1);
-        Set<IgniteBiTuple<Integer, IgniteUuid>> keySet2 = buildKeySet(cacheMatrix2);
+        Set<RowColMatrixKey> keySet1 = ((SparseDistributedMatrixStorage)cacheMatrix1.getStorage()).getAllKeys();
+        Set<RowColMatrixKey> keySet2 = ((SparseDistributedMatrixStorage)cacheMatrix2.getStorage()).getAllKeys();
 
         assert cache.containsKeys(keySet1) ||
             keySet1.stream().allMatch(k -> cache.invoke(k, (entry, arguments) -> entry.getKey().equals(k) && entry.getValue().size() == 100));
@@ -289,18 +288,20 @@ public class SparseDistributedMatrixTest extends GridCommonAbstractTest {
     public void testMatrixTimes(){
         IgniteUtils.setCurrentIgniteName(ignite.configuration().getIgniteInstanceName());
 
-        SparseDistributedMatrix cacheMatrix1 = new SparseDistributedMatrix(MATRIX_SIZE, MATRIX_SIZE, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
-        SparseDistributedMatrix cacheMatrix2 = new SparseDistributedMatrix(MATRIX_SIZE, MATRIX_SIZE, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
+        int size = MATRIX_SIZE;
 
-        for (int i = 0; i < MATRIX_SIZE; i++) {
+        SparseDistributedMatrix cacheMatrix1 = new SparseDistributedMatrix(size, size, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
+        SparseDistributedMatrix cacheMatrix2 = new SparseDistributedMatrix(size, size, StorageConstants.ROW_STORAGE_MODE, StorageConstants.RANDOM_ACCESS_MODE);
+
+        for (int i = 0; i < size; i++) {
             cacheMatrix1.setX(i, i, i);
             cacheMatrix2.setX(i, i, i);
         }
 
         Matrix res = cacheMatrix1.times(cacheMatrix2);
 
-        for(int i = 0; i < MATRIX_SIZE; i++)
-            for(int j = 0; j < MATRIX_SIZE; j++)
+        for(int i = 0; i < size; i++)
+            for(int j = 0; j < size; j++)
                 if (i == j)
                     assertEquals(UNEXPECTED_VAL, i * i, res.get(i, j), PRECISION);
                 else
@@ -313,19 +314,4 @@ public class SparseDistributedMatrixTest extends GridCommonAbstractTest {
             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;
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/46ec148c/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/vector/CacheVectorTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/vector/CacheVectorTest.java b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/vector/CacheVectorTest.java
index b5813d7..a6cdd4c 100644
--- a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/vector/CacheVectorTest.java
+++ b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/vector/CacheVectorTest.java
@@ -30,7 +30,7 @@ import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.ml.math.IdentityValueMapper;
 import org.apache.ignite.ml.math.Vector;
-import org.apache.ignite.ml.math.VectorKeyMapper;
+import org.apache.ignite.ml.math.distributed.VectorKeyMapper;
 import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
 import org.apache.ignite.ml.math.functions.Functions;
 import org.apache.ignite.ml.math.impls.MathTestConstants;