(git:ccc2433)
dbt_tas_io.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief tall-and-skinny matrices: Input / Output
10 !> \author Patrick Seewald
11 ! **************************************************************************************************
12 MODULE dbt_tas_io
14  dbm_distribution_obj,&
17  USE dbt_tas_base, ONLY: dbt_tas_get_info,&
24  USE dbt_tas_global, ONLY: dbt_tas_distribution,&
25  dbt_tas_rowcol_data
26  USE dbt_tas_split, ONLY: colsplit,&
28  rowsplit
29  USE dbt_tas_types, ONLY: dbt_tas_split_info,&
30  dbt_tas_type
31  USE kinds, ONLY: default_string_length,&
32  dp,&
33  int_8
34  USE message_passing, ONLY: mp_cart_type
35 #include "../../base/base_uses.f90"
36 
37  IMPLICIT NONE
38  PRIVATE
39 
40  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'dbt_tas_io'
41 
42  PUBLIC :: &
47 
48 CONTAINS
49 
50 ! **************************************************************************************************
51 !> \brief Write basic infos of tall-and-skinny matrix:
52 !> block dimensions, full dimensions, process grid dimensions
53 !> \param matrix ...
54 !> \param unit_nr ...
55 !> \param full_info Whether to print distribution and block size vectors
56 !> \author Patrick Seewald
57 ! **************************************************************************************************
58  SUBROUTINE dbt_tas_write_matrix_info(matrix, unit_nr, full_info)
59  TYPE(dbt_tas_type), INTENT(IN) :: matrix
60  INTEGER, INTENT(IN) :: unit_nr
61  LOGICAL, INTENT(IN), OPTIONAL :: full_info
62 
63  INTEGER :: unit_nr_prv
64  INTEGER(KIND=int_8) :: nblkcols_total, nblkrows_total
65 
66  CLASS(dbt_tas_distribution), ALLOCATABLE :: proc_row_dist, proc_col_dist
67  CLASS(dbt_tas_rowcol_data), ALLOCATABLE :: row_blk_size, col_blk_size
68  INTEGER(KIND=int_8) :: iblk
69  CHARACTER(default_string_length) :: name
70 
71  unit_nr_prv = prep_output_unit(unit_nr)
72  IF (unit_nr_prv == 0) RETURN
73 
74  CALL dbt_tas_get_info(matrix, nblkrows_total=nblkrows_total, nblkcols_total=nblkcols_total, &
75  proc_row_dist=proc_row_dist, proc_col_dist=proc_col_dist, &
76  row_blk_size=row_blk_size, col_blk_size=col_blk_size, name=name)
77 
78  IF (unit_nr_prv > 0) THEN
79  WRITE (unit_nr_prv, "(T2,A)") "GLOBAL INFO OF "//trim(name)
80  WRITE (unit_nr_prv, "(T4,A,1X)", advance="no") "block dimensions:"
81  WRITE (unit_nr_prv, "(I12,I12)", advance="no") nblkrows_total, nblkcols_total
82  WRITE (unit_nr_prv, "(/T4,A,1X)", advance="no") "full dimensions:"
83  WRITE (unit_nr_prv, "(I14,I14)", advance="no") row_blk_size%nfullrowcol, col_blk_size%nfullrowcol
84  WRITE (unit_nr_prv, "(/T4,A,1X)", advance="no") "process grid dimensions:"
85  WRITE (unit_nr_prv, "(I10,I10)", advance="no") proc_row_dist%nprowcol, proc_col_dist%nprowcol
86  IF (PRESENT(full_info)) THEN
87  IF (full_info) THEN
88  WRITE (unit_nr_prv, '(/T4,A)', advance='no') "Block sizes:"
89  WRITE (unit_nr_prv, '(/T8,A)', advance='no') 'Row:'
90  DO iblk = 1, row_blk_size%nmrowcol
91  WRITE (unit_nr_prv, '(I4,1X)', advance='no') row_blk_size%data(iblk)
92  END DO
93  WRITE (unit_nr_prv, '(/T8,A)', advance='no') 'Column:'
94  DO iblk = 1, col_blk_size%nmrowcol
95  WRITE (unit_nr_prv, '(I4,1X)', advance='no') col_blk_size%data(iblk)
96  END DO
97  WRITE (unit_nr_prv, '(/T4,A)', advance='no') "Block distribution:"
98  WRITE (unit_nr_prv, '(/T8,A)', advance='no') 'Row:'
99  DO iblk = 1, proc_row_dist%nmrowcol
100  WRITE (unit_nr_prv, '(I4,1X)', advance='no') proc_row_dist%dist(iblk)
101  END DO
102  WRITE (unit_nr_prv, '(/T8,A)', advance='no') 'Column:'
103  DO iblk = 1, proc_col_dist%nmrowcol
104  WRITE (unit_nr_prv, '(I4,1X)', advance='no') proc_col_dist%dist(iblk)
105  END DO
106 
107  END IF
108  END IF
109  WRITE (unit_nr_prv, *)
110  END IF
111 
112  END SUBROUTINE
113 
114 ! **************************************************************************************************
115 !> \brief Write info on tall-and-skinny matrix distribution & load balance
116 !> \param matrix ...
117 !> \param unit_nr ...
118 !> \param full_info Whether to print subgroup DBM distribution
119 !> \author Patrick Seewald
120 ! **************************************************************************************************
121  SUBROUTINE dbt_tas_write_dist(matrix, unit_nr, full_info)
122  TYPE(dbt_tas_type), INTENT(IN) :: matrix
123  INTEGER, INTENT(IN) :: unit_nr
124  LOGICAL, INTENT(IN), OPTIONAL :: full_info
125 
126  CHARACTER(default_string_length) :: name
127  INTEGER :: icol, igroup, irow, nblock, ndbt_p_max, &
128  nelement, nelement_p_max, ngroup, &
129  nproc, split_rowcol, unit_nr_prv
130  INTEGER(KIND=int_8) :: ndbt_p_sum, ndbt_s, ndbt_s_max, &
131  ndbt_tot, nelement_p_sum, nelement_s, &
132  nelement_s_max
133  INTEGER(KIND=int_8), DIMENSION(2) :: tmp_i8
134  INTEGER, DIMENSION(2) :: tmp
135  INTEGER, DIMENSION(:), POINTER :: coldist, rowdist
136  REAL(kind=dp) :: occupation
137  TYPE(dbm_distribution_obj) :: dist
138  TYPE(mp_cart_type) :: mp_comm, mp_comm_group
139 
140  unit_nr_prv = prep_output_unit(unit_nr)
141  IF (unit_nr_prv == 0) RETURN
142 
143  CALL dbt_tas_get_split_info(matrix%dist%info, mp_comm, ngroup, igroup, mp_comm_group, split_rowcol)
144  CALL dbt_tas_get_info(matrix, name=name)
145  nproc = mp_comm%num_pe
146 
147  nblock = dbt_tas_get_num_blocks(matrix)
148  nelement = dbt_tas_get_nze(matrix)
149 
150  ndbt_p_sum = dbt_tas_get_num_blocks_total(matrix)
151  nelement_p_sum = dbt_tas_get_nze_total(matrix)
152 
153  tmp = (/nblock, nelement/)
154  CALL mp_comm%max(tmp)
155  ndbt_p_max = tmp(1); nelement_p_max = tmp(2)
156 
157  ndbt_s = nblock
158  nelement_s = nelement
159 
160  CALL mp_comm_group%sum(ndbt_s)
161  CALL mp_comm_group%sum(nelement_s)
162 
163  tmp_i8 = (/ndbt_s, nelement_s/)
164  CALL mp_comm%max(tmp_i8)
165  ndbt_s_max = tmp_i8(1); nelement_s_max = tmp_i8(2)
166 
167  ndbt_tot = dbt_tas_nblkrows_total(matrix)*dbt_tas_nblkcols_total(matrix)
168  occupation = -1.0_dp
169  IF (ndbt_tot .NE. 0) occupation = 100.0_dp*real(ndbt_p_sum, dp)/real(ndbt_tot, dp)
170 
171  dist = dbm_get_distribution(matrix%matrix)
172  rowdist => dbm_distribution_row_dist(dist)
173  coldist => dbm_distribution_col_dist(dist)
174 
175  IF (unit_nr_prv > 0) THEN
176  WRITE (unit_nr_prv, "(T2,A)") &
177  "DISTRIBUTION OF "//trim(name)
178  WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Number of non-zero blocks:", ndbt_p_sum
179  WRITE (unit_nr_prv, "(T15,A,T75,F6.2)") "Percentage of non-zero blocks:", occupation
180  WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Average number of blocks per group:", (ndbt_p_sum + ngroup - 1)/ngroup
181  WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Maximum number of blocks per group:", ndbt_s_max
182  WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Average number of matrix elements per group:", (nelement_p_sum + ngroup - 1)/ngroup
183  WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Maximum number of matrix elements per group:", nelement_s_max
184  WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Average number of blocks per CPU:", (ndbt_p_sum + nproc - 1)/nproc
185  WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Maximum number of blocks per CPU:", ndbt_p_max
186  WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Average number of matrix elements per CPU:", (nelement_p_sum + nproc - 1)/nproc
187  WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Maximum number of matrix elements per CPU:", nelement_p_max
188  IF (PRESENT(full_info)) THEN
189  IF (full_info) THEN
190  WRITE (unit_nr_prv, "(T15,A)") "Row distribution on subgroup:"
191  WRITE (unit_nr_prv, '(T15)', advance='no')
192  DO irow = 1, SIZE(rowdist)
193  WRITE (unit_nr_prv, '(I3, 1X)', advance='no') rowdist(irow)
194  END DO
195  WRITE (unit_nr_prv, "(/T15,A)") "Column distribution on subgroup:"
196  WRITE (unit_nr_prv, '(T15)', advance='no')
197  DO icol = 1, SIZE(coldist)
198  WRITE (unit_nr_prv, '(I3, 1X)', advance='no') coldist(icol)
199  END DO
200  WRITE (unit_nr_prv, *)
201  END IF
202  END IF
203  END IF
204  END SUBROUTINE
205 
206 ! **************************************************************************************************
207 !> \brief Print info on how matrix is split
208 !> \param info ...
209 !> \param unit_nr ...
210 !> \param name ...
211 !> \author Patrick Seewald
212 ! **************************************************************************************************
213  SUBROUTINE dbt_tas_write_split_info(info, unit_nr, name)
214  TYPE(dbt_tas_split_info), INTENT(IN) :: info
215  INTEGER, INTENT(IN) :: unit_nr
216  CHARACTER(len=*), INTENT(IN), OPTIONAL :: name
217 
218  CHARACTER(len=:), ALLOCATABLE :: name_prv
219  INTEGER :: igroup, mynode, nsplit, split_rowcol, &
220  unit_nr_prv
221  INTEGER, DIMENSION(2) :: dims, groupdims, pgrid_offset
222  TYPE(mp_cart_type) :: mp_comm, mp_comm_group
223 
224  unit_nr_prv = prep_output_unit(unit_nr)
225  IF (unit_nr_prv == 0) RETURN
226 
227  IF (PRESENT(name)) THEN
228  ALLOCATE (name_prv, source=trim(name))
229  ELSE
230  ALLOCATE (name_prv, source="")
231  END IF
232 
233  CALL dbt_tas_get_split_info(info, mp_comm, nsplit, igroup, mp_comm_group, split_rowcol, pgrid_offset)
234 
235  mynode = mp_comm%mepos
236  dims = mp_comm%num_pe_cart
237  groupdims = mp_comm_group%num_pe_cart
238 
239  IF (unit_nr_prv > 0) THEN
240  SELECT CASE (split_rowcol)
241  CASE (rowsplit)
242  WRITE (unit_nr_prv, "(T4,A,I4,1X,A,I4)") name_prv//"splitting rows by factor", nsplit
243  CASE (colsplit)
244  WRITE (unit_nr_prv, "(T4,A,I4,1X,A,I4)") name_prv//"splitting columns by factor", nsplit
245  END SELECT
246  WRITE (unit_nr_prv, "(T4,A,I4,A1,I4)") name_prv//"global grid sizes:", dims(1), "x", dims(2)
247  END IF
248 
249  IF (unit_nr_prv > 0) THEN
250  WRITE (unit_nr_prv, "(T4,A,I4,A1,I4)") &
251  name_prv//"grid sizes on subgroups:", &
252  groupdims(1), "x", groupdims(2)
253  END IF
254 
255  END SUBROUTINE
256 
257 ! **************************************************************************************************
258 !> \brief ...
259 !> \param unit_nr ...
260 !> \return ...
261 !> \author Patrick Seewald
262 ! **************************************************************************************************
263  FUNCTION prep_output_unit(unit_nr) RESULT(unit_nr_out)
264  INTEGER, INTENT(IN), OPTIONAL :: unit_nr
265  INTEGER :: unit_nr_out
266 
267  IF (PRESENT(unit_nr)) THEN
268  unit_nr_out = unit_nr
269  ELSE
270  unit_nr_out = 0
271  END IF
272 
273  END FUNCTION
274 
275 END MODULE
276 
Definition: dbm_api.F:8
type(dbm_distribution_obj) function, public dbm_get_distribution(matrix)
Returns the distribution of the given matrix.
Definition: dbm_api.F:1266
integer function, dimension(:), pointer, contiguous, public dbm_distribution_col_dist(dist)
Returns the columns of the given distribution.
Definition: dbm_api.F:1455
integer function, dimension(:), pointer, contiguous, public dbm_distribution_row_dist(dist)
Returns the rows of the given distribution.
Definition: dbm_api.F:1425
Tall-and-skinny matrices: base routines similar to DBM API, mostly wrappers around existing DBM routi...
Definition: dbt_tas_base.F:13
integer(kind=int_8) function, public dbt_tas_get_nze_total(matrix)
Get total number of non-zero elements.
Definition: dbt_tas_base.F:958
pure integer function, public dbt_tas_get_nze(matrix)
As dbt_get_nze: get number of local non-zero elements.
Definition: dbt_tas_base.F:944
integer(kind=int_8) function, public dbt_tas_nblkrows_total(matrix)
...
Definition: dbt_tas_base.F:835
subroutine, public dbt_tas_get_info(matrix, nblkrows_total, nblkcols_total, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, distribution, name)
...
Definition: dbt_tas_base.F:999
integer(kind=int_8) function, public dbt_tas_nblkcols_total(matrix)
...
Definition: dbt_tas_base.F:861
integer(kind=int_8) function, public dbt_tas_get_num_blocks_total(matrix)
get total number of blocks
Definition: dbt_tas_base.F:926
pure integer function, public dbt_tas_get_num_blocks(matrix)
As dbt_get_num_blocks: get number of local blocks.
Definition: dbt_tas_base.F:913
Global data (distribution and block sizes) for tall-and-skinny matrices For very sparse matrices with...
tall-and-skinny matrices: Input / Output
Definition: dbt_tas_io.F:12
integer function, public prep_output_unit(unit_nr)
...
Definition: dbt_tas_io.F:264
subroutine, public dbt_tas_write_matrix_info(matrix, unit_nr, full_info)
Write basic infos of tall-and-skinny matrix: block dimensions, full dimensions, process grid dimensio...
Definition: dbt_tas_io.F:59
subroutine, public dbt_tas_write_dist(matrix, unit_nr, full_info)
Write info on tall-and-skinny matrix distribution & load balance.
Definition: dbt_tas_io.F:122
subroutine, public dbt_tas_write_split_info(info, unit_nr, name)
Print info on how matrix is split.
Definition: dbt_tas_io.F:214
methods to split tall-and-skinny matrices along longest dimension. Basically, we are splitting proces...
Definition: dbt_tas_split.F:13
integer, parameter, public rowsplit
Definition: dbt_tas_split.F:50
subroutine, public dbt_tas_get_split_info(info, mp_comm, nsplit, igroup, mp_comm_group, split_rowcol, pgrid_offset)
Get info on split.
integer, parameter, public colsplit
Definition: dbt_tas_split.F:50
DBT tall-and-skinny base types. Mostly wrappers around existing DBM routines.
Definition: dbt_tas_types.F:13
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public int_8
Definition: kinds.F:54
integer, parameter, public dp
Definition: kinds.F:34
integer, parameter, public default_string_length
Definition: kinds.F:57
Interface to the message passing library MPI.