You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
psblas3/test/Fileread/mmio.f90

298 lines
8.1 KiB
Fortran

module mmio
use psb_spmat_type
public mm_mat_read, mm_mat_write
interface mm_mat_read
module procedure dmm_mat_read
end interface
interface mm_mat_write
module procedure dmm_mat_write
end interface
private desym
contains
subroutine dmm_mat_read(a, iret, iunit, filename)
use psb_spmat_type
implicit none
type(psb_dspmat_type), intent(out) :: a
integer, intent(out) :: iret
integer, optional, intent(in) :: iunit
character(len=*), optional, intent(in) :: filename
character :: mmheader*15, fmt*15, object*10, type*10, sym*15
character(1024) :: line
integer :: indcrd, ptrcrd, totcrd,&
& valcrd, rhscrd, nrow, ncol, nnzero, neltvl, nrhs, nrhsix
real(kind(1.0d0)), pointer :: as_loc(:), dwork(:)
integer, pointer :: ia1_loc(:), ia2_loc(:), iwork(:), tmp(:), aux(:)
integer :: ircode, i,iel,ptr,nzr,infile,&
& j, liwork, ldwork, root, nprow, npcol, myprow, mypcol
logical, parameter :: debug=.false.
iret = 0
if (present(filename)) then
if (filename=='-') then
infile=5
else
if (present(iunit)) then
infile=iunit
else
infile=99
endif
open(infile,file=filename, status='OLD', err=901, action='READ')
endif
else
if (present(iunit)) then
infile=iunit
else
infile=5
endif
endif
read(infile,fmt=*,end=902) mmheader, object, fmt, type, sym
call lowerc(object,1,10)
call lowerc(fmt,1,15)
if ( (object .ne. 'matrix').or.(fmt.ne.'coordinate')) then
write(0,*) 'READ_MATRIX: input file type not yet supported'
iret=909
return
end if
if (debug) write(*,*) mmheader,':', object, ':',fmt,':', type,':', sym
do
read(infile,fmt='(a)') line
if (line(1:1) /= '%') exit
end do
if (debug) write(*,*) 'Line on input : "',line,'"'
read(line,fmt=*) nrow,ncol,nnzero
if (debug) write(*,*) 'Out: ',nrow,ncol,nnzero
a%m = nrow
a%k = ncol
a%fida = 'CSR'
a%descra='G'
call lowerc(type,1,10)
call lowerc(sym,1,15)
if ((type == 'real').and.(sym == 'general')) then
allocate(a%aspk(nnzero), a%ia1(nnzero), a%ia2(nrow+1),&
& a%pl(nrow),a%pr(nrow), tmp(nnzero+1), aux(nnzero+2),stat = ircode)
if (ircode /= 0) goto 993
do i=1,nnzero
read(infile,fmt=*,end=902) tmp(i),a%ia1(i),a%aspk(i)
end do
call mrgsrt(nnzero,tmp,aux,ircode)
if (ircode.eq.0) call reordvn(nnzero,a%aspk,tmp,a%ia1,aux)
! .... Order with key a%ia1 (COLUMN INDEX) ...
i = 1
j = i
! .... order with key tmp (row index) ...
do
if (i > nnzero) exit
do
if (j > nnzero) exit
if (tmp(j) /= tmp(i)) exit
j = j+1
! if (j.eq.(nnzero+1)) exit
enddo
iel = j - i
call mrgsrt(iel,a%ia1(i),aux,ircode)
if (ircode == 0) call reordvn(iel,a%aspk(i),tmp(i),&
& a%ia1(i), aux)
i = j
enddo
! convert to csr format
iel = 1
a%ia2(1) = 1
do i = a%ia2(1), nrow
do
if (tmp(iel) /= i) exit
iel = iel + 1
if (iel > nnzero) exit
enddo
a%ia2(i+1) = iel
enddo
deallocate(aux,tmp)
else if ((type == 'real').and.(sym == 'symmetric')) then
! we are generally working with non-symmetric matrices, so
! we de-symmetrize what we are about to read
allocate(a%aspk(2*nnzero),a%ia1(2*nnzero),&
& a%ia2(2*nnzero),as_loc(2*nnzero),&
& ia1_loc(2*nnzero),ia2_loc(2*nnzero),&
& a%pl(nrow),a%pr(nrow), stat = ircode)
if (ircode /= 0) goto 993
do i=1,nnzero
read(infile,fmt=*,end=902) a%ia1(i),a%ia2(i),a%aspk(i)
end do
liwork = 2*nnzero+2
allocate(iwork(liwork), stat = ircode)
if (ircode /= 0) goto 993
! After this call NNZERO contains the actual value for
! desymetrized matrix
call desym(nrow, a%aspk, a%ia2, a%ia1, as_loc, ia2_loc,&
& ia1_loc, iwork, nnzero, nzr)
call psb_spreall(a,nzr,ircode)
if (ircode /= 0) goto 993
allocate(tmp(nzr),stat=ircode)
if (ircode /= 0) goto 993
if (.false.) then
a%aspk(1:nzr) = as_loc(1:nzr)
a%ia1(1:nzr) = ia2_loc(1:nzr)
tmp(1:nzr) = ia1_loc(1:nzr)
else
do i=1,nzr
a%aspk(i) = as_loc(i)
a%ia1(i) = ia2_loc(i)
tmp(i) = ia1_loc(i)
end do
endif
iel = 1
a%ia2(1) = 1
do i = 1, nrow
do
if (tmp(iel) /= i) exit
iel = iel + 1
if (iel > nzr) exit
enddo
a%ia2(i+1) = iel
enddo
deallocate(as_loc, ia1_loc, ia2_loc,tmp,iwork)
else
write(0,*) 'read_matrix: matrix type not yet supported'
iret=904
end if
if (infile/=5) close(infile)
return
! open failed
901 iret=901
write(0,*) 'read_matrix: could not open file ',filename,' for input'
return
902 iret=902
write(0,*) 'READ_MATRIX: Unexpected end of file '
return
993 iret=993
write(0,*) 'READ_MATRIX: Memory allocation failure'
return
end subroutine dmm_mat_read
subroutine dmm_mat_write(a,mtitle,iret,eiout,filename)
use psb_spmat_type
implicit none
type(psb_dspmat_type), intent(in) :: a
integer, intent(out) :: iret
character(len=*), intent(in) :: mtitle
integer, optional, intent(in) :: eiout
character(len=*), optional, intent(in) :: filename
integer :: iout
iret = 0
if (present(filename)) then
if (filename=='-') then
iout=6
else
if (present(eiout)) then
iout = eiout
else
iout=99
endif
open(iout,file=filename, err=901, action='WRITE')
endif
else
if (present(eiout)) then
iout = eiout
else
iout=6
endif
endif
call psb_dcsprt(iout,a)
if (iout /= 6) close(iout)
return
901 continue
iret=901
write(0,*) 'Error while opening ',filename
return
end subroutine dmm_mat_write
subroutine desym(nrow,a,ja,ia,as,jas,ias,aux,nnzero,nzr)
implicit none
! .. scalar arguments ..
integer :: nrow,nnzero,value,index,ptr, nzr
! .. array arguments ..
real(kind(1.d0)) :: a(*),as(*)
integer :: ia(*),ias(*),jas(*),ja(*),aux(*)
! .. local scalars ..
integer :: i,iaw1,iaw2,iawt,j,jpt,k,kpt,ldim,nzl,js,iret,nel,diagel
! ..
nel = 0
diagel=0
do i=1, nnzero
as(i) = a(i)
jas(i) = ja(i)
ias(i) = ia(i)
if(ja(i) < ia(i)) then !this control avoids malfunctions in the cases
! where the matrix is declared symmetric but all its elements are
! explicitly stored see young1c.mtx from "Matrix Market".
! Nominally Matrix Market only stores lower triangle.
nel = nel+1
as(nnzero+nel) = a(i)
jas(nnzero+nel) = ia(i)
ias(nnzero+nel) = ja(i)
end if
end do
if (nel == 0) then ! Something strange is going on
write(0,*) 'Warning: DESYM did not copy anything in the upper triangle. '
write(0,*) ' This feels wrong!!!!! '
endif
! .... order with key ias ...
nzr = nnzero + nel
call mrgsrt(nzr,ias,aux,iret)
if (iret == 0) call reordvn(nzr,as,ias,jas,aux)
! .... order with key jas ...
i = 1
j = i
do
if (i > nzr) exit
do
if (j > nzr) exit
if (ias(j) /= ias(i)) exit
j = j+1
enddo
nzl = j - i
call mrgsrt(nzl,jas(i),aux,iret)
if (iret.eq.0) call reordvn(nzl,as(i),ias(i),jas(i),aux)
i = j
enddo
return
end subroutine desym
end module mmio