LCOV - code coverage report
Current view: top level - shared/common/src/27_toolbox_oop - m_mpiotk.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 20.1 % 274 55
Test Date: 2026-11-11 12:21:01 Functions: 40.0 % 5 2
Branches: 13.0 % 384 50

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_mpiotk
       2                 :             : !! NAME
       3                 :             : !!  m_mpiotk
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  This module provides helper functions for MPI-IO operations.
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !! Copyright (C) 2009-2026 ABINIT group (MG)
      10                 :             : !! This file is distributed under the terms of the
      11                 :             : !! GNU General Public License, see ~abinit/COPYING
      12                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      13                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
      14                 :             : !!
      15                 :             : !! SOURCE
      16                 :             : 
      17                 :             : #if defined HAVE_CONFIG_H
      18                 :             : #include "config.h"
      19                 :             : #endif
      20                 :             : 
      21                 :             : #include "abi_common.h"
      22                 :             : 
      23                 :             : MODULE m_mpiotk
      24                 :             : 
      25                 :             :  use defs_basis
      26                 :             :  use m_abicore
      27                 :             :  use m_errors
      28                 :             :  use m_xmpi
      29                 :             :  USE_MPI
      30                 :             : 
      31                 :             :  use iso_c_binding
      32                 :             : 
      33                 :             :  implicit none
      34                 :             : 
      35                 :             : #if defined HAVE_MPI1 && defined HAVE_MPI_IO
      36                 :             :  include 'mpif.h'
      37                 :             : #endif
      38                 :             : 
      39                 :             :  private
      40                 :             : 
      41                 :             : !public procedures.
      42                 :             : #ifdef HAVE_MPI_IO
      43                 :             :  public :: mpiotk_read_fsuba_dp2D     ! (individual|collective) read of a 2D sub-matrix
      44                 :             :  public :: mpiotk_write_fsuba_dp2D    ! (individual|collective) write of a 2D sub-matrix
      45                 :             : 
      46                 :             :  public :: mpiotk_read_fsuba_dpc3D    ! (individual|collective) read of a 3D sub-matrix
      47                 :             :  !public :: mpiotk_write_fsuba_dpc3D  ! (individual|collective) write of a 3D sub-matrix
      48                 :             : 
      49                 :             :  public :: mpiotk_read_fsuba_dpc4D    ! (individual|collective) read of a 4D sub-matrix
      50                 :             :  !public :: mpiotk_write_fsuba_dpc4D  ! (individual|collective) write of a 4D sub-matrix
      51                 :             : #else
      52                 :             :  public :: no_mpiotk
      53                 :             : #endif
      54                 :             : !!***
      55                 :             : 
      56                 :             : CONTAINS
      57                 :             : !!***
      58                 :             : 
      59                 :             : #ifndef HAVE_MPI_IO
      60                 :             : 
      61                 :             : !----------------------------------------------------------------------
      62                 :             : 
      63                 :             : !!****f* m_mpiotk/no_mpiotk
      64                 :             : !! NAME
      65                 :             : !!  no_mpiotk
      66                 :             : !!
      67                 :             : !! FUNCTION
      68                 :             : !!   Empty placeholder.
      69                 :             : !!
      70                 :             : !! SOURCE
      71                 :             : 
      72                 :             : subroutine no_mpiotk()
      73                 :             : 
      74                 :             : ! *************************************************************************
      75                 :             : 
      76                 :             : end subroutine no_mpiotk
      77                 :             : !!***
      78                 :             : 
      79                 :             : #else
      80                 :             : 
      81                 :             : !!****f* m_mpiotk/setup_fsuba_dp2D
      82                 :             : !! NAME
      83                 :             : !!  setup_fsuba_dp2D
      84                 :             : !!
      85                 :             : !! FUNCTION
      86                 :             : !!  Setup tables used in (read|write) a 2D array stored in a Fortran file
      87                 :             : !!
      88                 :             : !! NOTES
      89                 :             : !!  The value of ierr should always be checked by the caller
      90                 :             : !!
      91                 :             : !! INPUTS
      92                 :             : !!  sizes(2)
      93                 :             : !!  subsizes(2)
      94                 :             : !!  starts(2)
      95                 :             : !!  chunk_bsize =
      96                 :             : !!  comm = MPI communicator
      97                 :             : !!
      98                 :             : !! OUTPUTS
      99                 :             : !!  my_basead(:)
     100                 :             : !!  my_subsizes(:,:)
     101                 :             : !!  my_starts(:,:)
     102                 :             : !!  ierr=status error. A non zero value indicates that chunk_bsize is smaller that the fortran record
     103                 :             : !!    and therefore bufsz has not been read.
     104                 :             : !!
     105                 :             : !! SOURCE
     106                 :             : 
     107                 :          30 : subroutine setup_fsuba_dp2D(sizes,subsizes,starts,chunk_bsize,&
     108                 :             :   my_basead,my_subsizes,my_starts,my_ncalls,ncalls,comm,ierr)
     109                 :             : 
     110                 :             : !Arguments ------------------------------------
     111                 :             : !scalars
     112                 :             :  integer,intent(in) :: comm
     113                 :             :  integer,intent(out) :: ncalls,my_ncalls,ierr
     114                 :             :  integer(XMPI_OFFSET_KIND),intent(in) :: chunk_bsize
     115                 :             : !arrays
     116                 :             :  integer,intent(in) :: sizes(2),subsizes(2),starts(2)
     117                 :             :  integer,allocatable,intent(out) :: my_basead(:),my_subsizes(:,:),my_starts(:,:)
     118                 :             : 
     119                 :             : !Local variables ------------------------------
     120                 :             : !scalars
     121                 :             :  integer :: mpierr,ny2read,ny_chunk,icall,yrest
     122                 :             :  integer :: size_x,subs_x,start_x,start_y,stop_y
     123                 :             :  !character(len=500) :: msg
     124                 :             : 
     125                 :             : !************************************************************************
     126                 :             : 
     127                 :          30 :  size_x  = sizes(1)
     128                 :          30 :  subs_x  = subsizes(1)
     129                 :          30 :  start_x = starts(1)
     130                 :          30 :  start_y = starts(2)
     131                 :          30 :  stop_y  = start_y + subsizes(2)-1 ! last column to read
     132                 :             :  !
     133                 :             :  ! Read rows in blocks of size ny_chunk:
     134                 :             :  ! MPI-IO crashes if we try to read data > 2Gb in a single call.
     135                 :          30 :  ny2read = subsizes(2)
     136                 :          30 :  ny_chunk = ny2read
     137         [ -  + ]:          30 :  if ((two*subs_x*ny2read*xmpi_bsize_dp) > chunk_bsize) then
     138                 :           0 :    ny_chunk = chunk_bsize / (2*subs_x*xmpi_bsize_dp)
     139                 :             :    !if (ny_chunk == 0) ny_chunk = 50
     140                 :             :  end if
     141                 :             : 
     142                 :          30 :  call xmpi_min(ny_chunk,ierr,comm,mpierr)
     143         [ -  + ]:          30 :  if (ierr == 0) then
     144                 :           0 :    ierr = 1
     145                 :           0 :    RETURN
     146                 :             :  end if
     147                 :          30 :  ierr = 0
     148                 :             :  !
     149                 :             :  ! my_ncalls : number of read needed to fill my buffer.
     150                 :             :  ! ncalls    : max number of read in comm (needed for collective operations).
     151                 :          30 :  my_ncalls = ny2read / ny_chunk
     152                 :          30 :  yrest = MOD(ny2read, ny_chunk)
     153         [ -  + ]:          30 :  if (yrest /= 0) my_ncalls = my_ncalls + 1
     154                 :             : 
     155                 :          30 :  call xmpi_max(my_ncalls,ncalls,comm,mpierr)
     156                 :             :  !
     157                 :             :  ! Compute arrays used to define the file view.
     158   [ -  +  +  -  :          90 :  ABI_MALLOC(my_subsizes,(2,ncalls))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     159   [ -  +  +  -  :          60 :  ABI_MALLOC(my_starts,(2,ncalls))
          -  +  -  +  -  
                      + ]
     160   [ -  +  +  -  :          90 :  ABI_MALLOC(my_basead,(ncalls))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     161                 :             : 
     162         [ +  + ]:          60 :  do icall=1,my_ncalls
     163                 :             : 
     164         [ +  - ]:          60 :    if (icall*ny_chunk <= ny2read) then
     165         [ +  + ]:          90 :      my_subsizes(:,icall) = (/subs_x, ny_chunk/)
     166         [ +  + ]:          90 :      my_starts(:,icall) = (/start_x, (icall-1) * ny_chunk + start_y/)
     167                 :          30 :      my_basead(icall) = 1 + 2*(icall-1)*ny_chunk*subs_x ! 2 accounts for real and imag part.
     168                 :             :    else
     169                 :             :      ! Two cases:
     170                 :             :      ! 1) ny2read > ny_chunk and not divisible by ny2read
     171                 :             :      ! 2) ny2read < ny_chunk
     172         [ #  # ]:           0 :      my_subsizes(:,icall) = (/subs_x, yrest/)
     173         [ #  # ]:           0 :      if (ny2read >= ny_chunk) then
     174         [ #  # ]:           0 :        my_starts(:,icall) = (/start_x, stop_y-yrest+1/)
     175                 :           0 :        my_basead(icall) = 1 + 2 * (ny2read-yrest) * subs_x ! 2 accounts for real and imag part.
     176                 :             :      else
     177         [ #  # ]:           0 :        my_starts(:,icall) = starts
     178                 :           0 :        my_basead(icall) = 1
     179                 :             :      end if
     180                 :             :    end if
     181                 :             :  end do
     182                 :             :  !write(std_out,*)" >>>> my_ncalls, ncalls, ny2read, ny_chunk ",my_ncalls,ncalls,ny2read,ny_chunk
     183                 :             : 
     184                 :          60 : end subroutine setup_fsuba_dp2D
     185                 :             : !!***
     186                 :             : 
     187                 :             : !----------------------------------------------------------------------
     188                 :             : 
     189                 :             : !!****f* m_mpiotk/mpiotk_read_fsuba_dp2D
     190                 :             : !! NAME
     191                 :             : !!  mpiotk_read_fsuba_dp2D
     192                 :             : !!
     193                 :             : !! FUNCTION
     194                 :             : !!  Read a block of contiguous data stored in a 2D matrix.
     195                 :             : !!  Data is placed within Fortran records. Target: complex data stored in a real array.
     196                 :             : !!
     197                 :             : !! NOTES
     198                 :             : !!  The value of ierr should always be checked by the caller
     199                 :             : !!
     200                 :             : !! INPUTS
     201                 :             : !!  fh = MPI-IO file handler.
     202                 :             : !!  offset =
     203                 :             : !!  sizes(2)
     204                 :             : !!  subsizes(2)
     205                 :             : !!  starts(2)
     206                 :             : !!  bufsz = dimension of buffer (takes into accout both real and imaginary part)
     207                 :             : !!  chunk_bsize =
     208                 :             : !!  sc_mode= MPI-IO option
     209                 :             : !!    xmpio_single     ==> for reading by current proc.
     210                 :             : !!    xmpio_collective ==> for collective reading.
     211                 :             : !!  comm = MPI communicator
     212                 :             : !!
     213                 :             : !! OUTPUTS
     214                 :             : !!  buffer(bufsz)
     215                 :             : !!  ierr=status error. A non zero value indicates that chunk_bsize is smaller that the fortran record
     216                 :             : !!    and therefore bufsz has not been read.
     217                 :             : !!
     218                 :             : !! SOURCE
     219                 :             : 
     220                 :           0 : subroutine mpiotk_read_fsuba_dp2D(fh,offset,sizes,subsizes,starts,bufsz,buffer,chunk_bsize,sc_mode,comm,ierr)
     221                 :             : 
     222                 :             : !Arguments ------------------------------------
     223                 :             : !scalars
     224                 :             :  integer,intent(in) :: fh,comm,bufsz,sc_mode
     225                 :             :  integer,intent(out) :: ierr
     226                 :             :  integer(XMPI_OFFSET_KIND),intent(in) :: offset,chunk_bsize
     227                 :             : !arrays
     228                 :             :  integer,intent(in) :: sizes(2),subsizes(2),starts(2)
     229                 :             :  real(dp),intent(out),target :: buffer(bufsz)
     230                 :             : 
     231                 :             : !Local variables ------------------------------
     232                 :             : !scalars
     233                 :             :  integer :: mpierr,ptr,ncount,myfh
     234                 :             :  integer :: fsub_type,my_ncalls,icall,ncalls,subs_x
     235                 :             :  integer(XMPI_OFFSET_KIND) :: my_offset,my_offpad
     236                 :             :  !character(len=500) :: msg
     237                 :             :  type(c_ptr) :: cptr
     238                 :             : !arrays
     239                 :             :  integer :: call_subsizes(2),call_starts(2)
     240                 :           0 :  integer,allocatable :: my_basead(:),my_subsizes(:,:),my_starts(:,:)
     241                 :           0 :  real(dp),allocatable :: dummy_buf(:,:)
     242                 :           0 :  real(dp),pointer :: buf_ptr(:)
     243                 :             : 
     244                 :             : !************************************************************************
     245                 :             : 
     246                 :             :  ! Workaround for XLF
     247                 :           0 :  myfh = fh
     248                 :             : 
     249   [ #  #  #  # ]:           0 :  if (bufsz < 2 * PRODUCT(subsizes) ) then
     250                 :           0 :    ABI_ERROR("bufsz is too small")
     251                 :             :  end if
     252                 :             : 
     253         [ #  # ]:           0 :  if (sc_mode==xmpio_single) then
     254                 :             :    ! This makes the automatic tests fail (cut3d)
     255                 :             :    !ABI_WARNING("comm != xmpi_comm_self")
     256         [ #  # ]:           0 :  else if (sc_mode==xmpio_collective) then
     257                 :             :    continue
     258                 :             :  else
     259                 :           0 :    ABI_ERROR("Wrong sc_mode")
     260                 :             :  end if
     261                 :             : 
     262                 :           0 :  subs_x  = subsizes(1)
     263                 :             : 
     264                 :           0 :  call setup_fsuba_dp2D(sizes,subsizes,starts,chunk_bsize,my_basead,my_subsizes,my_starts,my_ncalls,ncalls,comm,ierr)
     265         [ #  # ]:           0 :  if (ierr/=0) RETURN
     266                 :             : 
     267         [ #  # ]:           0 :  do icall=1,ncalls
     268                 :             : 
     269         [ #  # ]:           0 :    if (icall <= my_ncalls) then
     270         [ #  # ]:           0 :      call_subsizes = my_subsizes(:,icall)
     271         [ #  # ]:           0 :      call_starts   = my_starts(:,icall)
     272                 :           0 :      ptr           = my_basead(icall)
     273                 :             :    else
     274                 :             :      ! Fake values needed to call read_all collectively.
     275         [ #  # ]:           0 :      call_subsizes = (/subs_x, 1/)
     276                 :           0 :      call_starts   = starts
     277                 :             :    end if
     278         [ #  # ]:           0 :    ncount = PRODUCT(call_subsizes)
     279                 :             :    !write(std_out,*)"  icall,ptr, ncount, ",icall,ptr,ncount
     280                 :             :    !write(std_out,*)"  call_starts",call_starts
     281                 :             :    !write(std_out,*)"  call_subsizes",call_subsizes
     282                 :             : 
     283                 :             :    ! Create subarry file view.
     284                 :           0 :    call xmpio_create_fsubarray_2D(sizes,call_subsizes,call_starts,MPI_DOUBLE_COMPLEX,fsub_type,my_offpad,mpierr)
     285                 :           0 :    ABI_CHECK_MPI(mpierr,"fsubarray_2D")
     286                 :             : 
     287                 :             :    ! Update the offset.
     288                 :           0 :    my_offset = offset + my_offpad
     289                 :             : 
     290                 :           0 :    call MPI_FILE_SET_VIEW(myfh, my_offset, MPI_BYTE, fsub_type, 'native', MPI_INFO_NULL, mpierr)
     291                 :           0 :    ABI_CHECK_MPI(mpierr,"SET_VIEW")
     292                 :             : 
     293                 :           0 :    call MPI_TYPE_FREE(fsub_type, mpierr)
     294                 :           0 :    ABI_CHECK_MPI(mpierr,"MPI_TYPE_FREE")
     295                 :             : 
     296         [ #  # ]:           0 :    if (sc_mode==xmpio_collective) then
     297                 :             :      ! Collective read
     298         [ #  # ]:           0 :      if (icall <= my_ncalls) then
     299         [ #  # ]:           0 :        cptr=c_loc(buffer(ptr)) ; call c_f_pointer(cptr,buf_ptr,[ncount])
     300         [ #  # ]:           0 :        call MPI_FILE_READ_ALL(myfh, buf_ptr, ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     301                 :             :      else
     302   [ #  #  #  #  :           0 :        ABI_MALLOC(dummy_buf,(2,subs_x))
          #  #  #  #  #  
                #  #  # ]
     303                 :           0 :        call MPI_FILE_READ_ALL(myfh, dummy_buf, ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     304         [ #  # ]:           0 :        ABI_FREE(dummy_buf)
     305                 :             :      end if
     306                 :           0 :      ABI_CHECK_MPI(mpierr,"FILE_READ_ALL")
     307                 :             : 
     308                 :             :    else
     309                 :             :      ! Individual read.
     310         [ #  # ]:           0 :      cptr=c_loc(buffer(ptr)) ; call c_f_pointer(cptr,buf_ptr,[ncount])
     311         [ #  # ]:           0 :      call MPI_FILE_READ(myfh, buf_ptr, ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     312                 :           0 :      ABI_CHECK_MPI(mpierr,"FILE_READ")
     313                 :             :    end if
     314                 :             : 
     315                 :             :  end do
     316                 :             : 
     317         [ #  # ]:           0 :  ABI_FREE(my_subsizes)
     318         [ #  # ]:           0 :  ABI_FREE(my_starts)
     319         [ #  # ]:           0 :  ABI_FREE(my_basead)
     320                 :             : 
     321   [ #  #  #  #  :           0 : end subroutine mpiotk_read_fsuba_dp2D
                   #  # ]
     322                 :             : !!***
     323                 :             : 
     324                 :             : !----------------------------------------------------------------------
     325                 :             : 
     326                 :             : !!****f* m_mpiotk/mpiotk_write_fsuba_dp2D
     327                 :             : !! NAME
     328                 :             : !!  mpiotk_write_fsuba_dp2D
     329                 :             : !!
     330                 :             : !! FUNCTION
     331                 :             : !!  Write a block of contiguous data stored in a 2D matrix.
     332                 :             : !!  Data is placed within Fortran records. Target: complex data stored in a real array.
     333                 :             : !!
     334                 :             : !! NOTES
     335                 :             : !!  The value of ierr should always be checked by the caller
     336                 :             : !!
     337                 :             : !! INPUTS
     338                 :             : !!  fh = MPI-IO file handler.
     339                 :             : !!  offset =
     340                 :             : !!  sizes(2)
     341                 :             : !!  subsizes(2)
     342                 :             : !!  starts(2)
     343                 :             : !!  bufsz = dimension of buffer (takes into accout both real and imaginary part)
     344                 :             : !!  buffer(bufsz)
     345                 :             : !!  chunk_bsize =
     346                 :             : !!  sc_mode= MPI-IO option
     347                 :             : !!    xmpio_single     ==> for reading by current proc.
     348                 :             : !!    xmpio_collective ==> for collective reading.
     349                 :             : !!  comm = MPI communicator
     350                 :             : !!
     351                 :             : !! OUTPUTS
     352                 :             : !!  ierr=status error. A non zero value indicates that chunk_bsize is smaller that the fortran record
     353                 :             : !!    and therefore bufsz has not been written.
     354                 :             : !!
     355                 :             : !! SOURCE
     356                 :             : 
     357                 :          30 : subroutine mpiotk_write_fsuba_dp2D(fh,offset,sizes,subsizes,starts,bufsz,buffer,chunk_bsize,sc_mode,comm,ierr)
     358                 :             : 
     359                 :             : !Arguments ------------------------------------
     360                 :             : !scalars
     361                 :             :  integer,intent(in) :: fh,comm,bufsz,sc_mode
     362                 :             :  integer,intent(out) :: ierr
     363                 :             :  integer(XMPI_OFFSET_KIND),intent(in) :: offset,chunk_bsize
     364                 :             : !arrays
     365                 :             :  integer,intent(in) :: sizes(2),subsizes(2),starts(2)
     366                 :             :  real(dp),intent(in),target :: buffer(bufsz)
     367                 :             : 
     368                 :             : !Local variables ------------------------------
     369                 :             : !scalars
     370                 :             :  integer :: mpierr,ptr,ncount,myfh
     371                 :             :  integer :: fsub_type,my_ncalls,icall,ncalls,subs_x
     372                 :             :  integer(XMPI_OFFSET_KIND) :: my_offset,my_offpad
     373                 :             :  type(c_ptr) :: cptr
     374                 :             :  !character(len=500) :: msg
     375                 :             : !arrays
     376                 :             :  integer :: call_subsizes(2),call_starts(2)
     377                 :          30 :  integer,allocatable :: my_basead(:),my_subsizes(:,:),my_starts(:,:)
     378                 :          30 : real(dp),pointer :: buf_ptr(:)
     379                 :             : 
     380                 :             : !************************************************************************
     381                 :             : 
     382                 :             :  DBG_ENTER("COLL")
     383                 :             : 
     384                 :             :  ! Workaround for XLF
     385                 :          30 :  myfh = fh
     386                 :             : 
     387   [ +  +  -  + ]:          90 :  if (bufsz < 2 * PRODUCT(subsizes) ) then
     388                 :           0 :    ABI_ERROR("bufsz is too small")
     389                 :             :  end if
     390                 :             : 
     391         [ +  - ]:          30 :  if (sc_mode==xmpio_single) then
     392                 :          30 :    call setup_fsuba_dp2D(sizes,subsizes,starts,chunk_bsize,my_basead,my_subsizes,my_starts,my_ncalls,ncalls,xmpi_comm_self,ierr)
     393         [ #  # ]:           0 :  else if (sc_mode==xmpio_collective) then
     394                 :           0 :    call setup_fsuba_dp2D(sizes,subsizes,starts,chunk_bsize,my_basead,my_subsizes,my_starts,my_ncalls,ncalls,comm,ierr)
     395                 :             :  else
     396                 :           0 :    ABI_ERROR("Wrong sc_mode")
     397                 :             :  end if
     398         [ -  + ]:          30 :  if (ierr/=0) RETURN
     399                 :             : 
     400                 :          30 :  subs_x = subsizes(1)
     401         [ +  + ]:          60 :  do icall=1,ncalls
     402                 :             : 
     403         [ +  - ]:          30 :    if (icall <= my_ncalls) then
     404         [ +  + ]:          90 :      call_subsizes = my_subsizes(:,icall)
     405         [ +  + ]:          90 :      call_starts   = my_starts(:,icall)
     406                 :          30 :      ptr           = my_basead(icall)
     407                 :             :    else
     408                 :             :      ! Fake values needed to call write_all collectively.
     409         [ #  # ]:           0 :      call_subsizes = (/subs_x, 1/)
     410                 :           0 :      call_starts   = starts
     411                 :             :    end if
     412         [ +  + ]:          90 :    ncount = PRODUCT(call_subsizes)
     413                 :             :    !write(std_out,*)"  icall,ptr, ncount, ",icall,ptr,ncount
     414                 :             :    !write(std_out,*)"  call_starts",call_starts
     415                 :             :    !write(std_out,*)"  call_subsizes",call_subsizes
     416                 :             : 
     417                 :             :    ! Create subarry file view.
     418                 :          30 :    call xmpio_create_fsubarray_2D(sizes,call_subsizes,call_starts,MPI_DOUBLE_COMPLEX,fsub_type,my_offpad,mpierr)
     419                 :          30 :    ABI_CHECK_MPI(mpierr,"fsubarray_2D")
     420                 :             : 
     421                 :             :    ! Update the offset.
     422                 :          30 :    my_offset = offset + my_offpad
     423                 :             : 
     424                 :          30 :    call MPI_FILE_SET_VIEW(myfh, my_offset, MPI_BYTE, fsub_type, 'native', MPI_INFO_NULL, mpierr)
     425                 :          30 :    ABI_CHECK_MPI(mpierr,"SET_VIEW")
     426                 :             : 
     427                 :          30 :    call MPI_TYPE_FREE(fsub_type, mpierr)
     428                 :          30 :    ABI_CHECK_MPI(mpierr,"MPI_TYPE_FREE")
     429                 :             : 
     430         [ -  + ]:          60 :    if (sc_mode==xmpio_collective) then
     431                 :             :      ! Collective write
     432         [ #  # ]:           0 :      if (icall <= my_ncalls) then
     433         [ #  # ]:           0 :        cptr=c_loc(buffer(ptr)) ; call c_f_pointer(cptr,buf_ptr,[ncount])
     434         [ #  # ]:           0 :        call MPI_FILE_WRITE_ALL(myfh, buf_ptr, ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     435                 :             :      else
     436                 :             :        ! Re-write my first chunk of data.
     437         [ #  # ]:           0 :        cptr=c_loc(buffer(1)) ; call c_f_pointer(cptr,buf_ptr,[ncount])
     438         [ #  # ]:           0 :        call MPI_FILE_WRITE_ALL(myfh, buf_ptr, ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     439                 :             :      end if
     440                 :           0 :      ABI_CHECK_MPI(mpierr,"FILE_WRITE_ALL")
     441                 :             : 
     442                 :             :    else
     443                 :             :      ! Individual write.
     444         [ +  + ]:          60 :      cptr=c_loc(buffer(ptr)) ; call c_f_pointer(cptr,buf_ptr,[ncount])
     445         [ -  + ]:          30 :      call MPI_FILE_WRITE(myfh, buf_ptr, ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     446                 :          30 :      ABI_CHECK_MPI(mpierr,"FILE_WRITE")
     447                 :             :    end if
     448                 :             : 
     449                 :             :  end do
     450                 :             : 
     451         [ -  + ]:          30 :  ABI_FREE(my_subsizes)
     452         [ -  + ]:          30 :  ABI_FREE(my_starts)
     453         [ -  + ]:          30 :  ABI_FREE(my_basead)
     454                 :             : 
     455                 :             :  DBG_EXIT("COLL")
     456                 :             : 
     457   [ -  -  -  -  :          30 : end subroutine mpiotk_write_fsuba_dp2D
                   -  - ]
     458                 :             : !!***
     459                 :             : 
     460                 :             : !----------------------------------------------------------------------
     461                 :             : 
     462                 :             : !!****f* m_mpiotk/mpiotk_read_fsuba_dpc3D
     463                 :             : !! NAME
     464                 :             : !!  mpiotk_read_fsuba_dpc3D
     465                 :             : !!
     466                 :             : !! FUNCTION
     467                 :             : !!  Read of a block of contiguous data stored in a 3D matrix.
     468                 :             : !!  Data is placed within Fortran records. Target: complex data stored in a complex array.
     469                 :             : !!
     470                 :             : !! NOTES
     471                 :             : !!  The value of ierr should always be checked by the caller
     472                 :             : !!
     473                 :             : !! INPUTS
     474                 :             : !!  fh = MPI-IO file handler.
     475                 :             : !!  offset =
     476                 :             : !!  sizes(3)
     477                 :             : !!  subsizes(3)
     478                 :             : !!  starts(3)
     479                 :             : !!  bufsz = dimension of cbuffer
     480                 :             : !!  chunk_bsize =
     481                 :             : !!  comm = MPI communicator
     482                 :             : !!  sc_mode= MPI-IO option
     483                 :             : !!    xmpio_single     ==> for reading by current proc.
     484                 :             : !!    xmpio_collective ==> for collective reading.
     485                 :             : !!
     486                 :             : !! OUTPUTS
     487                 :             : !!  cbuffer(bufsz)
     488                 :             : !!  ierr=status error. A non zero value indicates that chunk_bsize is smaller that the fortran record
     489                 :             : !!    and therefore bufsz has not been read.
     490                 :             : !!
     491                 :             : !! SOURCE
     492                 :             : 
     493                 :           0 : subroutine mpiotk_read_fsuba_dpc3D(fh,offset,sizes,subsizes,starts,bufsz,cbuffer,chunk_bsize,sc_mode,comm,ierr)
     494                 :             : 
     495                 :             : !Arguments ------------------------------------
     496                 :             : !scalars
     497                 :             :  integer,intent(in) :: fh,comm,bufsz,sc_mode
     498                 :             :  integer,intent(out) :: ierr
     499                 :             :  integer(XMPI_OFFSET_KIND),intent(in) :: offset,chunk_bsize
     500                 :             : !arrays
     501                 :             :  integer,intent(in) :: sizes(3),subsizes(3),starts(3)
     502                 :             :  complex(dp),intent(out),target :: cbuffer(bufsz)
     503                 :             : 
     504                 :             : !Local variables-------------------------------
     505                 :             : !scalars
     506                 :             :  integer :: mpierr,nz2read,nz_chunk,ptr,ncount,myfh
     507                 :             :  integer :: fsub_type,my_ncalls,icall,zrest,ncalls
     508                 :             :  integer :: size_x,size_y,subs_x,subs_y,subs_xy,start_x,start_y,start_z,stop_z
     509                 :             :  integer(XMPI_OFFSET_KIND) :: my_offset,my_offpad
     510                 :             :  !character(len=500) :: msg
     511                 :             :  type(c_ptr) :: cptr
     512                 :             : !arrays
     513                 :             :  integer :: call_subsizes(3),call_starts(3)
     514                 :           0 :  integer,allocatable :: my_basead(:),my_subsizes(:,:),my_starts(:,:)
     515                 :           0 :  complex(dp),allocatable :: dummy_cbuf(:)
     516                 :           0 :  complex(dp),pointer :: buf_ptr(:)
     517                 :             : !************************************************************************
     518                 :             : 
     519                 :             :  ! Workaround for XLF
     520                 :           0 :  myfh = fh
     521                 :             : 
     522   [ #  #  #  # ]:           0 :  if (bufsz < PRODUCT(subsizes) ) then
     523                 :           0 :    ABI_ERROR("bufsz is too small")
     524                 :             :  end if
     525                 :             : 
     526         [ #  # ]:           0 :  if (sc_mode==xmpio_single) then
     527         [ #  # ]:           0 :   ABI_CHECK(comm==xmpi_comm_self,"comm != xmpi_comm_self")
     528         [ #  # ]:           0 :  else if (sc_mode==xmpio_collective) then
     529                 :             :    continue
     530                 :             :  else
     531                 :           0 :    ABI_ERROR("Wrong sc_mode")
     532                 :             :  end if
     533                 :             : 
     534                 :           0 :  size_x  = sizes(1)
     535                 :           0 :  size_y  = sizes(2)
     536                 :           0 :  subs_x  = subsizes(1)
     537                 :           0 :  subs_y  = subsizes(2)
     538                 :           0 :  subs_xy = subs_x * subs_y
     539                 :           0 :  start_x = starts(1)
     540                 :           0 :  start_y = starts(2)
     541                 :           0 :  start_z = starts(3)
     542                 :           0 :  stop_z  = start_z + subsizes(3)-1 ! last column to read
     543                 :             : 
     544                 :             :  ! Read rows in blocks of size nz_chunk:
     545                 :             :  ! MPI-IO crashes if we try to read data > 2Gb in a single call.
     546                 :           0 :  nz2read = subsizes(3)
     547                 :           0 :  nz_chunk = nz2read
     548         [ #  # ]:           0 :  if ( (one*subs_xy*nz2read*xmpi_bsize_dpc) > chunk_bsize) then
     549                 :           0 :    nz_chunk = chunk_bsize / (subs_xy*xmpi_bsize_dpc)
     550                 :             :    !if (nz_chunk == 0) nz_chunk = 50
     551                 :             :  end if
     552                 :             : 
     553                 :           0 :  call xmpi_min(nz_chunk,ierr,comm,mpierr)
     554         [ #  # ]:           0 :  if (ierr == 0) then
     555                 :           0 :    ierr = 1
     556                 :             :    RETURN
     557                 :             :  end if
     558                 :           0 :  ierr = 0
     559                 :             : 
     560                 :             :  ! my_ncalls : number of read needed to fill my cbuffer.
     561                 :             :  ! ncalls    : max number of read in comm (needed for collective operations).
     562                 :           0 :  my_ncalls = nz2read / nz_chunk
     563                 :           0 :  zrest = MOD(nz2read, nz_chunk)
     564         [ #  # ]:           0 :  if (zrest /= 0) my_ncalls = my_ncalls + 1
     565                 :             : 
     566                 :           0 :  call xmpi_max(my_ncalls,ncalls,comm,mpierr)
     567                 :             : 
     568                 :             :  ! Compute arrays used to define the file view.
     569   [ #  #  #  #  :           0 :  ABI_MALLOC(my_subsizes,(3,ncalls))
          #  #  #  #  #  
                #  #  # ]
     570   [ #  #  #  #  :           0 :  ABI_MALLOC(my_starts,(3,ncalls))
             #  #  #  # ]
     571   [ #  #  #  #  :           0 :  ABI_MALLOC(my_basead,(ncalls))
          #  #  #  #  #  
                #  #  # ]
     572                 :             : 
     573         [ #  # ]:           0 :  do icall=1,my_ncalls
     574         [ #  # ]:           0 :    if (icall*nz_chunk <= nz2read) then
     575         [ #  # ]:           0 :      my_subsizes(:,icall) = (/subs_x, subs_y, nz_chunk/)
     576         [ #  # ]:           0 :      my_starts(:,icall) = (/start_x, start_y, (icall-1) * nz_chunk + start_z/)
     577                 :           0 :      my_basead(icall) = 1 + (icall-1)*subs_xy*nz_chunk
     578                 :             :    else
     579                 :             :      ! Two cases:
     580                 :             :      ! 1) nz2read > nz_chunk and not divisible by nz2read
     581                 :             :      ! 2) nz2read < nz_chunk
     582         [ #  # ]:           0 :      my_subsizes(:,icall) = (/subs_x, subs_y, zrest/)
     583         [ #  # ]:           0 :      if (nz2read >= nz_chunk) then
     584         [ #  # ]:           0 :        my_starts(:,icall) = (/start_x, start_y, stop_z-zrest+1/)
     585                 :           0 :        my_basead(icall) = 1 + (nz2read-zrest) * subs_xy
     586                 :             :      else
     587         [ #  # ]:           0 :        my_starts(:,icall) = starts
     588                 :           0 :        my_basead(icall) = 1
     589                 :             :      end if
     590                 :             :    end if
     591                 :             :  end do
     592                 :             :  !write(std_out,*)" >>>> my_ncalls, ncalls, nz2read, nz_chunk ",my_ncalls,ncalls,nz2read,nz_chunk
     593                 :             : 
     594         [ #  # ]:           0 :  do icall=1,ncalls
     595                 :             : 
     596         [ #  # ]:           0 :    if (icall <= my_ncalls) then
     597         [ #  # ]:           0 :      call_subsizes = my_subsizes(:,icall)
     598         [ #  # ]:           0 :      call_starts   = my_starts(:,icall)
     599                 :           0 :      ptr           = my_basead(icall)
     600                 :             :    else
     601                 :             :      ! Fake values needed to call read_all collectively.
     602         [ #  # ]:           0 :      call_subsizes = (/subs_x, 1, 1/)
     603                 :           0 :      call_starts   = starts
     604                 :             :    end if
     605         [ #  # ]:           0 :    ncount = PRODUCT(call_subsizes)
     606                 :             :    !write(std_out,*)"  icall,ptr, ncount, ",icall,ptr,ncount
     607                 :             :    !write(std_out,*)"  call_starts",call_starts
     608                 :             :    !write(std_out,*)"  call_subsizes",call_subsizes
     609                 :             : 
     610                 :             :    ! Create subarry file view.
     611                 :             :    call xmpio_create_fsubarray_3D(sizes,call_subsizes,call_starts,MPI_DOUBLE_COMPLEX,&
     612                 :           0 : &    fsub_type,my_offpad,mpierr)
     613                 :           0 :    ABI_CHECK_MPI(mpierr,"fsubarray_3D")
     614                 :             : 
     615                 :             :    ! Update the offset.
     616                 :           0 :    my_offset = offset + my_offpad
     617                 :             : 
     618                 :           0 :    call MPI_FILE_SET_VIEW(myfh, my_offset, MPI_BYTE, fsub_type, 'native', MPI_INFO_NULL, mpierr)
     619                 :           0 :    ABI_CHECK_MPI(mpierr,"SET_VIEW")
     620                 :             : 
     621                 :           0 :    call MPI_TYPE_FREE(fsub_type, mpierr)
     622                 :           0 :    ABI_CHECK_MPI(mpierr,"MPI_TYPE_FREE")
     623                 :             : 
     624         [ #  # ]:           0 :    if (sc_mode==xmpio_collective) then
     625                 :             :      ! Collective read
     626         [ #  # ]:           0 :      if (icall <= my_ncalls) then
     627         [ #  # ]:           0 :        cptr=c_loc(cbuffer(ptr)) ; call c_f_pointer(cptr,buf_ptr,[ncount])
     628         [ #  # ]:           0 :        call MPI_FILE_READ_ALL(myfh, buf_ptr, ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     629                 :             :      else
     630   [ #  #  #  #  :           0 :        ABI_MALLOC(dummy_cbuf,(subs_x))
          #  #  #  #  #  
                #  #  # ]
     631                 :           0 :        call MPI_FILE_READ_ALL(myfh, dummy_cbuf, ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     632         [ #  # ]:           0 :        ABI_FREE(dummy_cbuf)
     633                 :             :      end if
     634                 :           0 :      ABI_CHECK_MPI(mpierr,"FILE_READ_ALL")
     635                 :             : 
     636                 :             :    else
     637                 :             :      ! Individual read.
     638         [ #  # ]:           0 :      cptr=c_loc(cbuffer(ptr)) ; call c_f_pointer(cptr,buf_ptr,[ncount])
     639         [ #  # ]:           0 :      call MPI_FILE_READ(myfh, buf_ptr, ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     640                 :           0 :      ABI_CHECK_MPI(mpierr,"FILE_READ")
     641                 :             :    end if
     642                 :             : 
     643                 :             :  end do
     644                 :             : 
     645         [ #  # ]:           0 :  ABI_FREE(my_subsizes)
     646         [ #  # ]:           0 :  ABI_FREE(my_starts)
     647         [ #  # ]:           0 :  ABI_FREE(my_basead)
     648                 :             : 
     649                 :           0 : end subroutine mpiotk_read_fsuba_dpc3D
     650                 :             : !!***
     651                 :             : 
     652                 :             : !----------------------------------------------------------------------
     653                 :             : 
     654                 :             : !!****f* m_mpiotk/mpiotk_read_fsuba_dpc4D
     655                 :             : !! NAME
     656                 :             : !!  mpiotk_read_fsuba_dpc4D
     657                 :             : !!
     658                 :             : !! FUNCTION
     659                 :             : !!  Reading a block of contiguous data stored in a 4D matrix.
     660                 :             : !!  Data is placed within Fortran records. Target: complex data stored in a complex array.
     661                 :             : !!
     662                 :             : !! NOTES
     663                 :             : !!  The value of ierr should always be checked by the caller
     664                 :             : !!
     665                 :             : !! INPUTS
     666                 :             : !!  fh = MPI-IO file handler.
     667                 :             : !!  offset =
     668                 :             : !!  sizes(4)
     669                 :             : !!  subsizes(4)
     670                 :             : !!  starts(4)
     671                 :             : !!  bufsz = dimension of cbuffer
     672                 :             : !!  chunk_bsize =
     673                 :             : !!  comm = MPI communicator
     674                 :             : !!  sc_mode= MPI-IO option
     675                 :             : !!    xmpio_single     ==> for reading by current proc.
     676                 :             : !!    xmpio_collective ==> for collective reading.
     677                 :             : !!
     678                 :             : !! OUTPUTS
     679                 :             : !!  cbuffer(bufsz)
     680                 :             : !!  ierr=status error. A non zero value indicates that chunk_bsize is smaller that the fortran record
     681                 :             : !!    and therefore bufsz has not been read.
     682                 :             : !!
     683                 :             : !! SOURCE
     684                 :             : 
     685                 :           0 : subroutine mpiotk_read_fsuba_dpc4D(fh,offset,sizes,subsizes,starts,bufsz,cbuffer,chunk_bsize,sc_mode,comm,ierr)
     686                 :             : 
     687                 :             : !Arguments ------------------------------------
     688                 :             : !scalars
     689                 :             :  integer,intent(in) :: fh,comm,bufsz,sc_mode
     690                 :             :  integer,intent(out) :: ierr
     691                 :             :  integer(XMPI_OFFSET_KIND),intent(in) :: offset,chunk_bsize
     692                 :             : !arrays
     693                 :             :  integer,intent(in) :: sizes(4),subsizes(4),starts(4)
     694                 :             :  complex(dp),intent(out),target :: cbuffer(bufsz)
     695                 :             : 
     696                 :             : !Local variables-------------------------------
     697                 :             : !scalars
     698                 :             :  integer :: mpierr,na2read,na_chunk,ptr,ncount,myfh
     699                 :             :  integer :: fsub_type,my_ncalls,icall,arest,ncalls
     700                 :             :  integer :: size_x,size_y,size_z,subs_x,subs_y,subs_z,subs_xyz,start_x,start_y,start_z,start_a,stop_a
     701                 :             :  integer(XMPI_OFFSET_KIND) :: my_offset,my_offpad
     702                 :             :  !character(len=500) :: msg
     703                 :             :  type(c_ptr) :: cptr
     704                 :             : !arrays
     705                 :             :  integer :: call_subsizes(4),call_starts(4)
     706                 :           0 :  integer,allocatable :: my_basead(:),my_subsizes(:,:),my_starts(:,:)
     707                 :           0 :  complex(dp),allocatable :: dummy_cbuf(:)
     708                 :           0 :  complex(dp),pointer :: buf_ptr(:)
     709                 :             : !************************************************************************
     710                 :             : 
     711                 :             :  ! Workaround for XLF
     712                 :           0 :  myfh = fh
     713                 :             : 
     714   [ #  #  #  # ]:           0 :  if (bufsz < PRODUCT(subsizes) ) then
     715                 :           0 :    ABI_ERROR("bufsz is too small")
     716                 :             :  end if
     717                 :             : 
     718         [ #  # ]:           0 :  if (sc_mode==xmpio_single) then
     719         [ #  # ]:           0 :   ABI_CHECK(comm==xmpi_comm_self,"comm != xmpi_comm_self")
     720         [ #  # ]:           0 :  else if (sc_mode==xmpio_collective) then
     721                 :             :    continue
     722                 :             :  else
     723                 :           0 :    ABI_ERROR("Wrong sc_mode")
     724                 :             :  end if
     725                 :             : 
     726                 :           0 :  size_x  = sizes(1)
     727                 :           0 :  size_y  = sizes(2)
     728                 :           0 :  size_z  = sizes(3)
     729                 :             : 
     730                 :           0 :  subs_x  = subsizes(1)
     731                 :           0 :  subs_y  = subsizes(2)
     732                 :           0 :  subs_z  = subsizes(3)
     733                 :           0 :  subs_xyz = subs_x * subs_y * subs_z
     734                 :             : 
     735                 :           0 :  start_x = starts(1)
     736                 :           0 :  start_y = starts(2)
     737                 :           0 :  start_z = starts(3)
     738                 :           0 :  start_a = starts(4)
     739                 :           0 :  stop_a  = start_a + subsizes(4)-1 ! last column to read
     740                 :             : 
     741                 :             :  ! Read rows in blocks of size na_chunk:
     742                 :             :  ! MPI-IO crashes if we try to read data > 2Gb in a single call.
     743                 :           0 :  na2read = subsizes(4)
     744                 :           0 :  na_chunk = na2read
     745         [ #  # ]:           0 :  if ( (one*subs_xyz*na2read*xmpi_bsize_dpc) > chunk_bsize) then
     746                 :           0 :    na_chunk = chunk_bsize / (subs_xyz*xmpi_bsize_dpc)
     747                 :             :  end if
     748                 :             : 
     749                 :           0 :  call xmpi_min(na_chunk,ierr,comm,mpierr)
     750         [ #  # ]:           0 :  if (ierr == 0) then
     751                 :           0 :    ierr = 1
     752                 :             :    RETURN
     753                 :             :  end if
     754                 :           0 :  ierr = 0
     755                 :             : 
     756                 :             :  ! my_ncalls : number of read needed to fill my cbuffer.
     757                 :             :  ! ncalls    : max number of read in comm (needed for collective operations).
     758                 :           0 :  my_ncalls = na2read / na_chunk
     759                 :           0 :  arest = MOD(na2read, na_chunk)
     760         [ #  # ]:           0 :  if (arest /= 0) my_ncalls = my_ncalls + 1
     761                 :             : 
     762                 :           0 :  call xmpi_max(my_ncalls,ncalls,comm,mpierr)
     763                 :             : 
     764                 :             :  ! Compute arrays used to define the file view.
     765   [ #  #  #  #  :           0 :  ABI_MALLOC(my_subsizes,(4,ncalls))
          #  #  #  #  #  
                #  #  # ]
     766   [ #  #  #  #  :           0 :  ABI_MALLOC(my_starts,(4,ncalls))
             #  #  #  # ]
     767   [ #  #  #  #  :           0 :  ABI_MALLOC(my_basead,(ncalls))
          #  #  #  #  #  
                #  #  # ]
     768                 :             : 
     769         [ #  # ]:           0 :  do icall=1,my_ncalls
     770                 :             : 
     771         [ #  # ]:           0 :    if (icall*na_chunk <= na2read) then
     772         [ #  # ]:           0 :      my_subsizes(:,icall) = (/subs_x, subs_y, subs_z, na_chunk/)
     773         [ #  # ]:           0 :      my_starts(:,icall) = (/start_x, start_y, start_z, (icall-1) * na_chunk + start_a/)
     774                 :           0 :      my_basead(icall) = 1 + (icall-1)*subs_xyz*na_chunk
     775                 :             :    else
     776                 :             :      ! Two cases:
     777                 :             :      ! 1) na2read > na_chunk and not divisible by na2read
     778                 :             :      ! 2) na2read < na_chunk
     779         [ #  # ]:           0 :      my_subsizes(:,icall) = (/subs_x, subs_y, subs_z, arest/)
     780         [ #  # ]:           0 :      if (na2read >= na_chunk) then
     781         [ #  # ]:           0 :        my_starts(:,icall) = (/start_x, start_y, start_z, stop_a-arest+1/)
     782                 :           0 :        my_basead(icall) = 1 + (na2read-arest) * subs_xyz
     783                 :             :      else
     784         [ #  # ]:           0 :        my_starts(:,icall) = starts
     785                 :           0 :        my_basead(icall) = 1
     786                 :             :      end if
     787                 :             :    end if
     788                 :             :  end do
     789                 :             :  !write(std_out,*)" >>>> my_ncalls, ncalls, na2read, na_chunk ",my_ncalls,ncalls,na2read,na_chunk
     790                 :             : 
     791         [ #  # ]:           0 :  do icall=1,ncalls
     792                 :             : 
     793         [ #  # ]:           0 :    if (icall <= my_ncalls) then
     794         [ #  # ]:           0 :      call_subsizes = my_subsizes(:,icall)
     795         [ #  # ]:           0 :      call_starts   = my_starts(:,icall)
     796                 :           0 :      ptr           = my_basead(icall)
     797                 :             :    else
     798                 :             :      ! Fake values needed to call read_all collectively.
     799         [ #  # ]:           0 :      call_subsizes = (/subs_x, 1, 1, 1/)
     800                 :           0 :      call_starts   = starts
     801                 :             :    end if
     802         [ #  # ]:           0 :    ncount = PRODUCT(call_subsizes)
     803                 :             :    !
     804                 :             :    !write(std_out,*)"  icall,ptr, ncount, ",icall,ptr,ncount
     805                 :             :    !write(std_out,*)"  call_starts",call_starts
     806                 :             :    !write(std_out,*)"  call_subsizes",call_subsizes
     807                 :             :    !
     808                 :             :    ! Create subarry file view.
     809                 :             :    call xmpio_create_fsubarray_4D(sizes,call_subsizes,call_starts,MPI_DOUBLE_COMPLEX,&
     810                 :           0 : &    fsub_type,my_offpad,mpierr)
     811                 :           0 :    ABI_CHECK_MPI(mpierr,"fsubarray_4D")
     812                 :             : 
     813                 :             :    ! Update the offset.
     814                 :           0 :    my_offset = offset + my_offpad
     815                 :             : 
     816                 :           0 :    call MPI_FILE_SET_VIEW(myfh, my_offset, MPI_BYTE, fsub_type, 'native', MPI_INFO_NULL, mpierr)
     817                 :           0 :    ABI_CHECK_MPI(mpierr,"SET_VIEW")
     818                 :             : 
     819                 :           0 :    call MPI_TYPE_FREE(fsub_type, mpierr)
     820                 :           0 :    ABI_CHECK_MPI(mpierr,"MPI_TYPE_FREE")
     821                 :             : 
     822         [ #  # ]:           0 :    if (sc_mode==xmpio_collective) then
     823                 :             :      ! Collective read
     824         [ #  # ]:           0 :      if (icall <= my_ncalls) then
     825         [ #  # ]:           0 :        cptr=c_loc(cbuffer(ptr)) ; call c_f_pointer(cptr,buf_ptr,[ncount])
     826                 :           0 :        call MPI_FILE_READ_ALL(myfh, cbuffer(ptr:), ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     827                 :             :      else
     828   [ #  #  #  #  :           0 :        ABI_MALLOC(dummy_cbuf,(subs_x))
          #  #  #  #  #  
                #  #  # ]
     829                 :           0 :        call MPI_FILE_READ_ALL(myfh, dummy_cbuf, ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     830         [ #  # ]:           0 :        ABI_FREE(dummy_cbuf)
     831                 :             :      end if
     832                 :           0 :      ABI_CHECK_MPI(mpierr,"FILE_READ_ALL")
     833                 :             :    else
     834                 :             :      ! Individual read.
     835         [ #  # ]:           0 :      cptr=c_loc(cbuffer(ptr)) ; call c_f_pointer(cptr,buf_ptr,[ncount])
     836         [ #  # ]:           0 :      call MPI_FILE_READ(myfh, buf_ptr, ncount, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpierr)
     837                 :           0 :      ABI_CHECK_MPI(mpierr,"FILE_READ")
     838                 :             :    end if
     839                 :             : 
     840                 :             :  end do
     841                 :             : 
     842         [ #  # ]:           0 :  ABI_FREE(my_subsizes)
     843         [ #  # ]:           0 :  ABI_FREE(my_starts)
     844         [ #  # ]:           0 :  ABI_FREE(my_basead)
     845                 :             : 
     846                 :           0 : end subroutine mpiotk_read_fsuba_dpc4D
     847                 :             : !!***
     848                 :             : #endif
     849                 :             : 
     850                 :             : END MODULE m_mpiotk
     851                 :             : !!***
        

Generated by: LCOV version 2.3-1