(git:db0abe2)
Loading...
Searching...
No Matches
cp_blacs_env.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief methods related to the blacs parallel environment
10!> \par History
11!> 08.2002 created [fawzi]
12!> 02.2004 modified to associate a blacs_env with a given para_env
13!> \author Fawzi Mohamed
14! **************************************************************************************************
16 USE iso_c_binding, ONLY: c_null_ptr,&
17 c_ptr
20 USE kinds, ONLY: dp
21 USE machine, ONLY: m_flush
22 USE mathlib, ONLY: gcd
25#include "../base/base_uses.f90"
26
27 IMPLICIT NONE
28 PRIVATE
29
30 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
31 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_blacs_env'
32
33 ! Blacs type of distribution
34 INTEGER, PARAMETER, PUBLIC :: blacs_grid_square = 1, &
35 blacs_grid_row = 2, &
37
38 PUBLIC :: cp_blacs_env_type
40
41! **************************************************************************************************
42!> \brief represent a blacs multidimensional parallel environment
43!> (for the mpi corrispective see cp_paratypes/mp_para_cart_type)
44!> \param ref_count the reference count, when it is zero this object gets
45!> deallocated
46!> \param my_pid process id of the actual processor
47!> \param n_pid number of process ids
48!> \param the para_env associated (and compatible) with this blacs_env
49!> \param blacs2mpi: maps mepos(1)-mepos(2) of blacs to its mpi rank
50!> \param mpi2blacs(i,rank): maps the mpi rank to the mepos(i)
51!> \par History
52!> 08.2002 created [fawzi]
53!> \author Fawzi Mohamed
54! **************************************************************************************************
56 INTEGER :: my_pid = -1, n_pid = -1, ref_count = -1
57 TYPE(mp_para_env_type), POINTER :: para_env => null()
58 INTEGER, DIMENSION(:, :), POINTER :: blacs2mpi => null()
59 INTEGER, DIMENSION(:, :), POINTER :: mpi2blacs => null()
60 LOGICAL :: repeatable = .false.
61 TYPE(c_ptr) :: cusolver_context = c_null_ptr
62 CONTAINS
63 PROCEDURE, PUBLIC, pass, non_overridable :: create => cp_blacs_env_create_low
64 PROCEDURE, PUBLIC, pass, non_overridable :: retain => cp_blacs_env_retain
65 PROCEDURE, PUBLIC, pass, non_overridable :: release => cp_blacs_env_release_low
66 PROCEDURE, PUBLIC, pass, non_overridable :: get => get_blacs_info
67 PROCEDURE, PUBLIC, pass, non_overridable :: write => cp_blacs_env_write
68 END TYPE cp_blacs_env_type
69
70#if defined(__CUSOLVERMP)
71 INTERFACE
72 SUBROUTINE cp_fm_cusolver_context_destroy(context) BIND(C)
73 IMPORT :: c_ptr
74 TYPE(c_ptr), INTENT(INOUT) :: context
75 END SUBROUTINE cp_fm_cusolver_context_destroy
76 END INTERFACE
77#endif
78
79!***
80CONTAINS
81
82! **************************************************************************************************
83!> \brief Return informations about the specified BLACS context.
84!> \param blacs_env ...
85!> \param my_process_row ...
86!> \param my_process_column ...
87!> \param my_process_number ...
88!> \param number_of_process_rows ...
89!> \param number_of_process_columns ...
90!> \param number_of_processes ...
91!> \param para_env ...
92!> \param blacs2mpi ...
93!> \param mpi2blacs ...
94!> \date 19.06.2001
95!> \par History
96!> MM.YYYY moved here from qs_blacs (Joost VandeVondele)
97!> \author Matthias Krack
98!> \version 1.0
99! **************************************************************************************************
100 SUBROUTINE get_blacs_info(blacs_env, my_process_row, my_process_column, &
101 my_process_number, number_of_process_rows, &
102 number_of_process_columns, number_of_processes, &
103 para_env, blacs2mpi, mpi2blacs)
104 CLASS(cp_blacs_env_type), INTENT(IN) :: blacs_env
105 INTEGER, INTENT(OUT), OPTIONAL :: my_process_row, my_process_column, my_process_number, &
106 number_of_process_rows, number_of_process_columns, number_of_processes
107 TYPE(mp_para_env_type), OPTIONAL, POINTER :: para_env
108 INTEGER, DIMENSION(:, :), OPTIONAL, POINTER :: blacs2mpi, mpi2blacs
109
110 IF (PRESENT(my_process_row)) my_process_row = blacs_env%mepos(1)
111 IF (PRESENT(my_process_column)) my_process_column = blacs_env%mepos(2)
112 IF (PRESENT(my_process_number)) my_process_number = blacs_env%my_pid
113 IF (PRESENT(number_of_process_rows)) number_of_process_rows = blacs_env%num_pe(1)
114 IF (PRESENT(number_of_process_columns)) number_of_process_columns = blacs_env%num_pe(2)
115 IF (PRESENT(number_of_processes)) number_of_processes = blacs_env%n_pid
116 IF (PRESENT(para_env)) para_env => blacs_env%para_env
117 IF (PRESENT(blacs2mpi)) blacs2mpi => blacs_env%blacs2mpi
118 IF (PRESENT(mpi2blacs)) mpi2blacs => blacs_env%mpi2blacs
119
120 END SUBROUTINE get_blacs_info
121
122! **************************************************************************************************
123!> \brief allocates and initializes a type that represent a blacs context
124!> \param blacs_env the type to initialize
125!> \param para_env the para_env for which a blacs env should be created
126!> \param blacs_grid_layout ...
127!> \param blacs_repeatable ...
128!> \param row_major ...
129!> \param grid_2d ...
130!> \par History
131!> 08.2002 created [fawzi]
132!> \author Fawzi Mohamed
133! **************************************************************************************************
134 SUBROUTINE cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
135 TYPE(cp_blacs_env_type), INTENT(OUT), POINTER :: blacs_env
136 TYPE(mp_para_env_type), INTENT(INOUT), TARGET :: para_env
137 INTEGER, INTENT(IN), OPTIONAL :: blacs_grid_layout
138 LOGICAL, INTENT(IN), OPTIONAL :: blacs_repeatable, row_major
139 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: grid_2d
140
141 ALLOCATE (blacs_env)
142 CALL blacs_env%create(para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
143
144 END SUBROUTINE cp_blacs_env_create
145
146! **************************************************************************************************
147!> \brief allocates and initializes a type that represent a blacs context
148!> \param blacs_env the type to initialize
149!> \param para_env the para_env for which a blacs env should be created
150!> \param blacs_grid_layout ...
151!> \param blacs_repeatable ...
152!> \param row_major ...
153!> \param grid_2d ...
154!> \par History
155!> 08.2002 created [fawzi]
156!> \author Fawzi Mohamed
157! **************************************************************************************************
158 SUBROUTINE cp_blacs_env_create_low(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
159 CLASS(cp_blacs_env_type), INTENT(OUT) :: blacs_env
160 TYPE(mp_para_env_type), TARGET, INTENT(INOUT) :: para_env
161 INTEGER, INTENT(IN), OPTIONAL :: blacs_grid_layout
162 LOGICAL, INTENT(IN), OPTIONAL :: blacs_repeatable, row_major
163 INTEGER, DIMENSION(:), INTENT(IN), &
164 OPTIONAL :: grid_2d
165
166 INTEGER :: ipcol, iprow
167#if defined(__parallel)
168 INTEGER :: gcd_max, ipe, jpe, &
169 my_blacs_grid_layout, &
170 npcol, npe, nprow
171 LOGICAL :: my_blacs_repeatable, &
172 my_row_major
173#endif
174
175#ifdef __parallel
176 ! get the number of cpus for this blacs grid
177 nprow = 1
178 npcol = 1
179 npe = para_env%num_pe
180 ! get the layout of this grid
181
182 IF (PRESENT(grid_2d)) THEN
183 nprow = grid_2d(1)
184 npcol = grid_2d(2)
185 END IF
186
187 IF (nprow*npcol /= npe) THEN
188 ! hard code for the time being the grid layout
189 my_blacs_grid_layout = blacs_grid_square
190 IF (PRESENT(blacs_grid_layout)) my_blacs_grid_layout = blacs_grid_layout
191 ! XXXXXX
192 SELECT CASE (my_blacs_grid_layout)
193 CASE (blacs_grid_square)
194 ! make the grid as 'square' as possible, where square is defined as nprow and npcol
195 ! having the largest possible gcd
196 gcd_max = -1
197 DO ipe = 1, ceiling(sqrt(real(npe, dp)))
198 jpe = npe/ipe
199 IF (ipe*jpe /= npe) cycle
200 IF (gcd(ipe, jpe) >= gcd_max) THEN
201 nprow = ipe
202 npcol = jpe
203 gcd_max = gcd(ipe, jpe)
204 END IF
205 END DO
206 CASE (blacs_grid_row)
207 nprow = 1
208 npcol = npe
209 CASE (blacs_grid_col)
210 nprow = npe
211 npcol = 1
212 END SELECT
213 END IF
214
215 my_row_major = .true.
216 IF (PRESENT(row_major)) my_row_major = row_major
217 IF (my_row_major) THEN
218 CALL blacs_env%gridinit(para_env, "R", nprow, npcol)
219 ELSE
220 CALL blacs_env%gridinit(para_env, "C", nprow, npcol)
221 END IF
222
223 ! We set the components of blacs_env here such that we can still use INTENT(OUT) with gridinit
224 blacs_env%my_pid = para_env%mepos
225 blacs_env%n_pid = para_env%num_pe
226 blacs_env%ref_count = 1
227
228 my_blacs_repeatable = .false.
229 IF (PRESENT(blacs_repeatable)) my_blacs_repeatable = blacs_repeatable
230 blacs_env%repeatable = my_blacs_repeatable
231 IF (blacs_env%repeatable) CALL blacs_env%set(15, 1)
232
233#else
234 ! In serial mode, we just have to setup the object
235 CALL blacs_env%gridinit(para_env, "R", 1, 1)
236
237 blacs_env%ref_count = 1
238 blacs_env%my_pid = 0
239 blacs_env%n_pid = 1
240 mark_used(blacs_grid_layout)
241 mark_used(blacs_repeatable)
242 mark_used(grid_2d)
243 mark_used(row_major)
244#endif
245
246 CALL para_env%retain()
247 blacs_env%para_env => para_env
248
249 ! generate the mappings blacs2mpi and mpi2blacs
250 ALLOCATE (blacs_env%blacs2mpi(0:blacs_env%num_pe(1) - 1, 0:blacs_env%num_pe(2) - 1))
251 blacs_env%blacs2mpi = 0
252 blacs_env%blacs2mpi(blacs_env%mepos(1), blacs_env%mepos(2)) = para_env%mepos
253 CALL para_env%sum(blacs_env%blacs2mpi)
254 ALLOCATE (blacs_env%mpi2blacs(2, 0:para_env%num_pe - 1))
255 blacs_env%mpi2blacs = -1
256 DO ipcol = 0, blacs_env%num_pe(2) - 1
257 DO iprow = 0, blacs_env%num_pe(1) - 1
258 blacs_env%mpi2blacs(1, blacs_env%blacs2mpi(iprow, ipcol)) = iprow
259 blacs_env%mpi2blacs(2, blacs_env%blacs2mpi(iprow, ipcol)) = ipcol
260 END DO
261 END DO
262 END SUBROUTINE cp_blacs_env_create_low
263
264! **************************************************************************************************
265!> \brief retains the given blacs env
266!> \param blacs_env the blacs env to retain
267!> \par History
268!> 08.2002 created [fawzi]
269!> \author Fawzi Mohamed
270! **************************************************************************************************
271 SUBROUTINE cp_blacs_env_retain(blacs_env)
272 CLASS(cp_blacs_env_type), INTENT(INOUT) :: blacs_env
273
274 cpassert(blacs_env%ref_count > 0)
275 blacs_env%ref_count = blacs_env%ref_count + 1
276 END SUBROUTINE cp_blacs_env_retain
277
278! **************************************************************************************************
279!> \brief releases the given blacs_env
280!> \param blacs_env the blacs env to release
281!> \par History
282!> 08.2002 created [fawzi]
283!> \author Fawzi Mohamed
284! **************************************************************************************************
285 SUBROUTINE cp_blacs_env_release(blacs_env)
286 TYPE(cp_blacs_env_type), POINTER :: blacs_env
287
288 IF (ASSOCIATED(blacs_env)) THEN
289 cpassert(blacs_env%ref_count > 0)
290 blacs_env%ref_count = blacs_env%ref_count - 1
291 IF (blacs_env%ref_count < 1) THEN
292 CALL blacs_env%release()
293 DEALLOCATE (blacs_env)
294 END IF
295 END IF
296 NULLIFY (blacs_env)
297 END SUBROUTINE cp_blacs_env_release
298
299! **************************************************************************************************
300!> \brief releases the given blacs_env
301!> \param blacs_env the blacs env to release
302!> \par History
303!> 08.2002 created [fawzi]
304!> \author Fawzi Mohamed
305! **************************************************************************************************
306 SUBROUTINE cp_blacs_env_release_low(blacs_env)
307 CLASS(cp_blacs_env_type), INTENT(INOUT) :: blacs_env
308
309#if defined(__CUSOLVERMP)
310 CALL cp_fm_cusolver_context_destroy(blacs_env%cusolver_context)
311#endif
312
313 CALL blacs_env%gridexit()
314 CALL mp_para_env_release(blacs_env%para_env)
315 DEALLOCATE (blacs_env%mpi2blacs)
316 DEALLOCATE (blacs_env%blacs2mpi)
317
318 END SUBROUTINE cp_blacs_env_release_low
319
320! **************************************************************************************************
321!> \brief writes the description of the given blacs env
322!> \param blacs_env the blacs environment to write
323!> \param unit_nr the unit number where to write the description of the
324!> blacs environment
325!> \par History
326!> 08.2002 created [fawzi]
327!> \author Fawzi Mohamed
328! **************************************************************************************************
329 SUBROUTINE cp_blacs_env_write(blacs_env, unit_nr)
330 CLASS(cp_blacs_env_type), INTENT(IN) :: blacs_env
331 INTEGER, INTENT(in) :: unit_nr
332
333 WRITE (unit=unit_nr, fmt="(' group=',i10,', ref_count=',i10,',')") &
334 blacs_env%get_handle(), blacs_env%ref_count
335 WRITE (unit=unit_nr, fmt="(' mepos=(',i8,',',i8,'),')") &
336 blacs_env%mepos(1), blacs_env%mepos(2)
337 WRITE (unit=unit_nr, fmt="(' num_pe=(',i8,',',i8,'),')") &
338 blacs_env%num_pe(1), blacs_env%num_pe(2)
339 IF (ASSOCIATED(blacs_env%blacs2mpi)) THEN
340 WRITE (unit=unit_nr, fmt="(' blacs2mpi=')", advance="no")
341 CALL cp_2d_i_write(blacs_env%blacs2mpi, unit_nr=unit_nr)
342 ELSE
343 WRITE (unit=unit_nr, fmt="(' blacs2mpi=*null*')")
344 END IF
345 IF (ASSOCIATED(blacs_env%para_env)) THEN
346 WRITE (unit=unit_nr, fmt="(' para_env=<cp_para_env id=',i6,'>,')") &
347 blacs_env%para_env%get_handle()
348 ELSE
349 WRITE (unit=unit_nr, fmt="(' para_env=*null*')")
350 END IF
351 WRITE (unit=unit_nr, fmt="(' my_pid=',i10,', n_pid=',i10,' }')") &
352 blacs_env%my_pid, blacs_env%n_pid
353 CALL m_flush(unit_nr)
354 END SUBROUTINE cp_blacs_env_write
355
356END MODULE cp_blacs_env
various utilities that regard array of different kinds: output, allocation,... maybe it is not a good...
subroutine, public cp_2d_i_write(array, unit_nr, el_format)
writes an array to the given unit
methods related to the blacs parallel environment
integer, parameter, public blacs_grid_row
integer, parameter, public blacs_grid_col
integer, parameter, public blacs_grid_square
subroutine, public cp_blacs_env_release(blacs_env)
releases the given blacs_env
subroutine get_blacs_info(blacs_env, my_process_row, my_process_column, my_process_number, number_of_process_rows, number_of_process_columns, number_of_processes, para_env, blacs2mpi, mpi2blacs)
Return informations about the specified BLACS context.
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
wrappers for the actual blacs calls. all functionality needed in the code should actually be provide ...
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:127
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
elemental integer function, public gcd(a, b)
computes the greatest common divisor of two number
Definition mathlib.F:1291
Interface to the message passing library MPI.
subroutine, public mp_para_env_release(para_env)
releases the para object (to be called when you don't want anymore the shared copy of this object)
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
stores all the informations relevant to an mpi environment