23#include "../base/base_uses.f90"
28 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
29 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_blacs_env'
54 INTEGER :: my_pid = -1, n_pid = -1, ref_count = -1
56 INTEGER,
DIMENSION(:, :),
POINTER :: blacs2mpi => null()
57 INTEGER,
DIMENSION(:, :),
POINTER :: mpi2blacs => null()
58 LOGICAL :: repeatable = .false.
60 PROCEDURE,
PUBLIC, pass, non_overridable :: create => cp_blacs_env_create_low
61 PROCEDURE,
PUBLIC, pass, non_overridable :: retain => cp_blacs_env_retain
62 PROCEDURE,
PUBLIC, pass, non_overridable :: release => cp_blacs_env_release_low
64 PROCEDURE,
PUBLIC, pass, non_overridable :: write => cp_blacs_env_write
89 my_process_number, number_of_process_rows, &
90 number_of_process_columns, number_of_processes, &
91 para_env, blacs2mpi, mpi2blacs)
93 INTEGER,
INTENT(OUT),
OPTIONAL :: my_process_row, my_process_column, my_process_number, &
94 number_of_process_rows, number_of_process_columns, number_of_processes
96 INTEGER,
DIMENSION(:, :),
OPTIONAL,
POINTER :: blacs2mpi, mpi2blacs
98 IF (
PRESENT(my_process_row)) my_process_row = blacs_env%mepos(1)
99 IF (
PRESENT(my_process_column)) my_process_column = blacs_env%mepos(2)
100 IF (
PRESENT(my_process_number)) my_process_number = blacs_env%my_pid
101 IF (
PRESENT(number_of_process_rows)) number_of_process_rows = blacs_env%num_pe(1)
102 IF (
PRESENT(number_of_process_columns)) number_of_process_columns = blacs_env%num_pe(2)
103 IF (
PRESENT(number_of_processes)) number_of_processes = blacs_env%n_pid
104 IF (
PRESENT(para_env)) para_env => blacs_env%para_env
105 IF (
PRESENT(blacs2mpi)) blacs2mpi => blacs_env%blacs2mpi
106 IF (
PRESENT(mpi2blacs)) mpi2blacs => blacs_env%mpi2blacs
122 SUBROUTINE cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
125 INTEGER,
INTENT(IN),
OPTIONAL :: blacs_grid_layout
126 LOGICAL,
INTENT(IN),
OPTIONAL :: blacs_repeatable, row_major
127 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: grid_2d
130 CALL blacs_env%create(para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
146 SUBROUTINE cp_blacs_env_create_low(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
149 INTEGER,
INTENT(IN),
OPTIONAL :: blacs_grid_layout
150 LOGICAL,
INTENT(IN),
OPTIONAL :: blacs_repeatable, row_major
151 INTEGER,
DIMENSION(:),
INTENT(IN), &
154 INTEGER :: ipcol, iprow
155#if defined(__parallel)
156 INTEGER :: gcd_max, ipe, jpe, &
157 my_blacs_grid_layout, &
159 LOGICAL :: my_blacs_repeatable, &
167 npe = para_env%num_pe
170 IF (
PRESENT(grid_2d))
THEN
175 IF (nprow*npcol .NE. npe)
THEN
178 IF (
PRESENT(blacs_grid_layout)) my_blacs_grid_layout = blacs_grid_layout
180 SELECT CASE (my_blacs_grid_layout)
185 DO ipe = 1, ceiling(sqrt(real(npe,
dp)))
187 IF (ipe*jpe .NE. npe) cycle
188 IF (
gcd(ipe, jpe) >= gcd_max)
THEN
191 gcd_max =
gcd(ipe, jpe)
203 my_row_major = .true.
204 IF (
PRESENT(row_major)) my_row_major = row_major
205 IF (my_row_major)
THEN
206 CALL blacs_env%gridinit(para_env,
"Row-major", nprow, npcol)
208 CALL blacs_env%gridinit(para_env,
"Col-major", nprow, npcol)
212 blacs_env%my_pid = para_env%mepos
213 blacs_env%n_pid = para_env%num_pe
214 blacs_env%ref_count = 1
216 my_blacs_repeatable = .false.
217 IF (
PRESENT(blacs_repeatable)) my_blacs_repeatable = blacs_repeatable
218 blacs_env%repeatable = my_blacs_repeatable
219 IF (blacs_env%repeatable)
CALL blacs_env%set(15, 1)
223 CALL blacs_env%gridinit(para_env,
"Row-major", 1, 1)
225 blacs_env%ref_count = 1
228 mark_used(blacs_grid_layout)
229 mark_used(blacs_repeatable)
234 CALL para_env%retain()
235 blacs_env%para_env => para_env
238 ALLOCATE (blacs_env%blacs2mpi(0:blacs_env%num_pe(1) - 1, 0:blacs_env%num_pe(2) - 1))
239 blacs_env%blacs2mpi = 0
240 blacs_env%blacs2mpi(blacs_env%mepos(1), blacs_env%mepos(2)) = para_env%mepos
241 CALL para_env%sum(blacs_env%blacs2mpi)
242 ALLOCATE (blacs_env%mpi2blacs(2, 0:para_env%num_pe - 1))
243 blacs_env%mpi2blacs = -1
244 DO ipcol = 0, blacs_env%num_pe(2) - 1
245 DO iprow = 0, blacs_env%num_pe(1) - 1
246 blacs_env%mpi2blacs(1, blacs_env%blacs2mpi(iprow, ipcol)) = iprow
247 blacs_env%mpi2blacs(2, blacs_env%blacs2mpi(iprow, ipcol)) = ipcol
250 END SUBROUTINE cp_blacs_env_create_low
259 SUBROUTINE cp_blacs_env_retain(blacs_env)
262 cpassert(blacs_env%ref_count > 0)
263 blacs_env%ref_count = blacs_env%ref_count + 1
264 END SUBROUTINE cp_blacs_env_retain
276 IF (
ASSOCIATED(blacs_env))
THEN
277 cpassert(blacs_env%ref_count > 0)
278 blacs_env%ref_count = blacs_env%ref_count - 1
279 IF (blacs_env%ref_count < 1)
THEN
280 CALL blacs_env%release()
281 DEALLOCATE (blacs_env)
294 SUBROUTINE cp_blacs_env_release_low(blacs_env)
297 CALL blacs_env%gridexit()
299 DEALLOCATE (blacs_env%mpi2blacs)
300 DEALLOCATE (blacs_env%blacs2mpi)
302 END SUBROUTINE cp_blacs_env_release_low
313 SUBROUTINE cp_blacs_env_write(blacs_env, unit_nr)
315 INTEGER,
INTENT(in) :: unit_nr
317 WRITE (unit=unit_nr, fmt=
"(' group=',i10,', ref_count=',i10,',')") &
318 blacs_env%get_handle(), blacs_env%ref_count
319 WRITE (unit=unit_nr, fmt=
"(' mepos=(',i8,',',i8,'),')") &
320 blacs_env%mepos(1), blacs_env%mepos(2)
321 WRITE (unit=unit_nr, fmt=
"(' num_pe=(',i8,',',i8,'),')") &
322 blacs_env%num_pe(1), blacs_env%num_pe(2)
323 IF (
ASSOCIATED(blacs_env%blacs2mpi))
THEN
324 WRITE (unit=unit_nr, fmt=
"(' blacs2mpi=')", advance=
"no")
327 WRITE (unit=unit_nr, fmt=
"(' blacs2mpi=*null*')")
329 IF (
ASSOCIATED(blacs_env%para_env))
THEN
330 WRITE (unit=unit_nr, fmt=
"(' para_env=<cp_para_env id=',i6,'>,')") &
331 blacs_env%para_env%get_handle()
333 WRITE (unit=unit_nr, fmt=
"(' para_env=*null*')")
335 WRITE (unit=unit_nr, fmt=
"(' my_pid=',i10,', n_pid=',i10,' }')") &
336 blacs_env%my_pid, blacs_env%n_pid
338 END SUBROUTINE cp_blacs_env_write
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.
integer, parameter, public dp
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Collection of simple mathematical functions and subroutines.
elemental integer function, public gcd(a, b)
computes the greatest common divisor of two number
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