diff --git a/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixMult.java b/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixMult.java index 9763e4ea57d..4900006a0e0 100644 --- a/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixMult.java +++ b/src/main/java/org/apache/sysds/runtime/matrix/data/LibMatrixMult.java @@ -2105,6 +2105,218 @@ private static void matrixMultSparseSparseMMSmallRHS(SparseBlock a, SparseBlock } } } + + public static void matrixMultSparseSparseMM(SparseBlock a, SparseBlock b, DenseBlock c, boolean transA, + boolean transB, int m, int n, int cd, int rl, int ru) { + if( !transA && !transB ) + matrixMultSparseSparseMM(a, b, c, m, cd, a.size(), rl, ru); + else if( transA && !transB ) + matrixMultSparseSparseTransA(a, b, c, cd, rl, ru); + else if( !transA ) + matrixMultSparseSparseTransB(a, b, c, n, rl, ru); + else + matrixMultSparseSparseTransATransB(a, b, c, n, rl, ru); + } + + private static void matrixMultSparseSparseTransA(SparseBlock a, SparseBlock b, DenseBlock c, int cd, int rl, int ru) { + final int kmax = Math.min(cd, Math.min(a.numRows(), b.numRows())); + final long nnzA = Math.max(1, a.size()); + final int blocksizeK = Math.max(32, Math.min(1024, UtilFunctions.nextIntPow2( + (int)Math.max(1, Math.pow((double)a.numRows()*Math.max(1, ru-rl)/nnzA, 2))))); + for( int bk=0; bk= 32 ) { + final int end = apos + alen; + for( ; p+3 bix[bend-1] || aix[aend-1] < bix[bpos] ) + return 0; + + if( alen * 8 < blen ) + return sparseRowDotBinarySearch(a, aix, apos, aend, b, bix, bpos, bend); + else if( blen * 8 < alen ) + return sparseRowDotBinarySearch(b, bix, bpos, bend, a, aix, apos, aend); + return dotProduct(a, aix, apos, alen, b, bix, bpos, blen); + } + + private static double sparseRowDotBinarySearch(double[] a, int[] aix, int apos, int aend, + double[] b, int[] bix, int bpos, int bend) { + double ret = 0; + for( int i=apos; i= 0 ) + ret += a[i] * b[k]; + } + return ret; + } + + private static void matrixMultSparseSparseTransATransB(SparseBlock a, SparseBlock b, DenseBlock c, int n, int rl, int ru) { + final int blocksizeJ = 256; + final int kmax = a.numRows(); + final long nnzB = Math.max(1, b.size()); + final int blocksizeK = Math.max(32, Math.min(1024, UtilFunctions.nextIntPow2( + (int)Math.max(1, Math.pow((double)b.numRows()*Math.max(1, kmax)/nnzB, 2))))); + final int cmax = Math.min(n, b.numRows()); + for( int bj=0; bj= a.numRows() || a.isEmpty(k) ) + continue; + + int apos = a.pos(k); + int alen = a.size(k); + int aixPos = (rl == 0) ? 0 : a.posFIndexGTE(k, rl); + if( aixPos < 0 ) + continue; + + int[] aix = a.indexes(k); + double[] avals = a.values(k); + for( int p=apos+aixPos; p