FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
sparse_matrix.f90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! Copyright (c) 2019 FrontISTR Commons
3 ! This software is released under the MIT License, see LICENSE.txt
4 !-------------------------------------------------------------------------------
7  use hecmw_util
9  implicit none
10 
11  private
12 
13  public :: sparse_matrix_type_csr
14  public :: sparse_matrix_type_coo
15 
19 
20  public :: sparse_matrix
21  public :: sparse_matrix_set_type
22  public :: sparse_matrix_init
23  public :: sparse_matrix_finalize
24  public :: sparse_matrix_dump
25  public :: sparse_matrix_gather_rhs
27  public :: sparse_matrix_is_sym
28 
29  integer(kind=kint), parameter :: sparse_matrix_type_csr=1
30  integer(kind=kint), parameter :: sparse_matrix_type_coo=2
31 
32  integer(kind=kint), parameter :: sparse_matrix_symtype_asym=0
33  integer(kind=kint), parameter :: sparse_matrix_symtype_spd=1
34  integer(kind=kint), parameter :: sparse_matrix_symtype_sym=2
35 
36  type sparse_matrix
37  integer(kind=kint) :: type
38  integer(kind=kint) :: symtype
39  integer(kind=kint) :: n, n_loc
40  integer(kind=kint) :: nz
41  integer(kind=kint), pointer :: irn(:) => null()
42  integer(kind=kint), pointer :: jcn(:) => null()
43  real(kind=kreal), pointer :: a(:) => null()
44  real(kind=kreal), pointer :: rhs(:)
45  integer(kind=kint) :: offset
46  integer(kind=kint), pointer :: n_counts(:) => null()
47  integer(kind=kint), pointer :: displs(:) => null()
48  integer(kind=kint), pointer :: conv_ext(:) => null()
49  integer(kind=kint) :: iterlog
50  integer(kind=kint) :: timelog
51  logical :: is_initialized = .false.
52  end type sparse_matrix
53 
54 contains
55 
56  !!! public subroutines
57 
58  subroutine sparse_matrix_set_type(spMAT, type, symtype)
59  type (sparse_matrix), intent(inout) :: spmat
60  integer(kind=kint), intent(in) :: type
61  integer(kind=kint), intent(in) :: symtype
62  if (type == sparse_matrix_type_csr .or. &
63  type == sparse_matrix_type_coo) then
64  spmat%type = type
65  else
66  write(*,*) 'ERROR: unknown sparse matrix type'
67  stop
68  endif
69  if (symtype == sparse_matrix_symtype_asym .or. &
70  symtype == sparse_matrix_symtype_spd .or. &
71  symtype == sparse_matrix_symtype_sym) then
72  spmat%symtype = symtype
73  else
74  write(*,*) 'ERROR: unknown symmetry type for sparse matrix'
75  stop
76  endif
77  end subroutine sparse_matrix_set_type
78 
79  subroutine sparse_matrix_init(spMAT, N_loc, NZ)
80  type (sparse_matrix), intent(inout) :: spmat
81  integer(kind=kint), intent(in) :: n_loc
82  integer(kind=kint), intent(in) :: nz
83  if (spmat%is_initialized) then
84  !write(*,*) "WARNING: sparse_matrix_init_prof: already initialized; freeing"
85  call sparse_matrix_finalize(spmat)
86  endif
87  call sparse_matrix_set_dimension(spmat, n_loc)
88  call sparse_matrix_set_offsets(spmat)
89  call sparse_matrix_allocate_arrays(spmat, nz)
90  spmat%is_initialized = .true.
91  end subroutine sparse_matrix_init
92 
93  subroutine sparse_matrix_finalize(spMAT)
94  type (sparse_matrix), intent(inout) :: spmat
95  call sparse_matrix_free_arrays(spmat)
96  call sparse_matrix_clear(spmat)
97  spmat%is_initialized = .false.
98  end subroutine sparse_matrix_finalize
99 
100  subroutine sparse_matrix_dump(spMAT)
101  type(sparse_matrix), intent(in) :: spmat
102  integer(kind=kint),save :: num_call
103  character(len=128) :: fname
104  integer(kind=kint) :: i,myrank
105  myrank=hecmw_comm_get_rank()
106  write(fname,'(A,I0,A,I0)') 'sparse-matrix-',num_call,'.coo.',myrank
107  num_call = num_call + 1
108  write(*,*) 'Dumping sparse matrix to ', fname
109  open(91,file=fname,iostat=i)
110  if( i /= 0 ) return
111  if (spmat%type == sparse_matrix_type_csr) then
112  if (spmat%symtype == sparse_matrix_symtype_asym) &
113  write(91,*) '%SPARSE MATRIX CSR ASYM'
114  if (spmat%symtype == sparse_matrix_symtype_spd) &
115  write(91,*) '%SPARSE MATRIX CSR SPD'
116  if (spmat%symtype == sparse_matrix_symtype_sym) &
117  write(91,*) '%SPARSE MATRIX CSR SYM'
118  write(91,*) spmat%N_loc, spmat%N_loc, spmat%NZ
119  do i=1,spmat%N_loc+1
120  write(91,*) spmat%IRN(i)
121  enddo
122  do i=1,spmat%NZ
123  write(91,*) spmat%JCN(i), spmat%A(i)
124  enddo
125  elseif (spmat%type == sparse_matrix_type_coo) then
126  if (spmat%symtype == sparse_matrix_symtype_asym) &
127  write(91,*) '%SPARSE MATRIX COO ASYM'
128  if (spmat%symtype == sparse_matrix_symtype_spd) &
129  write(91,*) '%SPARSE MATRIX COO SPD'
130  if (spmat%symtype == sparse_matrix_symtype_sym) &
131  write(91,*) '%SPARSE MATRIX COO SYM'
132  write(91,*) spmat%N_loc, spmat%N_loc, spmat%NZ
133  do i=1,spmat%NZ
134  write(91,*) spmat%IRN(i), spmat%JCN(i), spmat%A(i)
135  enddo
136  endif
137  close(91)
138  end subroutine sparse_matrix_dump
139 
140  subroutine sparse_matrix_gather_rhs(spMAT, rhs_all)
141  type (sparse_matrix), intent(in) :: spmat
142  real(kind=kreal), intent(out) :: rhs_all(:)
143  integer(kind=kint) :: ierr,i
144  if (hecmw_comm_get_size() == 1) then
145  do i=1,spmat%N_loc
146  rhs_all(i) = spmat%rhs(i)
147  enddo
148  else
149  call hecmw_gatherv_real(spmat%rhs, spmat%N_loc, &
150  rhs_all, spmat%N_COUNTS, spmat%DISPLS, &
151  0, hecmw_comm_get_comm())
152  endif
153  end subroutine sparse_matrix_gather_rhs
154 
155  subroutine sparse_matrix_scatter_rhs(spMAT, rhs_all)
156  type (sparse_matrix), intent(inout) :: spmat
157  real(kind=kreal), intent(in) :: rhs_all(:)
158  integer(kind=kint) :: ierr,i
159  if (hecmw_comm_get_size() == 1) then
160  do i=1,spmat%N_loc
161  spmat%rhs(i) = rhs_all(i)
162  enddo
163  else
164  call hecmw_scatterv_real( &
165  rhs_all, spmat%N_COUNTS, spmat%DISPLS, &
166  spmat%rhs, spmat%N_loc, &
167  0, hecmw_comm_get_comm())
168  endif
169  end subroutine sparse_matrix_scatter_rhs
170 
171  function sparse_matrix_is_sym(spMAT)
172  type(sparse_matrix), intent(inout) :: spmat
173  logical :: sparse_matrix_is_sym
174  sparse_matrix_is_sym = (spmat%symtype > 0)
175  end function sparse_matrix_is_sym
176 
177  !!! private subroutines
178 
179  subroutine sparse_matrix_set_dimension(spMAT, N_loc)
180  type (sparse_matrix), intent(inout) :: spmat
181  integer(kind=kint), intent(in) :: n_loc
182  integer(kind=kint) :: ierr
183  spmat%N_loc = n_loc
184  if (hecmw_comm_get_size() == 1) then
185  spmat%N = spmat%N_loc
186  else
187  call hecmw_allreduce_int_1(spmat%N_loc, spmat%N, hecmw_sum, &
189  endif
190  end subroutine sparse_matrix_set_dimension
191 
192  subroutine sparse_matrix_set_offsets(spMAT)
193  type (sparse_matrix), intent(inout) :: spmat
194  integer(kind=kint) :: i,ierr,nprocs,myrank
195  nprocs=hecmw_comm_get_size()
196  myrank=hecmw_comm_get_rank()
197  ! OFFSET
198  !if (myrank == 0) then
199  if (associated(spmat%N_COUNTS)) deallocate(spmat%N_COUNTS)
200  if (associated(spmat%DISPLS)) deallocate(spmat%DISPLS)
201  allocate(spmat%N_COUNTS(nprocs), spmat%DISPLS(nprocs), stat=ierr)
202  if (ierr /= 0) then
203  write(*,*) " Allocation error, spMAT%N_COUNTS, spMAT%DISPLS"
205  endif
206  !endif
207  if (nprocs > 1) then
208  call hecmw_allgather_int_1(spmat%N_loc, &
209  spmat%N_COUNTS, hecmw_comm_get_comm())
210  endif
211  spmat%DISPLS(1)=0
212  do i=1,nprocs-1
213  spmat%DISPLS(i+1)=spmat%DISPLS(i)+spmat%N_COUNTS(i)
214  enddo
215  spmat%offset = spmat%DISPLS(myrank+1)
216  end subroutine sparse_matrix_set_offsets
217 
218  subroutine sparse_matrix_allocate_arrays(spMAT, NZ)
219  type(sparse_matrix), intent(inout) :: spmat
220  integer(kind=kint), intent(in) :: nz
221  integer(kind=kint) :: n_loc
222  integer(kind=kint) :: ierr
223  if (associated(spmat%IRN)) deallocate(spmat%IRN)
224  if (associated(spmat%JCN)) deallocate(spmat%JCN)
225  if (associated(spmat%A)) deallocate(spmat%A)
226  ierr = -1
227  n_loc=spmat%N_loc
228  if (spmat%type == sparse_matrix_type_csr) then
229  allocate(spmat%IRN(n_loc+1), spmat%JCN(nz), spmat%A(nz), stat=ierr)
230  elseif (spmat%type == sparse_matrix_type_coo) then
231  allocate(spmat%IRN(nz), spmat%JCN(nz), spmat%A(nz), stat=ierr)
232  endif
233  if (ierr /= 0) then
234  write(*,*) " Allocation error, spMAT%IRN, spMAT%JCN, spMAT%A"
236  endif
237  spmat%NZ = nz
238  end subroutine sparse_matrix_allocate_arrays
239 
240  subroutine sparse_matrix_free_arrays(spMAT)
241  type (sparse_matrix), intent(inout) :: spmat
242  if (associated(spmat%IRN)) deallocate(spmat%IRN)
243  if (associated(spmat%JCN)) deallocate(spmat%JCN)
244  if (associated(spmat%A)) deallocate(spmat%A)
245  if (associated(spmat%N_COUNTS)) deallocate(spmat%N_COUNTS)
246  if (associated(spmat%DISPLS)) deallocate(spmat%DISPLS)
247  if (associated(spmat%conv_ext)) deallocate(spmat%conv_ext)
248  end subroutine sparse_matrix_free_arrays
249 
250  subroutine sparse_matrix_clear(spMAT)
251  type(sparse_matrix), intent(inout) :: spmat
252  spmat%type = 0
253  spmat%symtype = 0
254  spmat%N = 0
255  spmat%N_loc = 0
256  spmat%NZ = 0
257  spmat%IRN => null()
258  spmat%JCN => null()
259  spmat%A => null()
260  spmat%offset = 0
261  spmat%N_COUNTS => null()
262  spmat%DISPLS => null()
263  spmat%conv_ext => null()
264  spmat%iterlog = 0
265  spmat%timelog = 0
266  end subroutine sparse_matrix_clear
267 
268 end module m_sparse_matrix
I/O and Utility.
Definition: hecmw_util_f.F90:7
integer(kind=kint), parameter hecmw_sum
integer(kind=kint) function hecmw_comm_get_size()
integer(kind=kint) function hecmw_comm_get_comm()
integer(kind=4), parameter kreal
integer(kind=kint) function hecmw_comm_get_rank()
subroutine hecmw_abort(comm)
subroutine hecmw_gatherv_real(sbuf, sc, rbuf, rcs, disp, root, comm)
subroutine hecmw_scatterv_real(sbuf, scs, disp, rbuf, rc, root, comm)
subroutine hecmw_allgather_int_1(sval, rbuf, comm)
subroutine hecmw_allreduce_int_1(sval, rval, op, comm)
This module provides DOF based sparse matrix data structure (CSR and COO)
subroutine, public sparse_matrix_init(spMAT, N_loc, NZ)
logical function, public sparse_matrix_is_sym(spMAT)
integer(kind=kint), parameter, public sparse_matrix_type_coo
integer(kind=kint), parameter, public sparse_matrix_type_csr
integer(kind=kint), parameter, public sparse_matrix_symtype_sym
subroutine, public sparse_matrix_finalize(spMAT)
subroutine, public sparse_matrix_gather_rhs(spMAT, rhs_all)
subroutine, public sparse_matrix_scatter_rhs(spMAT, rhs_all)
subroutine, public sparse_matrix_dump(spMAT)
integer(kind=kint), parameter, public sparse_matrix_symtype_asym
integer(kind=kint), parameter, public sparse_matrix_symtype_spd
subroutine, public sparse_matrix_set_type(spMAT, type, symtype)