16 USE iso_c_binding,
ONLY: c_null_ptr,&
25#include "../base/base_uses.f90"
30 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
31 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_blacs_env'
56 INTEGER :: my_pid = -1, n_pid = -1, ref_count = -1
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
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
67 PROCEDURE,
PUBLIC, pass, non_overridable :: write => cp_blacs_env_write
70#if defined(__CUSOLVERMP)
72 SUBROUTINE cp_fm_cusolver_context_destroy(context)
BIND(C)
74 TYPE(c_ptr),
INTENT(INOUT) :: context
75 END SUBROUTINE cp_fm_cusolver_context_destroy
101 my_process_number, number_of_process_rows, &
102 number_of_process_columns, number_of_processes, &
103 para_env, blacs2mpi, mpi2blacs)
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
108 INTEGER,
DIMENSION(:, :),
OPTIONAL,
POINTER :: blacs2mpi, mpi2blacs
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
134 SUBROUTINE cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
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
142 CALL blacs_env%create(para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
158 SUBROUTINE cp_blacs_env_create_low(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
161 INTEGER,
INTENT(IN),
OPTIONAL :: blacs_grid_layout
162 LOGICAL,
INTENT(IN),
OPTIONAL :: blacs_repeatable, row_major
163 INTEGER,
DIMENSION(:),
INTENT(IN), &
166 INTEGER :: ipcol, iprow
167#if defined(__parallel)
168 INTEGER :: gcd_max, ipe, jpe, &
169 my_blacs_grid_layout, &
171 LOGICAL :: my_blacs_repeatable, &
179 npe = para_env%num_pe
182 IF (
PRESENT(grid_2d))
THEN
187 IF (nprow*npcol /= npe)
THEN
190 IF (
PRESENT(blacs_grid_layout)) my_blacs_grid_layout = blacs_grid_layout
192 SELECT CASE (my_blacs_grid_layout)
197 DO ipe = 1, ceiling(sqrt(real(npe,
dp)))
199 IF (ipe*jpe /= npe) cycle
200 IF (
gcd(ipe, jpe) >= gcd_max)
THEN
203 gcd_max =
gcd(ipe, jpe)
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)
220 CALL blacs_env%gridinit(para_env,
"C", nprow, npcol)
224 blacs_env%my_pid = para_env%mepos
225 blacs_env%n_pid = para_env%num_pe
226 blacs_env%ref_count = 1
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)
235 CALL blacs_env%gridinit(para_env,
"R", 1, 1)
237 blacs_env%ref_count = 1
240 mark_used(blacs_grid_layout)
241 mark_used(blacs_repeatable)
246 CALL para_env%retain()
247 blacs_env%para_env => para_env
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
262 END SUBROUTINE cp_blacs_env_create_low
271 SUBROUTINE cp_blacs_env_retain(blacs_env)
274 cpassert(blacs_env%ref_count > 0)
275 blacs_env%ref_count = blacs_env%ref_count + 1
276 END SUBROUTINE cp_blacs_env_retain
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)
306 SUBROUTINE cp_blacs_env_release_low(blacs_env)
309#if defined(__CUSOLVERMP)
310 CALL cp_fm_cusolver_context_destroy(blacs_env%cusolver_context)
313 CALL blacs_env%gridexit()
315 DEALLOCATE (blacs_env%mpi2blacs)
316 DEALLOCATE (blacs_env%blacs2mpi)
318 END SUBROUTINE cp_blacs_env_release_low
329 SUBROUTINE cp_blacs_env_write(blacs_env, unit_nr)
331 INTEGER,
INTENT(in) :: unit_nr
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")
343 WRITE (unit=unit_nr, fmt=
"(' blacs2mpi=*null*')")
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()
349 WRITE (unit=unit_nr, fmt=
"(' para_env=*null*')")
351 WRITE (unit=unit_nr, fmt=
"(' my_pid=',i10,', n_pid=',i10,' }')") &
352 blacs_env%my_pid, blacs_env%n_pid
354 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