sparse matrix multiplication using MKL libraries - sparse-matrix

I was looking to find a way to perform a symmetric sparse matrix - matrix multiplication:
X = A B
where the sparse matrix A was previously stored in CSR3 format (upper triangular), while the matrix B is a dense non-symmetric matrix. Is there a routine inside the MKL libraries to do it? or do they all need the full sparse matrix in CSR format (to get the handle from) instead of the triangular one (I built the triangular matrix because I need to use it in MKL Pardiso)? I know about the mkl_sparse_d_mv(...) routine, but I couldn't find a way to get the sparse matrix handle from a symmetric sparse matrix previously stored like an upper triangular matrix in CSR format.
thank you in advance,
Daniele

Could you try the mkl_sparse_?_mm, where [?] == s,d,c and z data types.
This routine performs a matrix-matrix operation:
Y := alpha*op(A)X + betaY
where alpha and beta are scalars, A is a sparse matrix, op is a matrix modifier for matrix A, and X and Y are dense matrices.

In most cases you can easily feed a CSR3-stored matrix into sparse_d_create_csr by passing appropriately offset pointers to your row index for pointerB and pointerE.
You can then tell mkl_sparse_d_mm the sparse matrix is triangular and you'd like it to be filled (I have never done this and can't promise that it works).

ok, I can now say the routine needs the full matrix in CSR format, the matrix struct description it will only tells the routine to take one triangle(upper/lower) from the input full CSR matrix, but still it needs it all.

Related

How to Determine N of an M x N CSR Sparse Matrix

I have the CSR sparse matrix arrays representing an M x N matrix:
data
indoor
indices
My question is how do I determine the original dimension N. I understand that indptr has a M + 1 entries, so M is easily determined. But I can't see how to determine N, unless the matrix is square (M = N).
Any assistance would be much appreciated.
Kind regards
John
This heavily depends on the implementation of CRS/CCS. As you have noticed, it is only possible to directly extract the number of rows M when using CRS (or the number of columns N when using CCS) if the matrix has M * N entries. I'll try to answer this using the Eigen SparseMatrix implementation in C++ as you didn't specify for which language.
To initialize a sparse matrix with Eigen, you must first define a container of triplets (which contain information of the value, row and index of a coefficient):
std::vector<Eigen::Triplet<double>> coefficients;
buildProblem(coefficients); //fills the vector according to problem
Then you must declare the sparse matrix for which must include the dimension of the matrix:
Eigen::SparseMatrix<double> A(m,n);
A.setFromTriplets(coefficients.begin(), coefficients.end());
To retrieve the dimension, you can use these methods:
A.rows();
A.cols();
A.size(); // returns rows*cols
A.innerSize(); // returns minor dimension with respect to the storage order, i.e., the number of rows for a column-major matrix
A.outerSize(); // returns major dimension with respect to the storage order, i.e., the number of columns for a column-major matrix
A.nonZeros();

MKL Matrix Transpose

I have a very large rectangular and square float as well as complex matrix. I want to know Is there any in place MKL transpose routine? There is mkl_?imatcopy in MKL, please help me with an example.
I have tried this, but it didnot transpose matrix
size_t nEle = noOfCols * noOfRows;
float *data = (float*)calloc(nEle,sizeof(float));
initalizeData(data,noOfCols,noOfRows);
printdata(data,noOfCols,noOfRows);
printf("After transpose \n\n");
mkl_simatcopy('R','T',noOfCols,noOfRows,1,data,noOfPix,noOfCols);
//writeDataFile((char *)data,"AfterTranspose.img",nEle*sizeof(float));
printdata(data,noOfCols,noOfRows);
You may try to look at the existing in-place transposition routines for float real and complex datatypes. MKL package contains such examples: cimatcopy.c dimatcopy.c simatcopy.c zimatcopy.c. Please refer to the mklroot/examples/transc/source directory

store a vector as an (i,j) entry of a matrix in matlab

This is a simplified version of the project I am doing. I can get around this using other methods. I was just wondering, is it possible to do this in matlab ?
I want to store a 1*2 vector [100,100] to the (1,1) entry of a given matrix a. The following is the code.
a=zeros(2,2);
a(1,1)=[100,100];
Then I get Subscripted assignment dimension mismatch error.
I could use cell array instead. But there are not so many handy functions (like tril) for cell array compared with matrix. So, I was just wondering, does anyone know how to handle this situation or this is just a trivial case not need to mention at all. Many thanks for your time and attention.
You can use 3-d matrix instead of 2-d matrix if you already know the length of vector.
a = zeros (2,2,2) ;
a(1,1,:) = [100, 100] ;
or
a = [];
a (1,1,:) = [100,100];
In above example, you have to take care of indexing by yourself and matrix a can be in arbitrary dimensions.

Solve a banded matrix system of equations

I need to solve a 2D Poisson equation, that is, a system of equations in the for AX=B where A is an n-by-n matrix and B is a n-by-1 vector. Being A a discretization matrix for the 2D Poisson problem, I know that only 5 diagonals will be not null. Lapack doesn't provide functions to solve this particular problem, but it has functions for solving banded matrix system of equations, namely DGBTRF (for LU factorization) and DGBTRS. Now, the 5 diagonals are: the main diagonal, the first diagonals above and below the main and two diagonals above and below by m diagonals wrt the main diagonal. After reading the lapack documentation about band storage, I learned that I have to create a (3*m+1)-by-n matrix to store A in band storage format, let's call this matrix AB. Now the questions:
1) what is the difference between dgbtrs and dgbtrs_? Intel MKL provides both but I can't understand why
2) dgbtrf requires the band storage matrix to be an array. Should I linearize AB by rows or by columns?
3) is this the correct way to call the two functions?
int n, m;
double *AB;
/*... fill n, m, AB, with appropriate numbers */
int *pivots;
int nrows = 3 * m + 1, info, rhs = 1;
dgbtrf_(&n, &n, &m, &m, AB, &nrows, pivots, &info);
char trans = 'N';
dgbtrs_(&trans, &n, &m, &m, &rhs, AB, &nrows, pivots, B, &n, &info);
It also provides DGBTRS and DGBTRS_. Those are fortran administrativa that you should not care about. Just call dgbtrs (reason is that on some architectures, fortran routine names have underscore appended, on other not, and names may be either upper or lower case -- Intel MKL #defines the right one to dgbtrs).
LAPACK routines expects column major matrices (ie. Fortran style): store columns one after the others. The banded storage you must use is not hard : http://www.netlib.org/lapack/lug/node124.html.
It seems good to me, but please try it on small problems beforehand (always a good idea by the way). Also make sure you handle non-zero info (this is the way errors are reported).
Better style is to use MKL_INT instead of plain int, this is a typedef to the right type (may be different on some architectures).
Also make sure to allocate memory for pivots before calling dgbtrf.
This might be off topic. But for Poisson equation, FFT based solution is much faster. Just do 2D FFT of your potential field, divided by -(k^2+lambda^2) then do IFFT. lambda is a small number to avoid divergence for k=0. The 5-diagonal equation is a band-limited approximation of the Poisson equation, which approximate the differential operator by finite difference.
http://en.wikipedia.org/wiki/Screened_Poisson_equation

Mex sparse matrix

I created a sparse matrix in MEX using mxCreateSparse.
mxArray *W;
W=mxCreateSparse(n*n,n*n,xsize,mxREAL);
double *wpoint;
wpoint=mxGetPr(W);
for(p=0;p<xsize;p++)
{
Wpoint[(returnindex1(xi[p][0],xi[p][1])-1)*n*n + (returnindex1(xj[p][0],xj[p][1]))]= exp(-df[p]/(SIGMAI*SIGMAI)) * exp(-dx[p]/(SIGMAJ*SIGMAJ));
}
the maximum value which comes from (returnindex1(xi[p][0],xi[p][1])-1)*n*n + (returnindex1(xj[p][0],xj[p][1])) is n*n*n*n and I have created the sparse matrix of dimension (n*n)X(n*n)
When I display the whole matrix, some of the zero elements come as junk.
Also for large values of n, segmentation fault occurs at wpoint.
The pr array holds xsize elements and you accessing the array with out of bounds indices . Hence the seg violation.
I think your fundamental problem is that you have not fully grasped how sparse matrices are stored in MATLAB. I'm not an expert on the MATLAB implementation details but my recollection is that it uses compressed column storage.
In essence there are 3 arrays as follows:
double pr[NZMAX] which contains the NZMAX non-zero values.
int ir[NZMAX] which contains the row number of each value in pr.
int jc[m] which indexes into pr and ir identifying the first item in each of the m columns.
That's the executive summary, but I recommend that you read up on the details more carefully.

Resources