MPI-SCATCI  2.0
An MPI version of SCATCI
SCALAPACKMatrix_module.f90
Go to the documentation of this file.
1 ! Copyright 2019
2 !
3 ! For a comprehensive list of the developers that contributed to these codes
4 ! see the UK-AMOR website.
5 !
6 ! This file is part of UKRmol-in (UKRmol+ suite).
7 !
8 ! UKRmol-in is free software: you can redistribute it and/or modify
9 ! it under the terms of the GNU General Public License as published by
10 ! the Free Software Foundation, either version 3 of the License, or
11 ! (at your option) any later version.
12 !
13 ! UKRmol-in is distributed in the hope that it will be useful,
14 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ! GNU General Public License for more details.
17 !
18 ! You should have received a copy of the GNU General Public License
19 ! along with UKRmol-in (in source/COPYING). Alternatively, you can also visit
20 ! <https://www.gnu.org/licenses/>.
21 
33 
34  use blas_lapack_gbl, only: blasint
35  use const_gbl, only: stdout
36  use precisn, only: longint, wp
39  use parallelization_module, only: grid => process_grid
40 
41  implicit none
42 
43  public scalapackmatrix
44 
45  private
46 
50  real(wp), allocatable :: a_local_matrix(:,:)
51  integer(blasint) :: mat_dimen
52  integer(blasint) :: scal_block_size
53  integer(blasint) :: local_row_dimen, local_col_dimen
54  integer(blasint) :: descr_a_mat(50), descr_z_mat(50)
55  integer(blasint) :: lda
56  logical :: store_mat = .false.
57  contains
58  procedure, public :: print => print_scalapack
59  procedure, public :: am_i_involved
60  procedure, public :: setup_diag_matrix => initialize_struct_scalapack
61  procedure, public :: get_matelem_self => get_matelem_scalapack
62  procedure, public :: clear_matrix => clear_scalapack
63  procedure, public :: destroy_matrix => destroy_scalapack
64  procedure, public :: insert_into_diag_matrix => insert_into_local_matrix
65  procedure, private :: is_this_me
66  end type scalapackmatrix
67 
68 contains
69 
77  logical function am_i_involved (this)
78 
79  class(scalapackmatrix) :: this
80 
81  am_i_involved = this % store_mat
82 
83  end function am_i_involved
84 
85 
95  subroutine initialize_struct_scalapack (this, matrix_size, matrix_type, block_size)
96 
97  class(scalapackmatrix) :: this
98  integer, intent(in) :: matrix_size, matrix_type, block_size
99 
100  integer :: ifail, per_elm, dummy_int, c_update, l_update
101  real(wp) :: dummy_real
102 
103  !Blas variables
104  integer(blasint) :: ierr, ido, nb, info, nproc, nprow, npcol, myrow, mycol
105  integer(blasint), external :: numroc
106 
107  this % mat_dimen = matrix_size
108 
109  nprow = grid % gprows
110  npcol = grid % gpcols
111  myrow = grid % mygrow
112  mycol = grid % mygcol
113 
114  nproc = nprow * npcol
115 
116  write (stdout, "('nproc = ',i4,'matdimen = ',i4,'nrow = ',i4,' ncol = ',i4,'myrow = ',i4,' mycol = ',i4)") &
117  nproc, this % mat_dimen, nprow, npcol, myrow, mycol
118 
119  write (stdout, "('context = ',i4,'nprocs = ',i4,'matdimen = ',i8,'nrow = ',i8,' ncol = ',i8,'myrow = ',i8,' mycol = ',i8)")&
120  grid % gcntxt, nproc, this % mat_dimen, nprow, npcol, myrow, mycol
121 
122  this % store_mat = .true.
123 
124  if (.not. this % am_i_involved()) return
125 
126  this % scal_block_size = min(int(this % mat_dimen) / nprow, this % matrix_dimension / npcol)
127  this % scal_block_size = min(this % scal_block_size, 64_blasint)
128  this % scal_block_size = max(this % scal_block_size, 1_blasint)
129 
130  this % local_row_dimen = numroc(this % mat_dimen, this % scal_block_size, myrow, 0, nprow)
131  this % local_col_dimen = numroc(this % mat_dimen, this % scal_block_size, mycol, 0, npcol)
132 
133  this % lda = max(1_blasint, this % local_row_dimen)
134 
135  write (stdout, "('block_size = ',i4,' local_row_size = ',i8,' local_col_size = ',i8,' lda = ',i8)") &
136  this % scal_block_size, this % local_row_dimen, this % local_col_dimen, this % lda
137 
138  call descinit(this % descr_a_mat, this % mat_dimen, this % mat_dimen, this % scal_block_size, this % scal_block_size, &
139  0, 0, grid % gcntxt, this % lda, info)
140  if (info /= 0) then
141  write (stdout, "('Error in getting description for A', i4)") info
142  stop "AHH A"
143  end if
144 
145  call descinit(this % descr_z_mat, this % mat_dimen, this % mat_dimen, this % scal_block_size, this % scal_block_size, &
146  0, 0, grid % gcntxt, this % lda, info)
147  if (info /= 0) then
148  write (stdout, "('Error in getting description for Z', i4)") info
149  stop "AHH"
150  end if
151 
152  if (allocated(this % a_local_matrix)) then
153  call master_memory % free_memory(kind(this % a_local_matrix), size(this % a_local_matrix))
154  deallocate(this % a_local_matrix)
155  end if
156 
157  allocate(this % a_local_matrix(this % local_row_dimen, this % local_col_dimen), stat = ifail)
158  call master_memory % track_memory(kind(this % a_local_matrix), size(this % a_local_matrix), ifail, &
159  'SCALAPACKMATRIX::A_LOCAL_MATRIX')
160 
161  this % a_local_matrix = 0
162  this % n = real(this % local_row_dimen) * real(this % local_col_dimen)
163 
164  end subroutine initialize_struct_scalapack
165 
166 
171  logical function is_this_me (this, proc_row, proc_col)
172 
173  class(scalapackmatrix) :: this
174  integer(blasint), intent(in) :: proc_row, proc_col
175 
176  is_this_me = (proc_row == grid % mygrow) .and. &
177  (proc_col == grid % mygcol)
178 
179  end function is_this_me
180 
181 
186  subroutine get_matelem_scalapack (this, idx, i, j, coeff)
187 
188  class(scalapackmatrix) :: this
189  integer, intent(in) :: idx
190  integer, intent(out) :: i, j
191  real(wp), intent(out) :: coeff
192 
193  integer(blasint) :: i_loc, j_loc, proc_row, proc_col
194  integer(blasint), external :: indxl2g
195 
196  i_loc = idx / this % local_row_dimen + 1
197  j_loc = mod(idx, int(this % local_col_dimen)) + 1
198 
199  i = indxl2g(i_loc, this % scal_block_size, grid % mygrow, 0, grid % gprows)
200  j = indxl2g(j_loc, this % scal_block_size, grid % mygcol, 0, grid % gpcols)
201 
202  coeff = this % a_local_matrix(i_loc, j_loc)
203 
204  end subroutine get_matelem_scalapack
205 
206 
214  logical function insert_into_local_matrix (this, row, column, coefficient)
215 
216  class(scalapackmatrix) :: this
217  integer, intent(in) :: row, column
218  real(wp), intent(in) :: coefficient
219 
220  integer(blasint) :: proc_row, proc_col, i_loc, j_loc, blas_row, blas_col
221 
222  blas_row = row
223  blas_col = column
224 
225  if (row == column) call this % store_diagonal(row, coefficient)
226  if (.not. this % am_i_involved()) return
227 
228  !Figure out which proc it belongs to and the local matrix index
229  call infog2l(blas_row, blas_col, this % descr_a_mat, &
230  grid % gprows, grid % gpcols, &
231  grid % mygrow, grid % mygcol, &
232  i_loc, j_loc, proc_row, proc_col)
233 
234  if (this % is_this_me(proc_row, proc_col)) then
235  this % a_local_matrix(i_loc, j_loc) = coefficient
236  insert_into_local_matrix = .true.
237  else
238  insert_into_local_matrix = .false.
239  end if
240 
241  end function insert_into_local_matrix
242 
243 
248  subroutine print_scalapack(this)
249  class(scalapackmatrix) :: this
250 
251  write (stdout, "('-------TEMP CACHE---------')")
252  call this % temp_cache % print
253  !write(stdout,"('-------HARD CACHE---------')")
254  !call this%matrix_cache%print
255 
256  end subroutine print_scalapack
257 
258 
263  subroutine clear_scalapack (this)
264  class(scalapackmatrix) :: this
265 
266  if (allocated(this % a_local_matrix)) this % a_local_matrix = 0
267 
268  end subroutine clear_scalapack
269 
270 
275  subroutine destroy_scalapack(this)
276  class(scalapackmatrix) :: this
277 
278  if (allocated(this % a_local_matrix)) then
279  call master_memory % free_memory(kind(this % a_local_matrix), size(this % a_local_matrix))
280  if (allocated(this % a_local_matrix)) deallocate(this % a_local_matrix)
281  end if
282 
283  end subroutine destroy_scalapack
284 
285 end module scalapackmatrix_module
scalapackmatrix_module::get_matelem_scalapack
subroutine get_matelem_scalapack(this, idx, i, j, coeff)
Retrieve matrix element.
Definition: SCALAPACKMatrix_module.f90:187
memorymanager_module
Memory manager module.
Definition: MemoryManager_module.f90:31
scalapackmatrix_module::insert_into_local_matrix
logical function insert_into_local_matrix(this, row, column, coefficient)
Insert new element.
Definition: SCALAPACKMatrix_module.f90:215
scalapackmatrix_module::am_i_involved
logical function am_i_involved(this)
Is this process part of the BLACS grid.
Definition: SCALAPACKMatrix_module.f90:78
distributedmatrix_module::distributedmatrix
Distributed matrix type.
Definition: DistributedMatrix_module.f90:57
scalapackmatrix_module::print_scalapack
subroutine print_scalapack(this)
Print matrix.
Definition: SCALAPACKMatrix_module.f90:249
parallelization_module::process_grid
type(processgrid) process_grid
Definition: Parallelization_module.F90:80
scalapackmatrix_module::is_this_me
logical function is_this_me(this, proc_row, proc_col)
Check workitem association with current process.
Definition: SCALAPACKMatrix_module.f90:172
distributedmatrix_module
Distributed matrix module.
Definition: DistributedMatrix_module.f90:32
scalapackmatrix_module::initialize_struct_scalapack
subroutine initialize_struct_scalapack(this, matrix_size, matrix_type, block_size)
Initialize the type.
Definition: SCALAPACKMatrix_module.f90:96
parallelization_module
Distribution of processes into a grid.
Definition: Parallelization_module.F90:29
scalapackmatrix_module::scalapackmatrix
Definition: SCALAPACKMatrix_module.f90:47
scalapackmatrix_module
ScaLAPACK matrix module.
Definition: SCALAPACKMatrix_module.f90:32
scalapackmatrix_module::clear_scalapack
subroutine clear_scalapack(this)
Clear matrix.
Definition: SCALAPACKMatrix_module.f90:264
memorymanager_module::master_memory
type(memorymanager), public master_memory
This is the global memory manager.
Definition: MemoryManager_module.f90:69
scalapackmatrix_module::destroy_scalapack
subroutine destroy_scalapack(this)
Destroy matrix.
Definition: SCALAPACKMatrix_module.f90:276