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