Community
cancel
Showing results for
Did you mean:
Beginner
151 Views

## About COO with duplicate entries, and MKL_sparse_export_csr

Hello everyone,

Because I am working FEM, global stiffness matrix is sparse, which can be easily assembled in a COO format. But it's noted that this formed COO matrix have many unsorted duplicate entries (there are many values with same row and col value) which need to be sorted and consolidated or summed. In many other platforms, like matlab and python, sparse function can automatically sort and sum these duplicates, producing correct final COO format matrix.

But in MKL for Fortran users, I use mkl_?csrcoo, and it doens't consolidate these duplicates even though it produce sorted CSR matrix. Now I am using Matrix Manipulation Rountines in IE Sparse BLAS to do these things. I am not sure if these new rountines can operate COO with duplicate entries.

In addition, the routine mkl_spares_?_export_csr always give out wrong results. I also don't how to allocate array 'col_indx' and 'values', because I even don't know the length of these arrays if the duplicate entries have been consolidated.

My computer environment is VS 2015 community and Intel composer XE2018 update1.

Eric

Beginner
151 Views

Hello, everyone!

Now I find an indirect way to convert COO (with duplicates) into CSR. This approach was in fact given by an expert called mecej4 in this forum. It can be divided into two steps. First, we can use MKL_?CSRCOO subroutine to convert COO (with duplicates) into CSR with job(1)=2, then we will get a sorted CSR data even though it also has some duplicates. Second, I wrote my own simple subroutine 'Sum_duplicate' to consolidate those duplicates in CSR data, and then returns the final CSR data with no duplicates.

I have successfully used this approach to assemble the FEM stiffness matrix in a CSR format, and together with Pardiso solver to solve the equation 'KU=F'. It takes less than 1s to solve an linear elastic case with almost 200K DOFs.

The simple subroutine is attached, hoping it can help someone!

Best regards!

Eric

```include 'mkl_spblas.f90'

module Consolidate
implicit none

contains
subroutine Sum_duplicate(ia, ja, a, ia_new, ja_new, a_new, q)
integer :: ia(:), ja(:), ia_new(:), ja_new(:), q
integer :: p, num_new, num_old, i, j
real *8 :: a(:), a_new(:)

num_new=0; num_old=0; p=0; q=0

do i=1, size(ia)-1
num_old = num_new
num_new = num_new + ia(i+1)-ia(i)
ia_new(i) = ia(i)-p
if (ia(i+1)-ia(i)==0) cycle
q=q+1; ja_new(q)=ja(num_old+1); a_new(q)=a(num_old+1)
if (ia(i+1)-ia(i) >= 2)then
do j=num_old+2, num_new
if(ja(j)==ja(j-1))then
p=p+1
a_new(q)=a_new(q)+a(j)
elseif (ja(j) /= ja(j-1)) then
q=q+1
ja_new(q)=ja(j); a_new(q)=a(j)
end if
end do
end if
end do
ia_new(size(ia))=ia(size(ia))-p

return
end subroutine Sum_duplicate

end module Consolidate

Program ConvertCSR_test
use mkl_spblas
use Consolidate
implicit none
!include 'mkl_spblas.fi'
Integer  n, nnz, info
real *8, allocatable :: a(:), a_new(:), acoo(:)
integer, allocatable :: ia(:), ja(:), ia_new(:), ja_new(:), rowind(:), colind(:)
integer, allocatable :: iab(:), iae(:)
integer job(8), stat, index, rows,cols, q_size
type(SPARSE_MATRIX_T) :: A_csr, A_coo
integer,allocatable, dimension(:) :: iab_p, iae_p, ja_p
real *8,allocatable, dimension(:) :: acsr_p

n=4
nnz=6

allocate(rowind(nnz))
allocate(colind(nnz))
allocate(acoo(nnz))

rowind=(/4,1,3,3,4,4/)
colind=(/4,1,2,3,3,4/)
acoo=(/2,1,2,3,2,4/)

job(1)=2
job(2)=1
job(3)=1
job(6)=0

allocate(ia(n+1))
allocate(ja(nnz))
allocate(acsr(nnz))

call mkl_dcsrcoo(job, n, a, ja, ia, nnz, acoo, rowind, colind, info)

write(*,*) info

write(*,*) ia
write(*,*) ja
write(*,*) a

allocate(ia_new(size(ia)))
allocate(ja_new(size(ja)))
allocate(a_new(size(a)))

call Sum_duplicate(ia, ja, a, ia_new, ja_new, a_new, q_size)

write(*,*) q_size
write(*,*) ia_new
write(*,*) ja_new(1:q_size)
write(*,*) a_new(1:q_size)

end Program```