protected static void bothSparseMatmult(MatrixObject output,MatrixObject left,MatrixObject right,boolean isLeftTransposed,boolean isRightTransposed) throws DMLRuntimeException {
  int transA=isLeftTransposed ? CUSPARSE_OPERATION_TRANSPOSE : CUSPARSE_OPERATION_NON_TRANSPOSE;
  int transB=isRightTransposed ? CUSPARSE_OPERATION_TRANSPOSE : CUSPARSE_OPERATION_NON_TRANSPOSE;
  int m=(int)(isLeftTransposed ? left.getNumColumns() : left.getNumRows());
  int n=(int)(isRightTransposed ? right.getNumRows() : right.getNumColumns());
  int k=(int)(isLeftTransposed ? left.getNumRows() : left.getNumColumns());
  int k1=(int)(isRightTransposed ? right.getNumColumns() : right.getNumRows());
  if (k != k1)   throw new DMLRuntimeException("Dimension mismatch: " + k + " != "+ k1);
  if (m == -1 || n == -1 || k == -1)   throw new DMLRuntimeException("Incorrect dimensions");
  CSRPointer A=((JCudaObject)left.getGPUObject()).jcudaSparseMatrixPtr;
  CSRPointer B=((JCudaObject)right.getGPUObject()).jcudaSparseMatrixPtr;
  if (!isRightTransposed && right.getNumColumns() == 1) {
    sparseMatrixVectorMult(output,transA,(int)left.getNumRows(),(int)left.getNumColumns(),(int)right.getNumRows(),A,B);
  }
 else {
    sparseSparseMatmult(output,transA,transB,m,n,k,A,B);
  }
}

protected static void bothSparseMatmult ( MatrixObject output , MatrixObject left , MatrixObject right , boolean isLeftTransposed , boolean isRightTransposed ) throws DMLRuntimeException { int transA = isLeftTransposed ? CUSPARSE_OPERATION_TRANSPOSE : CUSPARSE_OPERATION_NON_TRANSPOSE ; int transB = isRightTransposed ? CUSPARSE_OPERATION_TRANSPOSE : CUSPARSE_OPERATION_NON_TRANSPOSE ; int m = ( int ) ( isLeftTransposed ? left . getNumColumns ( ) : left . getNumRows ( ) ) ; int n = ( int ) ( isRightTransposed ? right . getNumRows ( ) : right . getNumColumns ( ) ) ; int k = ( int ) ( isLeftTransposed ? left . getNumRows ( ) : left . getNumColumns ( ) ) ; int k1 = ( int ) ( isRightTransposed ? right . getNumColumns ( ) : right . getNumRows ( ) ) ; if ( k != k1 ) throw new DMLRuntimeException ( "Dimension mismatch: " + k + " != " + k1 ) ; if ( m == - 1 || n == - 1 || k == - 1 ) throw new DMLRuntimeException ( "Incorrect dimensions" ) ; CSRPointer A = ( ( JCudaObject ) left . getGPUObject ( ) ) . jcudaSparseMatrixPtr ; CSRPointer B = ( ( JCudaObject ) right . getGPUObject ( ) ) . jcudaSparseMatrixPtr ; if ( ! isRightTransposed && right . getNumColumns ( ) == 1 ) { sparseMatrixVectorMult ( output , transA , ( int ) left . getNumRows ( ) , ( int ) left . getNumColumns ( ) , ( int ) right . getNumRows ( ) , A , B ) ; } else { sparseSparseMatmult ( output , transA , transB , m , n , k , A , B ) ; } }
sparse c = sparse op ( a ) * sparse op ( b ) reroutes call to sparse matrix - vector mult if needed
