LCOV - code coverage report
Current view: top level - src/51_manage_mpi - m_wffile.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 39.7 % 938 372
Test Date: 2026-09-21 13:49:52 Functions: 39.1 % 46 18

            Line data    Source code
       1              : !!****m* ABINIT/m_wffile
       2              : !! NAME
       3              : !!  m_wffile
       4              : !!
       5              : !! FUNCTION
       6              : !!  This module provides the definition of the wffile_type used to WF file data.
       7              : !!  As the type contains MPI-dependent fields, it has to be declared in a MPI-managed directory.
       8              : !!
       9              : !! COPYRIGHT
      10              : !! Copyright (C) 2009-2026 ABINIT group (MT,MB,MVer,ZL,MD)
      11              : !! This file is distributed under the terms of the
      12              : !! GNU General Public License, see ~abinit/COPYING
      13              : !! or http://www.gnu.org/copyleft/gpl.txt .
      14              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
      15              : !!
      16              : !! NOTES
      17              : !! wffile_type: a handler for dealing with the IO of a wavefunction file
      18              : !!
      19              : !! SOURCE
      20              : 
      21              : #if defined HAVE_CONFIG_H
      22              : #include "config.h"
      23              : #endif
      24              : 
      25              : #include "abi_common.h"
      26              : 
      27              : MODULE m_wffile
      28              : 
      29              :  use defs_basis
      30              :  use m_errors
      31              :  use m_abicore
      32              :  USE_MPI
      33              :  use m_xmpi
      34              :  use m_nctk
      35              :  use netcdf
      36              : 
      37              :  use defs_abitypes, only : MPI_Type
      38              :  use m_io_tools,   only : mvrecord, open_file
      39              :  use m_fstrings,   only : toupper, endswith, sjoin
      40              :  use iso_c_binding
      41              : 
      42              :  implicit none
      43              : 
      44              :  private
      45              : 
      46              : #ifdef HAVE_MPI1
      47              : include 'mpif.h'
      48              : #endif
      49              : 
      50              : #define DEV_DEBUG_THIS 0
      51              : 
      52              : !public procedures.
      53              :  public :: WffOpen
      54              :  public :: wffclose
      55              :  public :: wffdelete
      56              :  public :: wffkg
      57              :  public :: wffoffset
      58              :  public :: wffreaddatarec  !  Generic subroutines to read data in one record of a wavefunction file
      59              :  public :: wffreadnpwrec
      60              :  public :: wffreadskiprec
      61              :  public :: wffreadwrite_mpio
      62              :  public :: wffwritedatarec !  Generic subroutines to write data in one record of a wavefunction file
      63              :  public :: wffwritenpwrec
      64              :  public :: xderiveread     !  Generic subroutines to read wf files.
      65              :  public :: xmpi_read_int2d
      66              :  public :: xderivewrite
      67              : 
      68              :  public :: getRecordMarkerLength_wffile
      69              :  public :: xnullifyOff
      70              :  public :: xmoveOff
      71              :  public :: xderiveWRecEnd
      72              :  public :: xderiveWRecInit
      73              :  public :: xderiveRRecEnd
      74              :  public :: xderiveRRecInit
      75              : #if defined HAVE_MPI_IO
      76              :  public :: rwRecordMarker
      77              : #endif
      78              :  public :: clsopn
      79              :  public :: wff_usef90
      80              :  public :: xdefineOff
      81              : !!***
      82              : 
      83              : !Generic interface of the routines wffreaddatarec
      84              :  interface wffreaddatarec
      85              :    module procedure WffReadDataRec_dp1d
      86              :    module procedure WffReadDataRec_dp2d
      87              :  end interface wffreaddatarec
      88              : 
      89              :  !Generic interface of the routines wffwritedatarec
      90              :  interface wffwritedatarec
      91              :    module procedure WffWriteDataRec_int2d
      92              :    module procedure WffWriteDataRec_dp1d
      93              :    module procedure WffWriteDataRec_dp2d
      94              :  end interface
      95              : 
      96              :  !Generic interface of the routines xderiveread
      97              :  interface xderiveread
      98              :    module procedure xderiveRead_int             !  read integer value
      99              :    module procedure xderiveRead_int1d           !  read integer array 1d
     100              :    module procedure xderiveRead_int2d           !  read integer array 2d
     101              :    module procedure xderiveRead_dp              !  read double precision value
     102              :    module procedure xderiveRead_dp1d            !  read double precision array 1d
     103              :    module procedure xderiveRead_dp2d            !  read double precision array 2d
     104              :    module procedure xderiveRead_int2d_displ     !  read integer array 2d non-contiguous
     105              :    module procedure xderiveRead_dp2d_displ      !  read double precision array 2d non-contiguous
     106              :    module procedure xderiveReadVal_char         !  read character string
     107              :    module procedure xmpi_read_int2d
     108              :  end interface xderiveread
     109              : 
     110              : !Generic interface of the routines xderivewrite
     111              :  interface xderivewrite
     112              :   module procedure xderiveWrite_int             ! write integer value
     113              :   module procedure xderiveWrite_int1d           ! write integer array 1d
     114              :   module procedure xderiveWrite_int2d           ! write integer array 2d
     115              :   module procedure xderiveWrite_dp              ! write double precision value
     116              :   module procedure xderiveWrite_dp1d            ! write double precision array 1d
     117              :   module procedure xderiveWrite_dp2d            ! write double precision array 2d
     118              :   module procedure xderiveWrite_dp2d_seq        ! write double precision array 2d in sequential
     119              :   module procedure xderiveWrite_int2d_displ     ! write integer array 2d non contiguous
     120              :   module procedure xderiveWrite_dp2d_displ      ! write double precision array 2d non contiguous
     121              :   module procedure xderiveWrite_char            ! write character string
     122              :  end interface xderivewrite
     123              : 
     124              : !!****t* m_wffile/wffile_type
     125              : !! NAME
     126              : !! wffile_type
     127              : !!
     128              : !! FUNCTION
     129              : !! This structure datatype is a handler for dealing with the IO of a
     130              : !! wavefunction file.
     131              : !! It contains, among other things, the method of access to the file
     132              : !! (standard F90 read/write, or NetCDF call, or MPI IO), the unit number
     133              : !! if applicable, the filename, the information on the
     134              : !! parallelism, etc ...
     135              : !!
     136              : !! SOURCE
     137              : 
     138              :  type, public :: wffile_type
     139              : 
     140              : ! WARNING : if you modify this datatype, please check there there is no creation/destruction/copy routine,
     141              : ! declared in another part of ABINIT, that might need to take into account your modification.
     142              : 
     143              : ! Integer scalar
     144              :   integer :: unwff
     145              :    ! unwff  unit number of unformatted wavefunction disk file
     146              : 
     147              :   integer :: iomode
     148              :    ! Method to access the wavefunction file
     149              :    !   IO_MODE_FORTRAN for usual Fortran IO routines
     150              :    !   IO_MODE_FORTRAN_MASTER if usual Fortran IO routines, but only the master node in the parallel case
     151              :    !   IO_MODE_MPI if MPI/IO routines (this access method is only available in parallel)
     152              :    !   IO_MODE_NETCDF if NetCDF routines (obsolete, do not use)
     153              :    !   IO_MODE_ETSF, NetCDF format read via etsf-io.
     154              : 
     155              :   integer :: formwff
     156              :    ! formwff=format of the eigenvalues
     157              :    !   -1 => not used
     158              :    !    0 => vector of eigenvalues
     159              :    !    1 => hermitian matrix of eigenvalues
     160              : 
     161              :   integer :: headform
     162              :    ! headform=format of the header
     163              : 
     164              :   integer ::  kgwff
     165              :    ! kgwff  if 1 , read or write kg_k ; if 0, do not care about kg_k
     166              : 
     167              : ! Character
     168              :   character(len=fnlen) :: fname
     169              :    ! filename (if available)
     170              : 
     171              : ! In case of MPI parallel use
     172              :   integer :: master
     173              :    ! index of the processor master of the IO procedure when the WffOpen call is issued
     174              : 
     175              :   integer :: me
     176              :    ! index of my processor in the spaceComm communicator
     177              : 
     178              :   integer :: me_mpiio
     179              :    ! index of my processor in the spaceComm_mpiio communicator
     180              : 
     181              :   integer :: nproc
     182              :    ! number of processors that will have access to the file
     183              : 
     184              :   integer :: spaceComm
     185              :    ! space communicator for the standard FORTRAN access to the file
     186              : 
     187              :   integer :: spaceComm_mpiio
     188              :    ! space communicator for the MPI/IO access to the file
     189              : 
     190              : ! In case of MPI/IO : additional information
     191              :   integer :: fhwff
     192              :    ! file handle used to access the file with MPI/IO.
     193              : 
     194              :   integer(kind=XMPI_OFFSET_KIND) :: nbOct_int,nbOct_dp,nbOct_ch
     195              :    ! nbOct_int byte number of int value
     196              :    ! nbOct_dp  byte number of dp value
     197              :    ! nbOct_ch  byte number of character value
     198              : 
     199              :   integer(kind=XMPI_OFFSET_KIND) :: nbOct_recMarker
     200              :    ! byte number of Fortran file record markers
     201              : 
     202              :   integer(kind=XMPI_OFFSET_KIND) :: lght_recs
     203              :    ! length of record
     204              : 
     205              :   integer :: marker_mpi_type
     206              :    ! MPI Datatype for Fortran record markers
     207              : 
     208              :   integer(kind=XMPI_OFFSET_KIND)  :: offwff,off_recs
     209              :    ! offwff   offset position of unformatted wavefunction disk file
     210              :    ! off_recs offset position of start record
     211              :    ! (used in parallel MPI-IO)
     212              : 
     213              :   integer :: offset_mpi_type
     214              :    ! MPI Datatype for INTEGER(kind=MPI_OFFSET_KIND)
     215              : 
     216              :  end type wffile_type
     217              : 
     218              : 
     219              : CONTAINS
     220              : !!***
     221              : 
     222              : !----------------------------------------------------------------------
     223              : 
     224              : !!****f* m_wffile/getRecordMarkerLength_wffile
     225              : !! NAME
     226              : !!  getRecordMarkerLength_wffile
     227              : !!
     228              : !! FUNCTION
     229              : !!  Get the record marker length of the FORTRAN header of a file to access it in MPI/IO.
     230              : !!  This routine assumes that the header has been written (and flushed) in the file.
     231              : !!
     232              : !! SIDE EFFECTS
     233              : !!  wff=<type(wffile_type)>=structured info for reading/writing the wavefunctions
     234              : !!      only%nbOct_recMarker is changed
     235              : !!
     236              : !! SOURCE
     237              : 
     238            0 : subroutine getRecordMarkerLength_wffile(wff)
     239              : 
     240              : !Arguments ------------------------------------
     241              : !scalars
     242              :  type(wffile_type),intent(inout) :: wff
     243              : 
     244              : !Local variables-------------------------------
     245              : #if defined HAVE_MPI_IO
     246              : !scalars
     247              :  integer :: ierr,ii,iimax
     248              :  integer(kind=MPI_OFFSET_KIND)  :: posit,rml
     249              :  character(len=500) :: msg
     250              : !arrays
     251              :  integer :: headform(1),statux(MPI_STATUS_SIZE)
     252              :  integer(kind=MPI_OFFSET_KIND)  :: off(1)
     253              : #endif
     254              : 
     255              : !************************************************************************
     256              : 
     257              : #ifdef DEV_DEBUG_THIS
     258              :  return
     259              :  ! Already done in WffOpen
     260              : #endif
     261              : 
     262              : #if defined HAVE_MPI_IO
     263              : 
     264              :  if (wff%nbOct_recMarker>0) return
     265              : 
     266              : !wff%nbOct_recMarker=4;return
     267              : !call flush(wff%unwff)
     268              : !call MPI_FILE_SYNC(wff%fhwff,ierr)
     269              : 
     270              : !Only master do that
     271              :  ierr=0
     272              :  if (wff%master==wff%me) then
     273              : 
     274              : ! Define number of INTEGER types to be tested
     275              : #if defined HAVE_FC_INT_QUAD
     276              :    iimax=4
     277              : #else
     278              :    iimax=3
     279              : #endif
     280              : 
     281              : ! Try to read headform
     282              :    rml=-1;ii=0
     283              :    do while (wff%nbOct_recMarker<=0.and.ii<iimax)
     284              :      ii=ii+1
     285              :      if (ii==1) rml=4
     286              :      if (ii==2) rml=8
     287              :      if (ii==3) rml=2
     288              :      if (ii==4) rml=16
     289              :      posit=rml+6*wff%nbOct_ch
     290              :      call MPI_FILE_READ_AT(wff%fhwff,posit,headform,1,MPI_INTEGER,statux,ierr)
     291              :      if (ierr==MPI_SUCCESS) then
     292              :        if (headform(1)==wff%headform) wff%nbOct_recMarker=rml
     293              :      end if
     294              :     end do
     295              : 
     296              :     if (ierr/=MPI_SUCCESS) then
     297              :      ABI_BUG("Header problem")
     298              :     end if
     299              : 
     300              :    if (ii==iimax.and.wff%nbOct_recMarker<=0) then
     301              : !      if (iimax>=4) then
     302              : !        write(msg,'(3a)') &
     303              : ! &        ' Your architecture is not able to handle 16, 8, 4 or 2-bytes FORTRAN file record markers !',ch10,&
     304              : ! &        ' You cannot use ABINIT and MPI/IO.'
     305              : !      else
     306              : !        write(msg,'(3a)') &
     307              : ! &        '  Your architecture is not able to handle 8, 4 or 2-bytes FORTRAN file record markers !',ch10,&
     308              : ! &        '  You cannot use ABINIT and MPI/IO.'
     309              : !      end if
     310              :      write(msg,'(13a)') &
     311              : &      ' Error during FORTRAN file record marker detection:',ch10,&
     312              : &      ' It was not possible to read/write a small file!',ch10,&
     313              : &      ' ACTION: check your access permissions to the file system.',ch10,&
     314              : &      ' Common sources of this problem:',ch10,&
     315              : &      '  - Quota limit exceeded,',ch10,&
     316              : &      '  - R/W incorrect permissions,',ch10,&
     317              : &      '  - WFK file requested as input (irdwfk=1/getwfk=1) but not existing ...'
     318              :      ABI_ERROR(msg)
     319              :    else
     320              :      write(msg,'(a,i0)') &
     321              : &     '  MPI/IO accessing FORTRAN file header: detected record mark length=',wff%nbOct_recMarker
     322              :      ABI_COMMENT(msg)
     323              :    end if
     324              : 
     325              :  end if  ! me=master
     326              : 
     327              : !Broadcast record marker length
     328              :  if (wff%spaceComm/=MPI_COMM_SELF) then
     329              :    off(1)=wff%nbOct_recMarker
     330              :    call MPI_BCAST(off,1,wff%offset_mpi_type,wff%master,wff%spaceComm,ierr)
     331              :    wff%nbOct_recMarker=off(1)
     332              :  end if
     333              : 
     334              : !Select MPI datatype for markers
     335              :  if (wff%nbOct_recMarker==4) then
     336              :    wff%marker_mpi_type=MPI_INTEGER4
     337              :  else if (wff%nbOct_recMarker==8) then
     338              :    wff%marker_mpi_type=MPI_INTEGER8
     339              : #if defined HAVE_FC_INT_QUAD && defined HAVE_MPI_INTEGER16
     340              :  else if (wff%nbOct_recMarker==16) then
     341              :    wff%marker_mpi_type=MPI_INTEGER16
     342              : #endif
     343              :  else if (wff%nbOct_recMarker==2) then
     344              :    wff%marker_mpi_type=MPI_INTEGER2
     345              :  end if
     346              : 
     347              : #endif
     348              : 
     349              :  RETURN
     350              :  ABI_UNUSED(wff%me)
     351              : 
     352              : end subroutine getRecordMarkerLength_wffile
     353              : !!***
     354              : 
     355              : !----------------------------------------------------------------------
     356              : 
     357              : !!****f* m_wffile/rwRecordMarker
     358              : !! NAME
     359              : !!  rwRecordMarker
     360              : !!
     361              : !! FUNCTION
     362              : !!  Read/Write a record marker in a FORTRAN file at a given file pointer position.
     363              : !!  This is needed to access data in a FORTRAN file with MPI/IO.
     364              : !!
     365              : !! INPUTS
     366              : !!  option=1 for reading by current proc
     367              : !!         2 for writing by current proc
     368              : !!         3 for reading by all procs
     369              : !!         4 for writing by all procs
     370              : !!  posit= position of the MPI/IO file pointer
     371              : !!  wff=<type(wffile_type)>=structured info for reading/writing
     372              : !!     Use here only:
     373              : !!       wff%fhwff= handle of the MPI/IO file
     374              : !!       wff%nbOct_recMarker= length of Fortran record markers
     375              : !!
     376              : !! OUTPUT
     377              : !!  ierr= error code
     378              : !!
     379              : !! SIDE EFFECTS
     380              : !!  posit= position of the MPI/IO file pointer
     381              : !!         updated after the reading (with the length of the record)
     382              : !!  recordmarker= content of the record marker
     383              : !!
     384              : !! SOURCE
     385              : 
     386              : #if defined HAVE_MPI_IO
     387              : 
     388          370 : subroutine rwRecordMarker(option,posit,recordmarker,wff,ierr)
     389              : 
     390              : !Arguments ------------------------------------
     391              : !scalars
     392              :  integer,intent(in) :: option
     393              :  integer(kind=MPI_OFFSET_KIND),intent(inout) :: posit,recordmarker
     394              :  integer,intent(out) :: ierr
     395              :  type(wffile_type),intent(inout) :: wff
     396              : 
     397              : !Local variables-------------------------------
     398              : !scalars
     399              :  integer(kind=2)  :: delim_record2(1)
     400              :  integer(kind=4)  :: delim_record4(1)
     401              :  integer(kind=8)  :: delim_record8(1)
     402              : #if defined HAVE_FC_INT_QUAD
     403              :  integer(kind=16) :: delim_record16(1)
     404              : #endif
     405              : !character(len=500) :: msg
     406              : !arrays
     407              :  integer  :: statux(MPI_STATUS_SIZE)
     408              : 
     409              : !************************************************************************
     410              : 
     411          370 :  ierr=0
     412              : 
     413          370 :  if (option==1) then
     414          235 :    if (wff%nbOct_recMarker==4) then
     415          235 :      call MPI_FILE_READ_AT(wff%fhwff,posit,delim_record4,1,wff%marker_mpi_type,statux,ierr)
     416          235 :      recordmarker = delim_record4(1)
     417            0 :    else if (wff%nbOct_recMarker==8) then
     418            0 :      call MPI_FILE_READ_AT(wff%fhwff,posit,delim_record8,1,wff%marker_mpi_type,statux,ierr)
     419            0 :      recordmarker = delim_record8(1)
     420              : #if defined HAVE_FC_INT_QUAD
     421            0 :    else if (wff%nbOct_recMarker==16) then
     422            0 :      call MPI_FILE_READ_AT(wff%fhwff,posit,delim_record16,1,wff%marker_mpi_type,statux,ierr)
     423            0 :      recordmarker = delim_record16(1)
     424              : #endif
     425            0 :    else if (wff%nbOct_recMarker==2) then
     426            0 :      call MPI_FILE_READ_AT(wff%fhwff,posit,delim_record2,1,wff%marker_mpi_type,statux,ierr)
     427            0 :      recordmarker = delim_record2(1)
     428              :    else
     429            0 :      ABI_BUG('Wrong record marker length!')
     430              :    end if
     431              : 
     432          135 :  else if (option==2) then
     433          135 :    if (wff%nbOct_recMarker==4) then
     434          135 :      delim_record4(1) = recordmarker
     435          135 :      call MPI_FILE_WRITE_AT(wff%fhwff,posit,delim_record4,1,wff%marker_mpi_type,statux,ierr)
     436            0 :    else if (wff%nbOct_recMarker==8) then
     437            0 :      delim_record8(1) = recordmarker
     438            0 :      call MPI_FILE_WRITE_AT(wff%fhwff,posit,delim_record8,1,wff%marker_mpi_type,statux,ierr)
     439              : #if defined HAVE_FC_INT_QUAD
     440            0 :    else if (wff%nbOct_recMarker==16) then
     441            0 :      delim_record16(1) = recordmarker
     442            0 :      call MPI_FILE_WRITE_AT(wff%fhwff,posit,delim_record16,1,wff%marker_mpi_type,statux,ierr)
     443              : #endif
     444            0 :    else if (wff%nbOct_recMarker==2) then
     445            0 :      delim_record2(1) = recordmarker
     446            0 :      call MPI_FILE_WRITE_AT(wff%fhwff,posit,delim_record2,1,wff%marker_mpi_type,statux,ierr)
     447              :    else
     448            0 :      ABI_BUG('Wrong record marker length!')
     449              :    end if
     450              : 
     451            0 :  else if (option==3) then
     452            0 :    if (wff%nbOct_recMarker==4) then
     453            0 :      call MPI_FILE_READ_AT_ALL(wff%fhwff,posit,delim_record4,1,wff%marker_mpi_type,statux,ierr)
     454            0 :      recordmarker = delim_record4(1)
     455            0 :    else if (wff%nbOct_recMarker==8) then
     456            0 :      call MPI_FILE_READ_AT_ALL(wff%fhwff,posit,delim_record8,1,wff%marker_mpi_type,statux,ierr)
     457            0 :      recordmarker = delim_record8(1)
     458              : #if defined HAVE_FC_INT_QUAD
     459            0 :    else if (wff%nbOct_recMarker==16) then
     460            0 :      call MPI_FILE_READ_AT_ALL(wff%fhwff,posit,delim_record16,1,wff%marker_mpi_type,statux,ierr)
     461            0 :      recordmarker = delim_record16(1)
     462              : #endif
     463            0 :    else if (wff%nbOct_recMarker==2) then
     464            0 :      call MPI_FILE_READ_AT_ALL(wff%fhwff,posit,delim_record2,1,wff%marker_mpi_type,statux,ierr)
     465            0 :      recordmarker = delim_record2(1)
     466              :    else
     467            0 :      ABI_BUG('Wrong record marker length !')
     468              :    end if
     469              : 
     470            0 :  else if (option==4) then
     471            0 :    if (wff%nbOct_recMarker==4) then
     472            0 :      delim_record4(1) = recordmarker
     473            0 :      call MPI_FILE_WRITE_AT_ALL(wff%fhwff,posit,delim_record4,1,wff%marker_mpi_type,statux,ierr)
     474            0 :    else if (wff%nbOct_recMarker==8) then
     475            0 :      delim_record8(1) = recordmarker
     476            0 :      call MPI_FILE_WRITE_AT_ALL(wff%fhwff,posit,delim_record8,1,wff%marker_mpi_type,statux,ierr)
     477              : #if defined HAVE_FC_INT_QUAD
     478            0 :    else if (wff%nbOct_recMarker==16) then
     479            0 :      delim_record16(1) = recordmarker
     480            0 :      call MPI_FILE_WRITE_AT_ALL(wff%fhwff,posit,delim_record16,1,wff%marker_mpi_type,statux,ierr)
     481              : #endif
     482            0 :    else if (wff%nbOct_recMarker==2) then
     483            0 :      delim_record2(1) = recordmarker
     484            0 :      call MPI_FILE_WRITE_AT_ALL(wff%fhwff,posit,delim_record2,1,wff%marker_mpi_type,statux,ierr)
     485              :    else
     486            0 :      ABI_BUG('Wrong record marker length!')
     487              :    end if
     488              : 
     489              :  else
     490            0 :    ABI_BUG('Wrong value for option!')
     491              :  end if
     492              : 
     493          370 :  posit = posit + recordmarker + 2*wff%nbOct_recMarker
     494              : 
     495          370 : end subroutine rwRecordMarker
     496              : #endif
     497              : !!***
     498              : 
     499              : !------------------------------------------------------------------------------------
     500              : 
     501              : !!****f* m_wffile/xnullifyOff
     502              : !! NAME
     503              : !!  xnullifyOff
     504              : !!
     505              : !! FUNCTION
     506              : !!  In case of MPI I/O, nullify the offset of a WF file
     507              : !!
     508              : !! INPUTS
     509              : !!
     510              : !! OUTPUT
     511              : !!
     512              : !! SIDE EFFECTS
     513              : !!  wff=<type(wffile_type)>=structured info for reading/writing
     514              : !!
     515              : !! SOURCE
     516              : 
     517            0 : subroutine xnullifyOff(wff)
     518              : 
     519              : !Arguments ------------------------------------
     520              :  type(wffile_type),intent(inout) :: wff
     521              : 
     522              : ! *************************************************************************
     523              : 
     524              : #if defined HAVE_MPI_IO
     525            0 :  wff%offwff    = 0
     526            0 :  wff%off_recs  = 0
     527            0 :  wff%lght_recs = 0
     528              : #endif
     529              : 
     530              :  RETURN
     531              :  ABI_UNUSED(wff%me)
     532              : 
     533              : end subroutine xnullifyOff
     534              : !!***
     535              : 
     536              : !------------------------------------------------------------------------------------
     537              : 
     538              : !!****f* m_wffile/xmoveOff
     539              : !! NAME
     540              : !!  xmoveOff
     541              : !!
     542              : !! FUNCTION
     543              : !!  In case of MPI I/O, move the offset of a WF file
     544              : !!
     545              : !! INPUTS
     546              : !!  [n_int] = number if integers to skip
     547              : !!  [n_dp]  = number if double precision reals to skip
     548              : !!  [n_ch]  = number if characters to skip
     549              : !!  [n_mark]= number if record markers to skip
     550              : !!
     551              : !! OUTPUT
     552              : !!
     553              : !! SIDE EFFECTS
     554              : !!  wff=<type(wffile_type)>=structured info for reading/writing
     555              : !!
     556              : !! SOURCE
     557              : 
     558            0 : subroutine xmoveOff(wff,n_int,n_dp,n_ch,n_mark)
     559              : 
     560              : !Arguments ------------------------------------
     561              :  integer,intent(in),optional :: n_int,n_dp,n_ch,n_mark
     562              :  type(wffile_type),intent(inout) :: wff
     563              : 
     564              : ! *************************************************************************
     565              : 
     566              : #if defined HAVE_MPI_IO
     567            0 :  if (present(n_int) ) wff%offwff=wff%offwff+n_int *wff%nbOct_int
     568            0 :  if (present(n_dp)  ) wff%offwff=wff%offwff+n_dp  *wff%nbOct_dp
     569            0 :  if (present(n_ch)  ) wff%offwff=wff%offwff+n_ch  *wff%nbOct_ch
     570            0 :  if (present(n_mark)) wff%offwff=wff%offwff+n_mark*wff%nbOct_recMarker
     571              : #else
     572              : !This section should not be used...
     573              :  if (present(n_int) .and.(.false.)) write(std_out,*) n_int
     574              :  if (present(n_dp)  .and.(.false.)) write(std_out,*) n_dp
     575              :  if (present(n_ch)  .and.(.false.)) write(std_out,*) n_ch
     576              :  if (present(n_mark).and.(.false.)) write(std_out,*) n_mark
     577              : #endif
     578              : 
     579            0 : end subroutine xmoveOff
     580              : !!***
     581              : 
     582              : !------------------------------------------------------------------------------------
     583              : 
     584              : !!****f* m_wffile/xderiveWRecEnd
     585              : !! NAME
     586              : !!  xderiveWRecEnd
     587              : !!
     588              : !! FUNCTION
     589              : !!  Writes the first and last wavefunction block marker using MPI/IO
     590              : !!
     591              : !! INPUTS
     592              : !!  me_proc= (optional argument) index of current proc
     593              : !!
     594              : !! OUTPUT
     595              : !!  ierr= exit status, a non-zero value meaning there is an error
     596              : !!
     597              : !! SIDE EFFECTS
     598              : !!  wff= structured info for reading/writing the wavefunctions
     599              : !!
     600              : !! NOTES
     601              : !!  We assume that:
     602              : !!    wff%offwff contains the position of the end of the record
     603              : !!    wff%off_recs contains the position of the beginning of the record
     604              : !!
     605              : !! SOURCE
     606              : 
     607           82 : subroutine xderiveWRecEnd(wff,ierr,me_proc)
     608              : 
     609              : !Arguments ------------------------------------
     610              :  type(wffile_type),intent(inout) :: wff
     611              :  integer,intent(in),optional :: me_proc
     612              :  integer,intent(out) :: ierr
     613              : 
     614              : !Local variables-------------------------------
     615              : #if defined HAVE_MPI_IO
     616              : !scalars
     617              :  integer :: me
     618              :  integer(kind=MPI_OFFSET_KIND) :: delim_record,posit
     619              : !arrays
     620              : #endif
     621              : 
     622              : ! *************************************************************************
     623              : 
     624           82 :  ierr=0
     625              : 
     626              : #if defined HAVE_MPI_IO
     627           82 :  me=-1;if (present(me_proc)) me=me_proc
     628           52 :  if (me==-1.or.me==0) then
     629              : 
     630           45 :    delim_record=wff%offwff-wff%off_recs-wff%nbOct_recMarker
     631              : 
     632              : !  Write the first word of the record
     633           45 :    posit=wff%off_recs
     634           45 :    call rwRecordMarker(2,posit,delim_record,wff,ierr)
     635              : 
     636              : !  Write the last word of the record
     637           45 :    posit=wff%offwff
     638           45 :    call rwRecordMarker(2,posit,delim_record,wff,ierr)
     639              : 
     640              :  end if
     641              : 
     642           82 :  wff%offwff = wff%offwff + wff%nbOct_recMarker
     643              : #endif
     644              : 
     645           82 :  RETURN
     646              :  ABI_UNUSED((/wff%me,me_proc/))
     647              : 
     648              : end subroutine xderiveWRecEnd
     649              : !!***
     650              : 
     651              : !------------------------------------------------------------------------------
     652              : 
     653              : !!****f* m_wffile/xderiveWRecInit
     654              : !! NAME
     655              : !!  xderiveWRecInit
     656              : !!
     657              : !! FUNCTION
     658              : !!  Writes the first wavefunction block marker using MPI/IO.
     659              : !!
     660              : !! INPUTS
     661              : !!  me_proc= (optional argument) index of current proc
     662              : !!
     663              : !! OUTPUT
     664              : !!  ierr= exit status, a non-zero value meaning there is an error
     665              : !!
     666              : !! SIDE EFFECTS
     667              : !!  wff= structured info for reading/writing the wavefunctions
     668              : !!
     669              : !! NOTES
     670              : !!  We assume that:
     671              : !!    wff%offwff contains the position of the beginning of the record
     672              : !!
     673              : !! SOURCE
     674              : 
     675           82 : subroutine xderiveWRecInit(wff,ierr,me_proc)
     676              : 
     677              : !Arguments ------------------------------------
     678              :  type(wffile_type),intent(inout) :: wff
     679              :  integer,intent(in),optional :: me_proc
     680              :  integer,intent(out) :: ierr
     681              : 
     682              : !Local variables-------------------------------
     683              : #if defined HAVE_MPI_IO
     684              : !scalars
     685              :  integer :: me
     686              :  integer(kind=MPI_OFFSET_KIND) :: delim_record,posit
     687              : !arrays
     688              : #endif
     689              : 
     690              : ! *************************************************************************
     691              : 
     692           82 :  ierr=0
     693              : 
     694              : #if defined HAVE_MPI_IO
     695           82 :  me=-1;if (present(me_proc)) me=me_proc
     696           52 :  if (me==-1.or.me==0) then
     697              : 
     698              : !  Write the first word of the record
     699           45 :    posit=wff%offwff;delim_record=0
     700           45 :    call rwRecordMarker(2,posit,delim_record,wff,ierr)
     701              : 
     702              :  end if
     703              : 
     704           82 :  wff%off_recs = wff%offwff
     705           82 :  wff%offwff = wff%offwff + wff%nbOct_recMarker
     706              : #endif
     707              : 
     708           82 :  RETURN
     709              :  ABI_UNUSED((/wff%me,me_proc/))
     710              : 
     711              : end subroutine xderiveWRecInit
     712              : !!***
     713              : 
     714              : !---------------------------------------------------------------------------------
     715              : 
     716              : !!****f* m_wffile/xderiveRRecEnd
     717              : !! NAME
     718              : !!  xderiveRRecEnd
     719              : !!
     720              : !! FUNCTION
     721              : !!  Initializes the end-of-record offset for MPI/IO.
     722              : !!
     723              : !! INPUTS
     724              : !!  me_proc= (optional argument) index of current proc
     725              : !!
     726              : !! OUTPUT
     727              : !!  ierr= exit status, a non-zero value meaning there is an error
     728              : !!
     729              : !! SIDE EFFECTS
     730              : !!  wff= structured info for reading/writing the wavefunctions
     731              : !!
     732              : !! NOTES
     733              : !!  We assume that:
     734              : !!    wff%off_recs contains the position of the beginning of the record
     735              : !!
     736              : !! SOURCE
     737              : 
     738           32 : subroutine xderiveRRecEnd(wff,ierr)
     739              : 
     740              : !Arguments ------------------------------------
     741              :  integer,intent(out) ::  ierr
     742              :  type(wffile_type),intent(inout) :: wff
     743              : 
     744              : ! *************************************************************************
     745              : 
     746           32 :  ierr=0
     747              : #if defined HAVE_MPI_IO
     748              : !Define offset end of record
     749           32 :  wff%offwff = wff%off_recs + wff%lght_recs + 2*wff%nbOct_recMarker
     750              : #endif
     751              : 
     752              :  RETURN
     753              :  ABI_UNUSED(wff%me)
     754              : 
     755              : end subroutine xderiveRRecEnd
     756              : !!***
     757              : 
     758              : !-------------------------------------------------------------------------------
     759              : 
     760              : !!****f* m_wffile/xderiveRRecInit
     761              : !! NAME
     762              : !!  xderiveRRecInit
     763              : !!
     764              : !! FUNCTION
     765              : !!  Initializes the record length for MPI/IO.
     766              : !!
     767              : !! INPUTS
     768              : !!  me_proc= (optional argument) index of current proc
     769              : !!
     770              : !! OUTPUT
     771              : !!  ierr= exit status, a non-zero value meaning there is an error
     772              : !!
     773              : !! SIDE EFFECTS
     774              : !!  wff= structured info for reading/writing the wavefunctions
     775              : !!
     776              : !! NOTES
     777              : !!  We assume that:
     778              : !!    wff%offwff contains the position of the beginning of the record
     779              : !!
     780              : !! SOURCE
     781              : 
     782           32 : subroutine xderiveRRecInit(wff,ierr)
     783              : 
     784              : !Arguments ------------------------------------
     785              :  type(wffile_type),intent(inout) :: wff
     786              :  integer,intent(out) :: ierr
     787              : 
     788              : !Local variables-------------------------------
     789              : #if defined HAVE_MPI_IO
     790              :  integer(kind=MPI_OFFSET_KIND) :: delim_record,posit
     791              : #endif
     792              : 
     793              : ! *************************************************************************
     794              : 
     795              :  ierr=0
     796              : 
     797              : #if defined HAVE_MPI_IO
     798           32 :  wff%off_recs = wff%offwff
     799              : 
     800              : !Read the length of the record
     801           32 :  posit=wff%off_recs
     802           32 :  call rwRecordMarker(1,posit,delim_record,wff,ierr)
     803              : 
     804           32 :  wff%lght_recs = delim_record
     805           32 :  wff%offwff =  wff%offwff + wff%nbOct_recMarker
     806              : #endif
     807              : 
     808           32 :  RETURN
     809              :  ABI_UNUSED(wff%me)
     810              : 
     811              : end subroutine xderiveRRecInit
     812              : !!***
     813              : 
     814              : !----------------------------------------------------------------------
     815              : 
     816              : !!****f* m_wffile/clsopn
     817              : !! NAME
     818              : !! clsopn
     819              : !!
     820              : !! FUNCTION
     821              : !! Close wavefunction file (provided its access is standard F90 IO), then reopen the same.
     822              : !! Uses fortran inquire statement to reopen with same characteristics.
     823              : !!
     824              : !! INPUTS
     825              : !!  wff=number of unit to which on which file is already opened.
     826              : !!
     827              : !! SIDE EFFECTS
     828              : !!
     829              : !! SOURCE
     830              : 
     831            0 : subroutine clsopn(wff)
     832              : 
     833              : !Arguments ------------------------------------
     834              : !scalars
     835              :  type(wffile_type),intent(inout) :: wff
     836              : 
     837              : !Local variables-------------------------------
     838              : !scalars
     839              :  integer :: ios,unit
     840              :  logical :: nmd,od
     841              :  character(len=11) :: fm
     842              :  character(len=500) :: message
     843              :  character(len=fnlen) :: filnam
     844              : 
     845              : ! *************************************************************************
     846              : 
     847            0 :  if ( ANY(wff%iomode==(/IO_MODE_FORTRAN_MASTER,IO_MODE_FORTRAN/) ))then
     848              : 
     849            0 :    unit=wff%unwff
     850            0 :    inquire (unit=unit,iostat=ios,opened=od,name=filnam,form=fm,named=nmd)
     851              : 
     852              : !  ios is a status specifier.  If an error condition exists,
     853              : !  ios is assigned a processor-dependent value > 0.
     854            0 :    if (ios/=0) then
     855              :      write(message, '(/,a,/,a,i8,a,i8,/,a,/,a,/,a)' ) &
     856            0 : &     ' clsopn : ERROR -',&
     857            0 : &     '  Attempt to inquire about unit=',unit,&
     858            0 : &     '  indicates error condition iostat=',ios,&
     859            0 : &     '  May be due to temporary problem with file, disks or network.',&
     860            0 : &     '  Action: check whether there might be some external problem,',&
     861            0 : &     '  then resubmit.'
     862            0 :      ABI_ERROR(message)
     863              : 
     864              : !    od is a logical variable which is set to true if the specified
     865              : !    unit is connected to a file; otherwise it is set to false.
     866            0 :    else if (.not.od) then
     867              :      write(message, '(/,a,/,a,i8,/,a,/,a,/,a,/,a)' ) &
     868            0 : &     ' clsopn : ERROR -',&
     869            0 : &     '  Tried to inquire about unit',unit,&
     870            0 : &     '  and found it not connected to a file.',&
     871            0 : &     '  May be due to temporary problem with file, disks or network.',&
     872            0 : &     '  Action: check whether there might be some external problem,',&
     873            0 : &     '  then resubmit.'
     874            0 :      ABI_ERROR(message)
     875              : 
     876              : !    nmd is a logical variable assigned the value true if the file
     877              : !    has a name; otherwise false.  A scratch file is not named.
     878            0 :    else if (.not.nmd) then
     879              : 
     880              : !    No action for the time being. Possibility to debug.
     881              : 
     882              :    else
     883              : 
     884              : !    May now close the file and then reopen it
     885              : !    (file is already opened according to above checks)
     886            0 :      close (unit=unit)
     887            0 :      open (unit=unit,file=filnam,form=fm,status='old') !VALGRIND complains filnam is just a few thousand bytes inside a block of 8300
     888              : 
     889              :    end if
     890              : 
     891            0 :  else if (wff%iomode == IO_MODE_MPI) then
     892            0 :    call xnullifyOff(wff)
     893              :  else if (wff%iomode == IO_MODE_ETSF) then
     894              : !  We do nothing, ETSF access already not being sequential.
     895              :  end if
     896              : 
     897            0 : end subroutine clsopn
     898              : !!***
     899              : 
     900              : !----------------------------------------------------------------------
     901              : 
     902              : !!****f* m_wffile/wff_usef90
     903              : !! NAME
     904              : !! wff_usef90
     905              : !!
     906              : !! FUNCTION
     907              : !!  1 if a Fortran file is going to be read by this node, 0 otherwise.
     908              : !!
     909              : !! INPUTS
     910              : !!
     911              : !! SOURCE
     912              : 
     913            0 : function wff_usef90(wff)
     914              : 
     915              : !Arguments ------------------------------------
     916              : !scalars
     917              :  integer :: wff_usef90
     918              :  type(wffile_type),intent(in) :: wff
     919              : 
     920              : ! *************************************************************************
     921              : 
     922            0 :  wff_usef90=0
     923            0 :  if (wff%iomode==IO_MODE_FORTRAN.or.(wff%iomode ==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me)) wff_usef90=1
     924              : 
     925            0 : end function wff_usef90
     926              : !!***
     927              : 
     928              : !----------------------------------------------------------------------
     929              : 
     930              : !!****f* m_wffile/wff_ireadf90
     931              : !! NAME
     932              : !! wff_ireadf90
     933              : !!
     934              : !! FUNCTION
     935              : !!  1 if a Fortran file is going to be read by this node, 0 otherwise.
     936              : !!
     937              : !! INPUTS
     938              : !!
     939              : !! SOURCE
     940              : 
     941              : function wff_ireadf90(wff)
     942              : 
     943              : !Arguments ------------------------------------
     944              : !scalars
     945              :  integer :: wff_ireadf90
     946              :  type(wffile_type),intent(in) :: wff
     947              : 
     948              : ! *************************************************************************
     949              : 
     950              :  wff_ireadf90=0
     951              :  if (wff%iomode==IO_MODE_FORTRAN.or.(wff%iomode==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me)) wff_ireadf90=1
     952              : 
     953              : end function wff_ireadf90
     954              : !!***
     955              : 
     956              : !----------------------------------------------------------------------
     957              : 
     958              : !!****f* m_wffile/WffOpen
     959              : !! NAME
     960              : !! WffOpen
     961              : !!
     962              : !! FUNCTION
     963              : !! This subroutine opens a Wf file. It might be accessed
     964              : !! by different mechanisms (usual F90 IO routines,
     965              : !!  MPI I/O, or, in the future, NetCDF). The routine
     966              : !! provides a file handler, wff (a data structure containing
     967              : !! all needed information).
     968              : !!
     969              : !! INPUTS
     970              : !! iomode=access mode (0 means all procs access using usual F90
     971              : !!  routines ; -1 means only the master proc access, using usual
     972              : !!  F90 routines ; 1 means MPI I/O; 2 means netcdf I/O)
     973              : !! filename=name of the file
     974              : !! master=the number of the master proc (only needed in parallel)
     975              : !! me=my number (only needed in parallel)
     976              : !! spaceComm= the space communicator handler (only needed in MPI parallel I/O)
     977              : !! spaceWorld= the space communicator for the whole set of procs
     978              : !! unwff=the file unit number
     979              : !!
     980              : !! OUTPUT
     981              : !! ier=error code
     982              : !! wff= structured info about the wavefunction file
     983              : !!
     984              : !! SOURCE
     985              : 
     986         2412 : subroutine WffOpen(iomode,spaceComm,filename,ier,wff,master,me,unwff,&
     987              : &                  spaceComm_mpiio) ! optional argument
     988              : 
     989              : !Arguments ------------------------------------
     990              :  integer, intent(in)  :: iomode,spaceComm,master,me,unwff
     991              :  integer, intent(in),optional  :: spaceComm_mpiio
     992              :  integer, intent(out) :: ier
     993              :  character(len=fnlen), intent(in) :: filename
     994              :  type(wffile_type), intent(inout) :: wff !vz_i
     995              : 
     996              : !Local variables-------------------------------
     997              :  character(len=500) :: message
     998              :  character(len=fnlen) :: fildata
     999              : #ifdef HAVE_MPI_IO
    1000              :  integer :: isize
    1001              : #endif
    1002              : 
    1003              : ! *************************************************************************
    1004              : 
    1005              : !Initialize the mandatory data of the wff datastructure
    1006         2412 :  wff%unwff  =unwff
    1007         2412 :  wff%iomode =iomode; if (endswith(filename, ".nc")) wff%iomode = IO_MODE_ETSF
    1008         2412 :  if (filename/=wff%fname) wff%fname=filename
    1009              : 
    1010              : !Initialize info useful for parallel use
    1011         2412 :  wff%nproc    =1
    1012         2412 :  wff%master   =master
    1013         2412 :  wff%me       =me
    1014         2412 :  wff%me_mpiio =0
    1015         2412 :  wff%spaceComm=spaceComm
    1016         2412 :  wff%spaceComm_mpiio=xmpi_comm_self
    1017              : 
    1018              : #if defined HAVE_MPI
    1019              : ! This case occurs when wff is connected to a DENSITY file
    1020              : ! abinit_comm_output is generally equal to MPI_COMM_WORLD (except if paral. over images)
    1021         2412 :   if (spaceComm==MPI_COMM_SELF) wff%spaceComm=abinit_comm_output
    1022              : ! if (spaceComm==MPI_COMM_SELF) wff%spaceComm=MPI_COMM_WORLD
    1023         2412 :   call MPI_COMM_SIZE(wff%spaceComm,wff%nproc,ier)
    1024              : ! Redefine the default MPIIO communicator if MPI, although MPIIO features should not be used unless
    1025              : ! present(spaceComm_mpiio).and.wff%iomode==1
    1026         2412 :   wff%spaceComm_mpiio=wff%spaceComm
    1027         2412 :   wff%me_mpiio=wff%me
    1028              : #endif
    1029              : 
    1030         2412 :   if (present(spaceComm_mpiio).and.any(wff%iomode==[IO_MODE_MPI, IO_MODE_ETSF])) wff%spaceComm_mpiio=spaceComm_mpiio
    1031              : #if defined HAVE_MPI
    1032         2412 :   call MPI_COMM_RANK(wff%spaceComm_mpiio,wff%me_mpiio,ier)
    1033              : #endif
    1034              : 
    1035         2412 :  ier=0
    1036         2412 :  if (wff%iomode==IO_MODE_FORTRAN) then !  All processors see a local file
    1037            0 :    if (open_file(filename, message, unit=unwff, form="unformatted") /= 0) then
    1038            0 :      ABI_ERROR(message)
    1039              :    end if
    1040            0 :    rewind(unwff)
    1041              : 
    1042         2412 :  else if (wff%iomode==IO_MODE_FORTRAN_MASTER) then !  Only the master processor see a local file
    1043          132 :    if(master==me)then
    1044          112 :      if (open_file(filename, message, unit=unwff, form="unformatted") /= 0) then
    1045            0 :        ABI_ERROR(message)
    1046              :      end if
    1047          112 :      rewind(unwff)
    1048              :    end if
    1049              : 
    1050              : #if defined HAVE_MPI_IO
    1051         2280 :  else if (wff%iomode==IO_MODE_MPI)then ! In the parallel case, only the master open filename file
    1052           32 :    if(master==me)then
    1053           27 :      if (open_file(filename, message, unit=unwff, form="unformatted") /= 0) then
    1054            0 :        ABI_ERROR(message)
    1055              :      end if
    1056           27 :      rewind(unwff)
    1057              :    end if
    1058              :    ! MG: Great! These barriers lead to a deadlock if prtded hence MPI_FILE_OPEN is not called by all the processors!
    1059              :    !call xmpi_barrier(wff%spaceComm)
    1060              :    !call xmpi_barrier(wff%spaceComm_mpiio)
    1061              : 
    1062           32 :    call MPI_FILE_OPEN(wff%spaceComm,filename,MPI_MODE_CREATE + MPI_MODE_RDWR,MPI_INFO_NULL,wff%fhwff,ier)
    1063           32 :    ABI_CHECK_MPI(ier,sjoin("WffOpen:", filename))
    1064              : 
    1065              : !  Define all type values
    1066           32 :    call MPI_Type_size(MPI_INTEGER,isize,ier)
    1067           32 :    wff%nbOct_int=isize
    1068           32 :    call MPI_Type_size(MPI_DOUBLE_PRECISION,isize,ier)
    1069           32 :    wff%nbOct_dp=isize
    1070           32 :    call MPI_Type_size(MPI_CHARACTER,isize,ier)
    1071           32 :    wff%nbOct_ch=isize
    1072           32 :    wff%nbOct_recMarker=-1;wff%kgwff=-1;wff%formwff=-1
    1073           32 :    wff%offwff=0;wff%off_recs=0;wff%lght_recs=0
    1074              :    wff%marker_mpi_type=MPI_INTEGER ! Default value
    1075              : 
    1076              : #ifdef DEV_DEBUG_THIS
    1077           32 :    wff%nbOct_recMarker=xmpio_bsize_frm
    1078           32 :    wff%marker_mpi_type=xmpio_mpi_type_frm
    1079              : #endif
    1080              : 
    1081              :    if (MPI_OFFSET_KIND==4) then
    1082              :      wff%offset_mpi_type=MPI_INTEGER4
    1083              :    else  if (MPI_OFFSET_KIND==8) then
    1084           32 :      wff%offset_mpi_type=MPI_INTEGER8
    1085              : #if defined HAVE_FC_INT_QUAD && defined HAVE_MPI_INTEGER16
    1086              :    else  if (MPI_OFFSET_KIND==16) then
    1087              :      wff%offset_mpi_type=MPI_INTEGER16
    1088              : #endif
    1089              :    else  if (MPI_OFFSET_KIND==2) then
    1090              :      wff%offset_mpi_type=MPI_INTEGER2
    1091              :    end if
    1092              : #endif
    1093              : 
    1094         2248 :  else if (wff%iomode==IO_MODE_ETSF)then
    1095         2248 :    fildata = nctk_ncify(filename)
    1096         2248 :    NCF_CHECK(nctk_open_modify(wff%unwff, fildata, xmpi_comm_self))
    1097         2248 :    wff%fname = fildata
    1098              :    !write(message,'(3A,I0)')'WffOpen: opening ', trim(wff%fname)," on unit ", wff%unwff
    1099              :    !call wrtout(std_out, message, 'COLL')
    1100              :  else
    1101              :    write(message, '(7a,i0,3a)' )&
    1102            0 : &   'For the time being the input variable iomode is restricted ',ch10,&
    1103            0 : &   'to 0 (all cases), 1 (in case MPI is enabled),',ch10,&
    1104            0 : &   'or 3 (only sequential, and if the NetCDF and ETSF_IO libraries have been enabled).',ch10,&
    1105            0 : &   'Its value is iomode= ',wff%iomode,'.',ch10,&
    1106            0 : &   'Action: change iomode or use ABINIT in parallel or enable NetCDF and/or ETSF_IO.'
    1107            0 :    ABI_ERROR(message)
    1108              :  end if
    1109              : 
    1110         2412 : end subroutine WffOpen
    1111              : !!***
    1112              : 
    1113              : !----------------------------------------------------------------------
    1114              : 
    1115              : !!****f* m_wffile/WffClose
    1116              : !! NAME
    1117              : !! WffClose
    1118              : !!
    1119              : !! FUNCTION
    1120              : !! This subroutine closes a Wf file.
    1121              : !!
    1122              : !! INPUTS
    1123              : !! wff= structured info about the wavefunction file
    1124              : !!
    1125              : !! OUTPUT
    1126              : !! ierr=error code
    1127              : !!
    1128              : !! SOURCE
    1129              : 
    1130         2412 : subroutine WffClose(wff,ier)
    1131              : 
    1132              : !Arguments ------------------------------------
    1133              :  type(wffile_type), intent(inout) :: wff
    1134              :  integer, intent(out) :: ier
    1135              : 
    1136              : ! *************************************************************************
    1137              : 
    1138         2412 :  ier=0
    1139         2412 :  if(wff%iomode==IO_MODE_FORTRAN) then ! All processors see a local file
    1140            0 :    close(unit=wff%unwff)
    1141              : 
    1142         2412 :  else if(wff%iomode == IO_MODE_ETSF)then
    1143         2248 :    NCF_CHECK(nf90_close(wff%unwff))
    1144              : 
    1145          164 :  else if(wff%iomode==IO_MODE_FORTRAN_MASTER)then !  Only the master processor see a local file
    1146          132 :    if(wff%master==wff%me) close (unit=wff%unwff)    ! VALGRIND complains buf points to uninitialized bytes
    1147              : 
    1148              : #if defined HAVE_MPI_IO
    1149           32 :  else if(wff%iomode==IO_MODE_MPI)then
    1150           32 :    call MPI_FILE_CLOSE(wff%fhwff,ier)
    1151           32 :    if (wff%master==wff%me ) close(unit=wff%unwff)
    1152           32 :    wff%offwff=0;wff%off_recs=0;wff%lght_recs=0
    1153           32 :    wff%nbOct_recMarker=-1
    1154           32 :    wff%kgwff=-1
    1155              : #endif
    1156              : 
    1157              :  end if
    1158              : 
    1159         2412 : end subroutine WffClose
    1160              : !!***
    1161              : 
    1162              : !----------------------------------------------------------------------
    1163              : 
    1164              : !!****f* m_wffile/WffDelete
    1165              : !! NAME
    1166              : !! WffDelete
    1167              : !!
    1168              : !! FUNCTION
    1169              : !! This subroutine closes a Wf file, and delete it.
    1170              : !!
    1171              : !! INPUTS
    1172              : !! wff= structured info about the wavefunction file
    1173              : !!
    1174              : !! OUTPUT
    1175              : !! ierr=error code
    1176              : !!
    1177              : !! SOURCE
    1178              : 
    1179            0 : subroutine WffDelete(wff,ier)
    1180              : 
    1181              : !Arguments ------------------------------------
    1182              :  type(wffile_type),intent(inout) :: wff
    1183              :  integer, intent(out) :: ier
    1184              : 
    1185              : ! *************************************************************************
    1186              : 
    1187            0 :  ier=0
    1188            0 :  if (wff%iomode==IO_MODE_FORTRAN) then !  All processors see a local file
    1189            0 :    close(unit=wff%unwff,status='delete')
    1190              : 
    1191            0 :  else if (wff%iomode==IO_MODE_FORTRAN_MASTER)then !  Only the master processor see a local file
    1192            0 :    if (wff%master==wff%me) close (unit=wff%unwff,status='delete')
    1193              : 
    1194              : 
    1195            0 :  else if (wff%iomode==IO_MODE_MPI)then
    1196              : #if defined HAVE_MPI_IO
    1197            0 :    if ( wff%fhwff /= -1 )then
    1198            0 :      call MPI_FILE_CLOSE(wff%fhwff,ier)
    1199              :    end if
    1200            0 :    if (wff%master==wff%me ) then
    1201            0 :      close(unit=wff%unwff,status='delete')
    1202            0 :      wff%fhwff = -1
    1203              :    end if
    1204            0 :    wff%offwff=0;wff%off_recs=0;wff%lght_recs=0
    1205            0 :    wff%nbOct_recMarker=-1
    1206            0 :    wff%kgwff=-1
    1207              : #endif
    1208              :  end if
    1209              : 
    1210            0 : end subroutine WffDelete
    1211              : !!***
    1212              : 
    1213              : !----------------------------------------------------------------------
    1214              : 
    1215              : !!****f* m_wffile/WffKg
    1216              : !! NAME
    1217              : !! WffKg
    1218              : !!
    1219              : !! FUNCTION
    1220              : !! Check kgwff to  manage WF file in the MPI/IO case
    1221              : !!
    1222              : !! INPUTS
    1223              : !!  wff <type(wffile_type)> = structured info about the wavefunction file
    1224              : !!  optkg= if 1 , read or write kg_k ; if 0,do not care about kg_k in rwwf
    1225              : !!
    1226              : !! OUTPUT
    1227              : !!
    1228              : !! SOURCE
    1229              : 
    1230          160 : subroutine WffKg(wff,optkg)
    1231              : 
    1232              : !Arguments ------------------------------------
    1233              :  type(wffile_type),intent(inout) :: wff
    1234              :  integer,intent(in) :: optkg
    1235              : 
    1236              : ! *********************************************************************
    1237              : 
    1238              : #if defined HAVE_MPI_IO
    1239          160 :  if (wff%iomode == IO_MODE_MPI) wff%kgwff=optkg
    1240              : #else
    1241              :  ABI_UNUSED((/wff%iomode,optkg/))
    1242              : #endif
    1243              : 
    1244          160 : end subroutine WffKg
    1245              : !!***
    1246              : 
    1247              : !----------------------------------------------------------------------
    1248              : 
    1249              : !!****f* ABINIT/WffOffset
    1250              : !! NAME
    1251              : !! WffOffset
    1252              : !!
    1253              : !! FUNCTION
    1254              : !! Tool to manage WF file in the MPI/IO case : broadcast the offset of
    1255              : !! the first k-point data block
    1256              : !!
    1257              : !! INPUTS
    1258              : !!  wff <type(wffile_type)> = structured info about the wavefunction file
    1259              : !!  sender = id of the sender
    1260              : !!  spaceComm = id of the space communicator handler
    1261              : !!
    1262              : !! OUTPUT
    1263              : !!  ier = error code returned by the MPI call
    1264              : !!
    1265              : !! SOURCE
    1266              : 
    1267          592 : subroutine WffOffset(wff,sender,spaceComm,ier)
    1268              : 
    1269              : !Arguments ------------------------------------
    1270              :  type(wffile_type),intent(inout) :: wff
    1271              :  integer          ,intent(inout) :: sender
    1272              :  integer          ,intent(in)    :: spaceComm
    1273              :  integer          ,intent(out)   :: ier
    1274              : 
    1275              : !Local variables ------------------------------
    1276              : #if defined HAVE_MPI_IO
    1277              :  integer :: icom
    1278              :  integer(kind=MPI_OFFSET_KIND)  :: off(1)
    1279              : #endif
    1280              : 
    1281              : ! *********************************************************************
    1282              : 
    1283              : #if defined HAVE_MPI_IO
    1284          592 :  if (wff%iomode == IO_MODE_MPI) then
    1285           60 :    call xmpi_max(sender,icom,spaceComm,ier)
    1286           60 :    if (icom>=0)then
    1287           60 :      off(1)=wff%offwff
    1288           60 :      call MPI_BCAST(off,1,wff%offset_mpi_type,icom,spaceComm,ier)
    1289           60 :      wff%offwff=off(1)
    1290              :    end if
    1291              :  end if ! iomode
    1292              : #else
    1293              :  ier = 0
    1294              :  ABI_UNUSED((/wff%iomode,sender,spaceComm/))
    1295              : #endif
    1296              : 
    1297          592 : end subroutine WffOffset
    1298              : !!***
    1299              : 
    1300              : !----------------------------------------------------------------------
    1301              : 
    1302              : !!****f* m_wffile/WffReadDataRec_dp1d
    1303              : !! NAME
    1304              : !! WffReadDataRec_dp1d
    1305              : !!
    1306              : !! FUNCTION
    1307              : !! Subroutine to read data in one record of a wavefunction file
    1308              : !! Handles double precision 1D arrays
    1309              : !!
    1310              : !! INPUTS
    1311              : !! ndp=size of the double precision array to be read
    1312              : !! wff= structured info about the wavefunction file
    1313              : !!
    1314              : !! OUTPUT
    1315              : !! dparray=array of double precision numbers
    1316              : !! ierr=error code
    1317              : !!
    1318              : !! SIDE EFFECTS
    1319              : !!
    1320              : !! SOURCE
    1321              : 
    1322            0 : subroutine WffReadDataRec_dp1d(dparray,ierr,ndp,wff)
    1323              : 
    1324              : !Arguments ------------------------------------
    1325              :  type(wffile_type),intent(inout) :: wff
    1326              :  integer,intent(in) ::  ndp
    1327              :  integer,intent(out) :: ierr
    1328              :  real(dp),intent(out) :: dparray(ndp)
    1329              : 
    1330              : !Local variables-------------------------------
    1331              :  character(len=500) :: msg
    1332              : 
    1333              : ! *************************************************************************
    1334              : 
    1335            0 :  ierr=0
    1336            0 :  if (wff%iomode==IO_MODE_FORTRAN.or.(wff%iomode==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me)) then
    1337            0 :    read (wff%unwff,iostat=ierr) dparray(1:ndp)
    1338              : 
    1339            0 :  else if(wff%iomode==IO_MODE_MPI)then
    1340              : #if defined HAVE_MPI_IO
    1341            0 :    call xderiveRRecInit(wff,ierr)
    1342            0 :    call xderiveRead(wff,dparray,ndp,MPI_COMM_SELF,ierr)
    1343            0 :    call xderiveRRecEnd(wff,ierr)
    1344              : #endif
    1345              :  else
    1346            0 :    write(msg,'(a,i0)')"Wrong iomode: ",wff%iomode
    1347            0 :    ABI_ERROR(msg)
    1348              :  end if
    1349              : 
    1350            0 : end subroutine WffReadDataRec_dp1d
    1351              : !!***
    1352              : 
    1353              : !----------------------------------------------------------------------
    1354              : 
    1355              : 
    1356              : !!****f* m_wffile/WffReadDataRec_dp2d
    1357              : !! NAME
    1358              : !! WffReadDataRec_dp2d
    1359              : !!
    1360              : !! FUNCTION
    1361              : !! Subroutine to read data in one record of a wavefunction file
    1362              : !! Handles double precision 2D arrays
    1363              : !!
    1364              : !! INPUTS
    1365              : !! n1,n2=sizes of the double precision array to be read
    1366              : !! wff= structured info about the wavefunction file
    1367              : !!
    1368              : !! OUTPUT
    1369              : !! dparray=array of double precision numbers
    1370              : !! ierr=error code
    1371              : !!
    1372              : !! SIDE EFFECTS
    1373              : !!
    1374              : !! SOURCE
    1375              : 
    1376            0 : subroutine WffReadDataRec_dp2d(dparray,ierr,n1,n2,wff)
    1377              : 
    1378              : !Arguments ------------------------------------
    1379              :  type(wffile_type),intent(inout) :: wff
    1380              :  integer,intent(in) ::  n1,n2
    1381              :  integer,intent(out) :: ierr
    1382              :  real(dp),intent(out) :: dparray(n1,n2)
    1383              : 
    1384              : !Local variables-------------------------------
    1385              :  character(len=500) :: msg
    1386              : 
    1387              : ! *************************************************************************
    1388              : 
    1389            0 :  ierr=0
    1390            0 :  if (wff%iomode==IO_MODE_FORTRAN.or.(wff%iomode==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me)) then
    1391            0 :    read (wff%unwff,iostat=ierr) dparray(1:n1,1:n2)
    1392              : 
    1393            0 :  else if(wff%iomode==IO_MODE_MPI)then
    1394              : #if defined HAVE_MPI_IO
    1395            0 :    call xderiveRRecInit(wff,ierr)
    1396            0 :    call xderiveRead(wff,dparray,n1,n2,MPI_COMM_SELF,ierr)
    1397            0 :    call xderiveRRecEnd(wff,ierr)
    1398              : #endif
    1399              :  else
    1400            0 :    write(msg,'(a,i0)')"Wrong iomode: ",wff%iomode
    1401            0 :    ABI_ERROR(msg)
    1402              :  end if
    1403              : 
    1404            0 : end subroutine WffReadDataRec_dp2d
    1405              : !!***
    1406              : 
    1407              : !----------------------------------------------------------------------
    1408              : 
    1409              : !!****f* m_wffile/WffReadNpwRec
    1410              : !! NAME
    1411              : !! WffReadNpwRec
    1412              : !!
    1413              : !! FUNCTION
    1414              : !! This subroutine read the npw record of a wavefunction file
    1415              : !!
    1416              : !! INPUTS
    1417              : !! wff= structured info about the wavefunction file
    1418              : !!  wff%access == -1 and wf%master == Wff%me:
    1419              : !!     read binary data
    1420              : !!  wff%iomode == 0:
    1421              : !!     read binary data
    1422              : !!  wff%iomode == 1:
    1423              : !!     use MPI/IO routines (MPIO defined)
    1424              : !!  wff%iomode == 2:
    1425              : !!     read netcdf format (NETCDF defined)
    1426              : !! ikpt= the i-th kpoint.
    1427              : !! isppol= the given spin polarisation element.
    1428              : !!
    1429              : !! OUTPUT
    1430              : !! ierr=error code (iostat integer from read statement)
    1431              : !! nband_disk=number of bands
    1432              : !! npw=number of plane waves
    1433              : !! nspinor=number of spinorial components of the wavefunctions
    1434              : !!
    1435              : !! SIDE EFFECTS
    1436              : !!
    1437              : !! SOURCE
    1438              : 
    1439        63806 : subroutine WffReadNpwRec(ierr,ikpt,isppol,nband_disk,npw,nspinor,wff)
    1440              : 
    1441              : !Arguments ------------------------------------
    1442              :  type(wffile_type),intent(inout) :: wff
    1443              :  integer,intent(in)  :: ikpt, isppol
    1444              :  integer,intent(out) :: ierr,nband_disk,npw,nspinor
    1445              : 
    1446              : !Local variables-------------------------------
    1447              :  !character(len=500) :: msg
    1448              :  integer :: vid
    1449              : ! *************************************************************************
    1450              : 
    1451        63806 :  ierr=0
    1452              : 
    1453        63806 :  if (wff%iomode == IO_MODE_FORTRAN.or.(wff%iomode==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me) ) then
    1454            0 :    read (wff%unwff,iostat=ierr) npw,nspinor,nband_disk
    1455              : 
    1456        63806 :  else if(wff%iomode==IO_MODE_MPI)then
    1457              : #if defined HAVE_MPI_IO
    1458           16 :    call xderiveRRecInit(wff,ierr)
    1459           16 :    call xderiveRead(wff,npw,ierr)
    1460           16 :    call xderiveRead(wff,nspinor,ierr)
    1461           16 :    call xderiveRead(wff,nband_disk,ierr)
    1462           16 :    call xderiveRRecEnd(wff,ierr)
    1463              : #endif
    1464              : 
    1465        63790 :  else if (wff%iomode == IO_MODE_ETSF) then
    1466              : 
    1467              :    !write(std_out,*)"readnpwrec: ikpt, spin", ikpt, spin
    1468        63790 :    NCF_CHECK(nctk_get_dim(wff%unwff, "number_of_spinor_components", nspinor))
    1469        63790 :    vid = nctk_idname(wff%unwff, "number_of_coefficients")
    1470       127580 :    NCF_CHECK(nf90_get_var(wff%unwff, vid, npw, start=[ikpt]))
    1471        63790 :    vid = nctk_idname(wff%unwff, "number_of_states")
    1472       191370 :    NCF_CHECK(nf90_get_var(wff%unwff, vid, nband_disk, start=[ikpt, isppol]))
    1473              : 
    1474              :  else
    1475              :    ! MG: I don't understand why we have to use this ugly code!!!!!!!!
    1476              :    ! Only master knows npw,nspinor,nband_disk in IO_MODE_FORTRAN_MASTE mode
    1477              :    ! To the person who wrote this stuff:
    1478              :    ! Have you ever heard about the "IF" statement of Fortran and the typical construct
    1479              :    !
    1480              :    !      if (rank==master) call mpifoo_seq()
    1481              : 
    1482            0 :    ABI_WARNING("Skipping read in WffReadNpwRec. Keep fingers crossed")
    1483              :    ! MG: Must initialze these values somehow to avoid overflows.
    1484            0 :    npw = 0; nspinor = 0; nband_disk = 0
    1485              :  end if
    1486              : 
    1487              :  !write(std_out,*)"nband_disk,npw,nspinor",nband_disk,npw,nspinor
    1488        63806 :  ABI_CHECK(ierr==0,"ierr!=0")
    1489              : 
    1490        63806 : end subroutine WffReadNpwRec
    1491              : !!***
    1492              : 
    1493              : !----------------------------------------------------------------------
    1494              : 
    1495              : !!****f* m_wffile/WffReadSkipRec
    1496              : !! NAME
    1497              : !! WffReadSkipRec
    1498              : !!
    1499              : !! FUNCTION
    1500              : !! This subroutine move forward or backward in a Wf file by nrec records.
    1501              : !!
    1502              : !! INPUTS
    1503              : !! nrec=number of records
    1504              : !! wff= structured info about the wavefunction file
    1505              : !!
    1506              : !! OUTPUT
    1507              : !! ierr=error code
    1508              : !!
    1509              : !! TODO
    1510              : !! For the future : one should treat the possible errors of backspace
    1511              : !!
    1512              : !! SOURCE
    1513              : 
    1514              : 
    1515        63878 : subroutine WffReadSkipRec(ierr,nrec,wff)
    1516              : 
    1517              : !Arguments ------------------------------------
    1518              :  integer,intent(in)  :: nrec
    1519              :  integer,intent(out) :: ierr
    1520              :  type(wffile_type),intent(inout) :: wff
    1521              : 
    1522              : !Local variables-------------------------------
    1523              : #if defined HAVE_MPI_IO
    1524              :  integer :: irec
    1525              :  integer(kind=MPI_OFFSET_KIND) :: delim_record,offset
    1526              : #endif
    1527              : 
    1528              : ! *************************************************************************
    1529              : 
    1530        63878 :  ierr=0
    1531        63878 :  if( wff%iomode==IO_MODE_FORTRAN.or.(wff%iomode==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me)) then
    1532              : 
    1533            0 :    call mvrecord(wff%unwff,nrec,ierr)
    1534            0 :    ABI_CHECK(ierr==0,"error in mvrecord")
    1535              : 
    1536              : 
    1537        63878 :  else if(wff%iomode==IO_MODE_MPI)then
    1538              : #if defined HAVE_MPI_IO
    1539           16 :    if (nrec>0) then ! Move forward nrec records
    1540           32 :      do irec=1,nrec
    1541           16 :        wff%off_recs = wff%offwff
    1542           16 :        call rwRecordMarker(1,wff%offwff,delim_record,wff,ierr)
    1543           32 :        wff%lght_recs = delim_record
    1544              :      end do
    1545              :    else             ! Move backward -nrec records
    1546            0 :      do irec=1,-nrec
    1547            0 :        offset = wff%offwff-wff%nbOct_recMarker
    1548            0 :        call rwRecordMarker(1,offset,delim_record,wff,ierr)
    1549            0 :        wff%lght_recs = delim_record
    1550            0 :        wff%offwff = wff%offwff - delim_record - 2*wff%nbOct_recMarker
    1551            0 :        wff%off_recs = wff%offwff
    1552              :      end do
    1553              :    end if
    1554              : #endif
    1555              :  end if ! wff%iomode==0,1 or -1
    1556              : 
    1557        63878 : end subroutine WffReadSkipRec
    1558              : !!***
    1559              : 
    1560              : !----------------------------------------------------------------------
    1561              : 
    1562              : !!****f* m_wffile/WffReadWrite_mpio
    1563              : !! NAME
    1564              : !! WffReadWrite_mpio
    1565              : !!
    1566              : !! FUNCTION
    1567              : !!  This procedure read or write cg in the file _WFK using MPI_IO
    1568              : !!  when cg are dispatched amoung commcart communicator
    1569              : !!
    1570              : !! INPUTS
    1571              : !!  wff=struct info for wavefunction
    1572              : !!  nband_disk=number of bands on disk files to be write
    1573              : !!  icg=shift to be given to the location of the cg array
    1574              : !!  mcg=second dimention of cg
    1575              : !!  mpi_enreg=information about parallelisation
    1576              : !!  depl_mpi_to_seq=for each proc, index of cg in sequential mode
    1577              : !!  npwso=npw*nspinor number of plane waves treated by this node.
    1578              : !!  npwsotot=npwtot*nspinor Total number of planewaves Used to calculate the size of data to be written.
    1579              : !!  rdwr=1 if reading, 2 if writing
    1580              : !!
    1581              : !! OUTPUT
    1582              : !!  ierr=error status
    1583              : !!
    1584              : !! SIDE EFFECTS
    1585              : !!  cg(2,mcg)=planewave coefficients of wavefunctions,
    1586              : !!
    1587              : !! NOTES
    1588              : !!  cg is written like the following:
    1589              : !!    BeginMarker cg ( iband = 1 )  EndMarker
    1590              : !!    BeginMarker cg ( iband = 2 )  EndMarker
    1591              : !!    ...
    1592              : !!    BeginMarker cg( iband = nband_disk ) EndMarker
    1593              : !!
    1594              : !!  BeginMarker and EndMarker give the value of the total length of cg for one band
    1595              : !!
    1596              : !!  For MPI-IO library the performance is improved by the use a "view" of the file for each proc.
    1597              : 
    1598              : !! SOURCE
    1599              : 
    1600           68 : subroutine WffReadWrite_mpio(wff,rdwr,cg,mcg,icg,nband_disk,npwso,npwsotot,depl_mpi_to_seq,ierr)
    1601              : 
    1602              : !Arguments ------------------------------------
    1603              : !scalars
    1604              :  integer,intent(in) :: icg,mcg,nband_disk,npwso,npwsotot,rdwr
    1605              :  integer,intent(out) :: ierr
    1606              :  type(wffile_type),intent(inout) :: wff
    1607              : !arrays
    1608              :  integer,intent(in) :: depl_mpi_to_seq(npwso)
    1609              :  real(dp),intent(inout) :: cg(2,mcg)
    1610              : 
    1611              : !Local variables-------------------------------
    1612              : !scalars
    1613              : #if defined HAVE_MPI_IO
    1614              :  integer,parameter :: MAXBAND=500, check_markers=1
    1615              :  integer :: filetype,iband,ibandmax,ibandmin,iblock,ii,iloc,ipw,jerr,jj
    1616              :  integer :: nb,nband_block,step,totsize1bandcg,wfftempo
    1617              :  integer(kind=MPI_OFFSET_KIND) :: delim_record,loc_depl_band,offset,totsize1bandByte
    1618              :  character(len=500) :: msg
    1619              : !arrays
    1620           68 :  integer,allocatable :: BlockLength(:),BlockType(:),map(:),tempo_map(:)
    1621           68 :  integer(kind=MPI_OFFSET_KIND),allocatable :: BlockDepl(:)
    1622           68 :  integer(kind=2),allocatable :: bufdelim2(:)
    1623           68 :  integer(kind=4),allocatable :: bufdelim4(:)
    1624           68 :  integer(kind=8),allocatable :: bufdelim8(:)
    1625           68 :  real(dp),allocatable :: buf(:),tempo_buf(:)
    1626              : #if defined HAVE_FC_INT_QUAD
    1627           68 :  integer(kind=16),allocatable :: bufdelim16(:)
    1628              : #endif
    1629              : #endif
    1630              : 
    1631              : ! *********************************************************************
    1632              : 
    1633           68 :  ierr=0
    1634              : 
    1635              : #if defined HAVE_MPI_IO
    1636              : !----------------------------------------------
    1637              : !! Prepare WF data
    1638              : !----------------------------------------------
    1639              : !Init offset of record
    1640           68 :  wff%off_recs = wff%offwff
    1641              : 
    1642              : !Total size to be written (in number of bands and in bytes)
    1643           68 :  totsize1bandcg=2*npwsotot
    1644              : !call xmpi_sum(totsize1bandcg,wff%spaceComm_mpiio,ierr)
    1645              : 
    1646           68 :  totsize1bandByte=totsize1bandcg*wff%nbOct_dp+2*wff%nbOct_recMarker
    1647              : 
    1648              : !Check file size
    1649           68 :  offset=wff%offwff+nband_disk*totsize1bandByte
    1650              :  if (offset>Huge(offset)) then
    1651              :    msg='File is too large for MPI-IO specifications !'
    1652              :    ABI_ERROR(msg)
    1653              :  end if
    1654              : 
    1655              : !Open file
    1656           68 :  call MPI_FILE_OPEN(wff%spaceComm_mpiio,wff%fname,MPI_MODE_RDWR,MPI_INFO_NULL,wfftempo,ierr)
    1657           68 :  ABI_CHECK_MPI(ierr, sjoin("MPI_FILE_OPEN:", wff%fname))
    1658              : 
    1659              : !----------------------------------------------------------
    1660              : !Loop blocks of bands (to decrease offsets inside the file)
    1661              : !----------------------------------------------------------
    1662           68 :  ibandmax=0;ibandmin=1
    1663           68 :  ii=huge(check_markers)/totsize1bandByte;step=min(ii,MAXBAND,nband_disk)
    1664           68 :  do iblock=1,nband_disk/step+1
    1665           68 :    ibandmax=min(ibandmin+step-1,nband_disk)
    1666           68 :    nband_block=ibandmax-ibandmin+1
    1667           68 :    offset=wff%offwff+(ibandmin-1)*totsize1bandByte
    1668              : 
    1669              : !  ----------------------------------------------
    1670              : !  Read/Write bands
    1671              : !  ----------------------------------------------
    1672              : 
    1673              : !  Build map; for better performance, map must be in increasing order
    1674          204 :    ABI_MALLOC_OR_DIE(map,(2*npwso*nband_block), ierr)
    1675              : 
    1676          204 :    ABI_STAT_MALLOC(buf,(2*npwso*nband_block), ierr)
    1677           68 :    ABI_CHECK(ierr==0, "out of memory in wavefunction buffer. Try to decrease MAXBAND in WffReadWrite_mpio")
    1678              : 
    1679           68 :    if (rdwr==1) then
    1680              : !    If reading, only build map
    1681           16 :      nb=0;loc_depl_band=0
    1682           48 :      ABI_MALLOC(tempo_map,(2*npwso))
    1683          816 :      do iband=ibandmin,ibandmax
    1684       131200 :        tempo_map(1:2*npwso)=-1
    1685        66000 :        jj=1;ipw=(iband-1)*npwso+icg
    1686        66000 :        do ii=1,npwso
    1687        65200 :          iloc=loc_depl_band+wff%nbOct_recMarker+2*(depl_mpi_to_seq(ii)-1)*wff%nbOct_dp
    1688        65200 :          tempo_map(jj  )=iloc              ! Real part
    1689        65200 :          tempo_map(jj+1)=iloc+wff%nbOct_dp ! Imag part
    1690        66000 :          jj=jj+2
    1691              :        end do
    1692       131200 :        do ii=1,2*npwso ! Now, elimate holes
    1693       131200 :          if (tempo_map(ii)/=-1) then
    1694       130400 :            nb=nb+1
    1695       130400 :            map(nb)=tempo_map(ii)
    1696              :          end if
    1697              :        end do
    1698          816 :        loc_depl_band=loc_depl_band+totsize1bandByte ! Location in bytes
    1699              :      end do
    1700           52 :    else if (rdwr==2) then
    1701              : !    If writing, build map and store cg in a buffer
    1702           52 :      nb=0;loc_depl_band=0
    1703          156 :      ABI_MALLOC(tempo_map,(2*npwso))
    1704          156 :      ABI_MALLOC(tempo_buf,(2*npwso))
    1705         1572 :      do iband=ibandmin,ibandmax
    1706       622384 :        tempo_map(1:2*npwso)=-1
    1707         1520 :        jj=1;ipw=(iband-1)*npwso+icg
    1708       311952 :        do ii=1,npwso
    1709       310432 :          iloc=loc_depl_band+wff%nbOct_recMarker+2*(depl_mpi_to_seq(ii)-1)*wff%nbOct_dp
    1710       310432 :          tempo_map(jj  )=iloc              ! Real part
    1711       310432 :          tempo_map(jj+1)=iloc+wff%nbOct_dp ! Imag part
    1712       931296 :          tempo_buf(jj:jj+1)=cg(1:2,ipw+ii)
    1713       311952 :          jj=jj+2
    1714              :        end do
    1715       622384 :        do ii=1,2*npwso ! Now, elimate holes
    1716       622384 :          if (tempo_map(ii)/=-1) then
    1717       620864 :            nb=nb+1
    1718       620864 :            map(nb)=tempo_map(ii)
    1719       620864 :            buf(nb)=tempo_buf(ii)
    1720              :          end if
    1721              :        end do
    1722         1572 :        loc_depl_band=loc_depl_band+totsize1bandByte ! Location in bytes
    1723              :      end do
    1724           52 :      ABI_FREE(tempo_map)
    1725           52 :      ABI_FREE(tempo_buf)
    1726              :    end if  ! rdwr
    1727              : 
    1728              : !  Build and commit MPI datatype
    1729          204 :    ABI_MALLOC(BlockLength,(nb+2))
    1730          204 :    ABI_MALLOC(BlockDepl,(nb+2))
    1731          136 :    ABI_MALLOC(BlockType,(nb+2))
    1732           68 :    BlockLength(1)=1;BlockDepl(1)=0;BlockType(1)=MPI_LB
    1733       751332 :    do ii=2,nb+1
    1734       751264 :      BlockLength(ii)=1
    1735       751264 :      BlockDepl(ii)=map(ii-1)
    1736       751332 :      BlockType(ii)=MPI_DOUBLE_PRECISION
    1737              :    end do
    1738           68 :    BlockLength(nb+2)=1;BlockDepl(nb+2)=totsize1bandByte*nband_block;BlockType(nb+2)=MPI_UB
    1739           68 :    call xmpio_type_struct(nb+2,BlockLength,BlockDepl,BlockType,filetype,ierr)
    1740           68 :    call MPI_TYPE_COMMIT(filetype,ierr)
    1741           68 :    ABI_FREE(BlockLength)
    1742           68 :    ABI_FREE(BlockDepl)
    1743           68 :    ABI_FREE(BlockType)
    1744              : 
    1745              : !  Read/Write data on disk
    1746           68 :    call MPI_FILE_SET_VIEW(wfftempo,offset,MPI_BYTE,filetype,"native",MPI_INFO_NULL,ierr)
    1747           68 :    if (rdwr==1) then
    1748           16 :      call MPI_FILE_READ_ALL (wfftempo,buf,nb,MPI_DOUBLE_PRECISION,MPI_STATUS_IGNORE,ierr)
    1749              :    else
    1750           52 :      call MPI_FILE_WRITE_ALL(wfftempo,buf,nb,MPI_DOUBLE_PRECISION,MPI_STATUS_IGNORE,ierr)
    1751              :    end if
    1752              : 
    1753              : !  In case of reading, retrieve cg
    1754           68 :    if (rdwr==1) then
    1755           16 :      nb=0;loc_depl_band=0
    1756           48 :      ABI_MALLOC(tempo_buf,(2*npwso))
    1757          816 :      do iband=ibandmin,ibandmax
    1758       131200 :        do ii=1,2*npwso ! Now, elimate holes
    1759       131200 :          if (tempo_map(ii)/=-1) then
    1760       130400 :            nb=nb+1;tempo_buf(ii)=buf(nb)
    1761              :          end if
    1762              :        end do
    1763          800 :        jj=1;ipw=(iband-1)*npwso+icg
    1764        66000 :        do ii=1,npwso
    1765        65200 :          iloc=loc_depl_band+wff%nbOct_recMarker+2*(depl_mpi_to_seq(ii)-1)*wff%nbOct_dp
    1766       195600 :          cg(1:2,ipw+ii)=tempo_buf(jj:jj+1)
    1767        66000 :          jj=jj+2
    1768              :        end do
    1769          816 :        loc_depl_band=loc_depl_band+totsize1bandByte ! Location in bytes
    1770              :      end do
    1771           16 :      ABI_FREE(tempo_map)
    1772           16 :      ABI_FREE(tempo_buf)
    1773              :    end if ! rdwr
    1774              : 
    1775              : !  Free memory
    1776           68 :    ABI_FREE(map)
    1777           68 :    ABI_FREE(buf)
    1778           68 :    call MPI_TYPE_FREE(filetype,ierr)
    1779              : 
    1780              : !  ----------------------------------------------
    1781              : !  Check/Write record markers (only master proc)
    1782              : !  ----------------------------------------------
    1783           68 :    if ((rdwr==1.and.check_markers==1).or.(rdwr==2)) then
    1784              : 
    1785              : !    Define view for the file
    1786           68 :      nb=2*nband_block
    1787          204 :      ABI_MALLOC(BlockLength,(nb+2))
    1788          204 :      ABI_MALLOC(BlockDepl,(nb+2))
    1789          136 :      ABI_MALLOC(BlockType,(nb+2))
    1790           68 :      BlockLength(1)=1;BlockDepl(1)=0;BlockType(1)=MPI_LB
    1791           68 :      jj=2
    1792         2388 :      do ii=1,nband_block
    1793         6960 :        BlockType(jj:jj+1)  =wff%marker_mpi_type
    1794         6960 :        BlockLength(jj:jj+1)=1
    1795         2320 :        BlockDepl(jj  )=(ii-1)*totsize1bandByte
    1796         2320 :        BlockDepl(jj+1)= ii   *totsize1bandByte-wff%nbOct_recMarker
    1797         2388 :        jj=jj+2
    1798              :      end do
    1799           68 :      BlockLength(nb+2)=1;BlockDepl(nb+2)=nband_block*totsize1bandByte;BlockType(nb+2)=MPI_UB
    1800           68 :      call xmpio_type_struct(nb+2,BlockLength,BlockDepl,BlockType,filetype,ierr)
    1801           68 :      call MPI_TYPE_COMMIT(filetype,ierr)
    1802           68 :      call MPI_FILE_SET_VIEW(wfftempo,offset,MPI_BYTE,filetype,"native",MPI_INFO_NULL,ierr)
    1803           68 :      ABI_FREE(BlockLength)
    1804           68 :      ABI_FREE(BlockDepl)
    1805           68 :      ABI_FREE(BlockType)
    1806              : 
    1807              : !    Read/Write all markers (depend on Fortran marker MPI type)
    1808           68 :      if (wff%me_mpiio==0) then
    1809           19 :        jerr=0;delim_record=totsize1bandByte-2*wff%nbOct_recMarker
    1810           19 :        if (wff%nbOct_recMarker==4) then
    1811           57 :          ABI_MALLOC(bufdelim4,(nb))
    1812          979 :          if (rdwr==2) bufdelim4(:)=delim_record
    1813           19 :          if (rdwr==1) then
    1814            4 :            call MPI_FILE_READ (wfftempo,bufdelim4,2*nband_block,wff%marker_mpi_type,MPI_STATUS_IGNORE,ierr)
    1815          404 :            if (any(bufdelim4(:)/=delim_record)) jerr=1
    1816              :          else
    1817           15 :            call MPI_FILE_WRITE(wfftempo,bufdelim4,2*nband_block,wff%marker_mpi_type,MPI_STATUS_IGNORE,ierr)
    1818              :          end if
    1819           19 :          ABI_FREE(bufdelim4)
    1820            0 :        else if (wff%nbOct_recMarker==8) then
    1821            0 :          ABI_MALLOC(bufdelim8,(nb))
    1822            0 :          if (rdwr==2) bufdelim8(:)=delim_record
    1823            0 :          if (rdwr==1) then
    1824            0 :            call MPI_FILE_READ (wfftempo,bufdelim8,2*nband_block,wff%marker_mpi_type,MPI_STATUS_IGNORE,ierr)
    1825            0 :            if (any(bufdelim8(:)/=delim_record)) jerr=1
    1826              :          else
    1827            0 :            call MPI_FILE_WRITE(wfftempo,bufdelim8,2*nband_block,wff%marker_mpi_type,MPI_STATUS_IGNORE,ierr)
    1828              :          end if
    1829            0 :          ABI_FREE(bufdelim8)
    1830              : #if defined HAVE_FC_INT_QUAD
    1831            0 :        else if (wff%nbOct_recMarker==16) then
    1832            0 :          ABI_MALLOC(bufdelim16,(nb))
    1833            0 :          if (rdwr==2) bufdelim16(:)=delim_record
    1834            0 :          if (rdwr==1) then
    1835            0 :            call MPI_FILE_READ (wfftempo,bufdelim16,2*nband_block,wff%marker_mpi_type,MPI_STATUS_IGNORE,ierr)
    1836            0 :            if (any(bufdelim16(:)/=delim_record)) jerr=1
    1837              :          else
    1838            0 :            call MPI_FILE_WRITE(wfftempo,bufdelim16,2*nband_block,wff%marker_mpi_type,MPI_STATUS_IGNORE,ierr)
    1839              :          end if
    1840            0 :          ABI_FREE(bufdelim16)
    1841              : #endif
    1842            0 :        else if (wff%nbOct_recMarker==2) then
    1843            0 :          ABI_MALLOC(bufdelim2,(nb))
    1844            0 :          if (rdwr==2) bufdelim2(:)=delim_record
    1845            0 :          if (rdwr==1) then
    1846            0 :            call MPI_FILE_READ (wfftempo,bufdelim2,2*nband_block,wff%marker_mpi_type,MPI_STATUS_IGNORE,ierr)
    1847            0 :            if (any(bufdelim2(:)/=delim_record)) jerr=1
    1848              :          else
    1849            0 :            call MPI_FILE_WRITE(wfftempo,bufdelim2,2*nband_block,wff%marker_mpi_type,MPI_STATUS_IGNORE,ierr)
    1850              :          end if
    1851            0 :          ABI_FREE(bufdelim2)
    1852              :        end if
    1853           19 :        if (rdwr==1.and.jerr==1) then
    1854            0 :          write(unit=msg,fmt='(2a)') 'Error when reading record markers of file ',trim(wff%fname)
    1855            0 :          ABI_ERROR(msg)
    1856              :        end if
    1857              :      end if  ! me_mpiio=0
    1858              : 
    1859              : !    Free memory
    1860           68 :      call MPI_TYPE_FREE(filetype,ierr)
    1861              : 
    1862              :    end if ! rdwr
    1863              : 
    1864              : !  -----------------------------------------
    1865              : !  End loop on blocks of bands
    1866              : !  -----------------------------------------
    1867           68 :    if (ibandmax>=nband_disk) exit
    1868           68 :    ibandmin=ibandmax+1
    1869              :  end do
    1870              : 
    1871              : !-----------------------------------------
    1872              : !End statements
    1873              : !-----------------------------------------
    1874              : !Close file
    1875           68 :  call MPI_FILE_CLOSE(wfftempo,ierr)
    1876              : 
    1877              : !Update offset
    1878           68 :  wff%offwff=wff%offwff+totsize1bandByte*nband_disk
    1879              : #endif
    1880              : 
    1881              : #if !defined HAVE_MPI_IO
    1882              : !Dummy check to avoid warning from compilers.
    1883              :  ABI_UNUSED((/wff%iomode,rdwr,size(cg),mcg,icg,nband_disk,npwso,depl_mpi_to_seq(1),npwsotot/))
    1884              : #endif
    1885              : 
    1886           68 : end subroutine WffReadWrite_mpio
    1887              : !!***
    1888              : 
    1889              : !----------------------------------------------------------------------
    1890              : 
    1891              : !!****f* m_wffile/WffWriteDataRec_int2d
    1892              : !! NAME
    1893              : !! WffWriteDataRec_int2d
    1894              : !!
    1895              : !! FUNCTION
    1896              : !! Subroutine to write data in one record of a wavefunction file
    1897              : !! Handles integer 2D arrays
    1898              : !!
    1899              : !! INPUTS
    1900              : !! intarray=array of integer numbers
    1901              : !! n1,n2=sizes of the integer array to be written
    1902              : !! wff= structured info about the wavefunction file
    1903              : !!
    1904              : !! OUTPUT
    1905              : !! ierr=error code
    1906              : !!
    1907              : !! SIDE EFFECTS
    1908              : !!
    1909              : !! SOURCE
    1910              : 
    1911            0 : subroutine WffWriteDataRec_int2d(intarray,ierr,n1,n2,wff)
    1912              : 
    1913              : !Arguments ------------------------------------
    1914              :  type(wffile_type),intent(inout) :: wff
    1915              :  integer,intent(in) ::  n1,n2
    1916              :  integer,intent(out) :: ierr
    1917              :  integer,intent(in) :: intarray(n1,n2)
    1918              : 
    1919              : !Local variables-------------------------------
    1920              :  character(len=500) :: msg
    1921              : 
    1922              : ! *************************************************************************
    1923              : 
    1924            0 :  ierr=0
    1925            0 :  if (wff%iomode==IO_MODE_FORTRAN.or.(wff%iomode==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me)) then
    1926            0 :    write(wff%unwff,iostat=ierr) intarray(1:n1,1:n2)
    1927              : 
    1928            0 :  else if(wff%iomode==IO_MODE_MPI)then
    1929              : #if defined HAVE_MPI_IO
    1930            0 :    call xderiveWRecInit(wff,ierr)
    1931            0 :    call xderiveWrite(wff,intarray,n1,n2,MPI_COMM_SELF,ierr)
    1932            0 :    call xderiveWRecEnd(wff,ierr)
    1933              : #endif
    1934              :  else
    1935            0 :    write(msg,'(a,i0,a)')' The value of wff%iomode=',wff%iomode,' is not allowed.'
    1936            0 :    ABI_WARNING(msg)
    1937              :  end if
    1938              : 
    1939            0 : end subroutine WffWriteDataRec_int2d
    1940              : !!***
    1941              : 
    1942              : !----------------------------------------------------------------------
    1943              : 
    1944              : 
    1945              : !!****f* m_wffile/WffWriteDataRec_dp1d
    1946              : !! NAME
    1947              : !! WffWriteDataRec_dp1d
    1948              : !!
    1949              : !! FUNCTION
    1950              : !! Subroutine to write data in one record of a wavefunction file
    1951              : !! Handles double precision 1D arrays
    1952              : !!
    1953              : !! INPUTS
    1954              : !! dparray=array of double precision numbers
    1955              : !! ndp=size of the double precision array to be written
    1956              : !! wff= structured info about the wavefunction file
    1957              : !!
    1958              : !! OUTPUT
    1959              : !! ierr=error code
    1960              : !!
    1961              : !! SIDE EFFECTS
    1962              : !!
    1963              : !! SOURCE
    1964              : 
    1965            0 : subroutine WffWriteDataRec_dp1d(dparray,ierr,ndp,wff)
    1966              : 
    1967              : !Arguments ------------------------------------
    1968              :  type(wffile_type),intent(inout) :: wff
    1969              :  integer,intent(in) ::  ndp
    1970              :  integer,intent(out) :: ierr
    1971              :  real(dp),intent(in) :: dparray(ndp)
    1972              : 
    1973              : !Local variables-------------------------------
    1974              :  character(len=500) :: msg
    1975              : 
    1976              : ! *************************************************************************
    1977              : 
    1978            0 :  ierr=0
    1979            0 :  if (wff%iomode==IO_MODE_FORTRAN.or.(wff%iomode==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me)) then
    1980            0 :    write(wff%unwff,iostat=ierr) dparray(1:ndp)
    1981              : 
    1982            0 :  else if(wff%iomode==IO_MODE_MPI)then
    1983              : #if defined HAVE_MPI_IO
    1984            0 :    call xderiveWRecInit(wff,ierr)
    1985            0 :    call xderiveWrite(wff,dparray,ndp,MPI_COMM_SELF,ierr)
    1986            0 :    call xderiveWRecEnd(wff,ierr)
    1987              : #endif
    1988              :  else
    1989            0 :    write(msg,'(a,i0,a)')' The value of wff%iomode=',wff%iomode,' is not allowed.'
    1990            0 :    ABI_WARNING(msg)
    1991              :  end if
    1992              : 
    1993            0 : end subroutine WffWriteDataRec_dp1d
    1994              : !!***
    1995              : 
    1996              : !----------------------------------------------------------------------
    1997              : 
    1998              : 
    1999              : !!****f* m_wffile/WffWriteDataRec_dp2d
    2000              : !! NAME
    2001              : !! WffWriteDataRec_dp2d
    2002              : !!
    2003              : !! FUNCTION
    2004              : !! Subroutine to write data in one record of a wavefunction file
    2005              : !! Handles double precision 2D arrays
    2006              : !!
    2007              : !! INPUTS
    2008              : !! dparray=array of double precision numbers
    2009              : !! n1,n2=sizes of the double precision array to be written
    2010              : !! wff= structured info about the wavefunction file
    2011              : !!
    2012              : !! OUTPUT
    2013              : !! ierr=error code
    2014              : !!
    2015              : !! SIDE EFFECTS
    2016              : !!
    2017              : !! SOURCE
    2018              : 
    2019              : 
    2020            0 : subroutine WffWriteDataRec_dp2d(dparray,ierr,n1,n2,wff)
    2021              : 
    2022              : !Arguments ------------------------------------
    2023              :  type(wffile_type),intent(inout) :: wff
    2024              :  integer,intent(in) ::  n1,n2
    2025              :  integer,intent(out) :: ierr
    2026              :  real(dp),intent(in) :: dparray(n1,n2)
    2027              : 
    2028              : !Local variables-------------------------------
    2029              :  character(len=500) :: msg
    2030              : 
    2031              : ! *************************************************************************
    2032              : 
    2033            0 :  ierr=0
    2034            0 :  if (wff%iomode==IO_MODE_FORTRAN.or.(wff%iomode==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me)) then
    2035            0 :    write(wff%unwff,iostat=ierr) dparray(1:n1,1:n2)
    2036              : 
    2037            0 :  else if(wff%iomode==IO_MODE_MPI)then
    2038              : #if defined HAVE_MPI_IO
    2039            0 :    call xderiveWRecInit(wff,ierr)
    2040            0 :    call xderiveWrite(wff,dparray,n1,n2,MPI_COMM_SELF,ierr)
    2041            0 :    call xderiveWRecEnd(wff,ierr)
    2042              : #endif
    2043              :  else
    2044            0 :    write(msg,'(a,i0,a)')' The value of wff%iomode=',wff%iomode,' is not allowed.'
    2045            0 :    ABI_WARNING(msg)
    2046              :  end if
    2047              : 
    2048            0 : end subroutine WffWriteDataRec_dp2d
    2049              : !!***
    2050              : 
    2051              : !----------------------------------------------------------------------
    2052              : 
    2053              : 
    2054              : !!****f* m_wffile/WffWriteNpwRec
    2055              : !! NAME
    2056              : !! WffWriteNpwRec
    2057              : !!
    2058              : !! FUNCTION
    2059              : !! This subroutine writes the npw record of a wavefunction file
    2060              : !!
    2061              : !! INPUTS
    2062              : !! wff= structured info about the wavefunction file
    2063              : !! nband_disk=number of bands
    2064              : !! npw=number of plane waves
    2065              : !! nspinor=number of spinorial components of the wavefunctions
    2066              : !! opt_paral=(optional argument, default=1, only used for MPI-IO)
    2067              : !!           1: all procs in the communicator write the data
    2068              : !!           2: only master in the communicator writes the data
    2069              : !!
    2070              : !! OUTPUT
    2071              : !! ierr=error code
    2072              : !!
    2073              : !! SIDE EFFECTS
    2074              : !!
    2075              : !! SOURCE
    2076              : 
    2077              : 
    2078          416 : subroutine WffWriteNpwRec(ierr,nband_disk,npw,nspinor,wff,&
    2079              : &                         opt_paral) ! optional argument
    2080              : 
    2081              : !Arguments ------------------------------------
    2082              :  type(wffile_type),intent(inout) :: wff
    2083              :  integer,intent(in) :: nband_disk,npw,nspinor
    2084              :  integer,intent(in),optional :: opt_paral
    2085              :  integer,intent(out) :: ierr
    2086              : 
    2087              : !Local variables-------------------------------
    2088              :  integer :: opt_paral_
    2089              :  character(len=500) :: msg
    2090              : #if defined HAVE_MPI_IO
    2091              :  integer :: me
    2092              :  integer(kind=MPI_OFFSET_KIND)  :: off(1)
    2093              : #endif
    2094              : 
    2095              : ! *************************************************************************
    2096              : 
    2097          416 :  ierr=0
    2098          416 :  opt_paral_=1;if (present(opt_paral)) opt_paral_=opt_paral
    2099              : 
    2100          416 :  if (wff%iomode==IO_MODE_FORTRAN.or.(wff%iomode ==IO_MODE_FORTRAN_MASTER.and.wff%master==wff%me)) then
    2101          364 :    write(wff%unwff,iostat=ierr) npw,nspinor,nband_disk
    2102              : 
    2103           52 :  else if(wff%iomode==IO_MODE_MPI)then
    2104              : #if defined HAVE_MPI_IO
    2105           52 :    me=-1;if (opt_paral_==2) me=wff%me_mpiio
    2106           52 :    if ((me==-1.and.opt_paral_==1).or.(me==0.and.opt_paral_==2)) then
    2107           15 :      call xderiveWRecInit(wff,ierr)
    2108           15 :      call xderiveWrite(wff,npw,ierr)
    2109           15 :      call xderiveWrite(wff,nspinor,ierr)
    2110           15 :      call xderiveWrite(wff,nband_disk,ierr)
    2111           15 :      call xderiveWRecEnd(wff,ierr)
    2112              :    end if
    2113           52 :    if (opt_paral_==2.and.wff%spaceComm_mpiio/=MPI_COMM_SELF) then
    2114           52 :      call xmpi_barrier(wff%spaceComm_mpiio)
    2115           52 :      off(1)=wff%offwff
    2116           52 :      call MPI_BCAST(off,1,wff%offset_mpi_type,0,wff%spaceComm_mpiio,ierr)
    2117           52 :      wff%offwff=off(1)
    2118              :    end if
    2119              : #endif
    2120              :  else
    2121            0 :    write(msg,'(a,i0,a)')' The value of wff%iomode=',wff%iomode,' is not allowed.'
    2122            0 :    ABI_WARNING(msg)
    2123              :  end if
    2124              : 
    2125          416 : end subroutine WffWriteNpwRec
    2126              : !!***
    2127              : 
    2128              : !!****f* m_wffile/xderiveRead_int
    2129              : !! NAME
    2130              : !!  xderiveRead_int
    2131              : !!
    2132              : !! FUNCTION
    2133              : !!  Generic routine to read/write wf files with MPI I/O.
    2134              : !!  Target: integer scalar.
    2135              : !!
    2136              : !! INPUTS
    2137              : !! (none)
    2138              : !!
    2139              : !! OUTPUT
    2140              : !!  xval= data buffer
    2141              : !!  ierr= exit status, a non-zero value meaning there is an error
    2142              : !!
    2143              : !! SIDE EFFECTS
    2144              : !!  wff= structured info for reading/writing the wavefunctions
    2145              : !!
    2146              : !! SOURCE
    2147              : 
    2148           48 : subroutine xderiveRead_int(wff,xval,ierr)
    2149              : 
    2150              : !Arguments ------------------------------------
    2151              :  type(wffile_type),intent(inout) :: wff
    2152              :  integer,intent(out) :: xval
    2153              :  integer,intent(out) :: ierr
    2154              : 
    2155              : !Local variables-------------------------------
    2156              : #if defined HAVE_MPI_IO
    2157              :  integer :: arr_xval(1),statux(MPI_STATUS_SIZE)
    2158              : #endif
    2159              :  character(len=500) :: msg
    2160              : 
    2161              : ! *********************************************************************
    2162              : 
    2163           48 :  xval=0; ierr=0
    2164              : 
    2165              : #if defined HAVE_MPI_IO
    2166           48 :  call MPI_FILE_READ_AT(wff%fhwff,wff%offwff,arr_xval,1,MPI_INTEGER,statux,ierr)
    2167           48 :  xval=arr_xval(1)
    2168           48 :  wff%offwff = wff%offwff + wff%nbOct_int
    2169           48 :  RETURN
    2170              : #endif
    2171              : 
    2172              :  ABI_UNUSED(wff%me)
    2173              : 
    2174              :  write(msg,'(a,i0,a)')' The value of wff%iomode=',wff%iomode,' is not allowed.'
    2175              :  ABI_WARNING(msg)
    2176              : 
    2177              : end subroutine xderiveRead_int
    2178              : !!***
    2179              : 
    2180              : !----------------------------------------------------------------------
    2181              : 
    2182              : 
    2183              : !!****f* m_wffile/xderiveRead_int1d
    2184              : !! NAME
    2185              : !!  xderiveRead_int1d
    2186              : !!
    2187              : !! FUNCTION
    2188              : !!  Generic routine to read/write wf files with MPI I/O.
    2189              : !!  Target: one-dimensional integer arrays.
    2190              : !!
    2191              : !! INPUTS
    2192              : !!  n1= first dimension of the array
    2193              : !!  spaceComm= MPI communicator
    2194              : !!
    2195              : !! OUTPUT
    2196              : !!  xval= data buffer array
    2197              : !!  ierr= exit status, a non-zero value meaning there is an error
    2198              : !!
    2199              : !! SIDE EFFECTS
    2200              : !!  wff= structured info for reading/writing the wavefunctions
    2201              : !!
    2202              : !! SOURCE
    2203              : 
    2204            0 : subroutine xderiveRead_int1d(wff,xval,n1,spaceComm,ierr)
    2205              : 
    2206              : !Arguments ------------------------------------
    2207              :  type(wffile_type),intent(inout) :: wff
    2208              :  integer,intent(out) :: xval(:)
    2209              :  integer,intent(in) :: n1,spaceComm
    2210              :  integer,intent(out) :: ierr
    2211              : 
    2212              : !Local variables-------------------------------
    2213              : #if defined HAVE_MPI_IO
    2214              :  integer(kind=MPI_OFFSET_KIND) :: delim_record,nboct,dispoct(1),posit,totoct
    2215              :  integer :: statux(MPI_STATUS_SIZE)
    2216              : #endif
    2217              :  character(len=500) :: msg
    2218              : 
    2219              : ! *********************************************************************
    2220              : 
    2221            0 :  xval(:)=0 ; ierr=0 ! Initialization, for the compiler
    2222              :  if(.false.)write(std_out,*)wff%me,n1,spaceComm
    2223              : 
    2224              : #if defined HAVE_MPI_IO
    2225            0 :  nboct = wff%nbOct_int * n1
    2226            0 :  posit = wff%offwff
    2227            0 :  delim_record = posit - wff%off_recs + wff%lght_recs - wff%nbOct_recMarker
    2228              : 
    2229            0 :  if (delim_record >= nboct) then
    2230              : !  Compute offset for local part
    2231              : !  dispoct = sum (nboct, rank=0..me)
    2232            0 :    if (spaceComm/=MPI_COMM_SELF) then
    2233            0 :      call MPI_SCAN([nboct],dispoct,1,wff%offset_mpi_type,MPI_SUM,spaceComm,ierr)
    2234            0 :      posit = posit + dispoct(1) - nboct
    2235              :    end if
    2236            0 :    call MPI_FILE_READ_AT(wff%fhwff,posit,xval,n1,MPI_INTEGER,statux,ierr)
    2237              : 
    2238              : !  get the total number of bits wrote by processors
    2239            0 :    if (spaceComm/=MPI_COMM_SELF) then
    2240            0 :      call xmpi_max(dispoct(1),totoct,spaceComm,ierr)
    2241              :      !call MPI_ALLREDUCE(dispoct,totoct,1,wff%offset_mpi_type,MPI_MAX,spaceComm,ierr)
    2242              :    else
    2243            0 :      totoct=nboct
    2244              :    end if
    2245              :  else
    2246            0 :    ierr = 1
    2247            0 :    nboct = 0
    2248            0 :    totoct = 0
    2249              :  end if
    2250              : 
    2251              : !new offset
    2252            0 :  wff%offwff = wff%offwff + totoct
    2253            0 :  return
    2254              : #endif
    2255              : 
    2256              :  write(msg,'(a,i0,a)')' The value of wff%iomode=',wff%iomode,' is not allowed.'
    2257              :  ABI_WARNING(msg)
    2258              : 
    2259              : end subroutine xderiveRead_int1d
    2260              : !!***
    2261              : 
    2262              : !----------------------------------------------------------------------
    2263              : 
    2264              : 
    2265              : !!****f* m_wffile/xderiveRead_int2d
    2266              : !! NAME
    2267              : !!  xderiveRead_int2d
    2268              : !!
    2269              : !! FUNCTION
    2270              : !!  Generic routine to read/write wf files with MPI I/O.
    2271              : !!  Target: two-dimensional integer arrays.
    2272              : !!
    2273              : !! INPUTS
    2274              : !!  n1= first dimension of the array
    2275              : !!  n2= second dimension of the array
    2276              : !!  spaceComm= MPI communicator
    2277              : !!
    2278              : !! OUTPUT
    2279              : !!  xval= data buffer array
    2280              : !!  ierr= exit status, a non-zero value meaning there is an error
    2281              : !!
    2282              : !! SIDE EFFECTS
    2283              : !!  wff= structured info for reading/writing the wavefunctions
    2284              : !!
    2285              : !! SOURCE
    2286              : 
    2287            0 : subroutine xderiveRead_int2d(wff,xval,n1,n2,spaceComm,ierr)
    2288              : 
    2289              : !Arguments ------------------------------------
    2290              :  type(wffile_type),intent(inout) :: wff
    2291              :  integer,intent(out) :: xval(:,:)
    2292              :  integer,intent(in) :: n1,n2,spaceComm
    2293              :  integer,intent(out) :: ierr
    2294              : 
    2295              : !Local variables-------------------------------
    2296              : #if defined HAVE_MPI_IO
    2297              :  integer(kind=MPI_OFFSET_KIND) :: delim_record,nboct,dispoct(1),posit,totoct
    2298              :  integer :: statux(MPI_STATUS_SIZE)
    2299              : #endif
    2300              :  character(len=500) :: msg
    2301              : 
    2302              : ! *********************************************************************
    2303              : 
    2304            0 :  xval(:,:)=0 ; ierr=0 ! Initialization, for the compiler
    2305              :  if(.false.)write(std_out,*)wff%me,n1,n2,spaceComm
    2306              : 
    2307              : #if defined HAVE_MPI_IO
    2308            0 :  nboct = wff%nbOct_int * n1 * n2
    2309            0 :  posit = wff%offwff
    2310            0 :  delim_record = posit - wff%off_recs + wff%lght_recs - wff%nbOct_recMarker
    2311              : 
    2312            0 :  if (delim_record >= nboct) then
    2313              : !  Compute offset for local part
    2314              : !  dispoct = sum (nboct, rank=0..me)
    2315            0 :    if (spaceComm/=MPI_COMM_SELF) then
    2316            0 :      call MPI_SCAN([nboct],dispoct,1,wff%offset_mpi_type,MPI_SUM,spaceComm,ierr)
    2317            0 :      posit = posit + dispoct(1) - nboct
    2318              :    end if
    2319            0 :    call MPI_FILE_READ_AT(wff%fhwff,posit,xval,n1*n2,MPI_INTEGER,statux,ierr)
    2320              : 
    2321              : !  get the total number of bits wrote by processors
    2322            0 :    if (spaceComm/=MPI_COMM_SELF) then
    2323            0 :      call xmpi_max(dispoct(1),totoct,spaceComm,ierr)
    2324              :      !call MPI_ALLREDUCE(dispoct,totoct,1,wff%offset_mpi_type,MPI_MAX,spaceComm,ierr)
    2325              :    else
    2326            0 :      totoct=nboct
    2327              :    end if
    2328              :  else
    2329            0 :    ierr = 1
    2330            0 :    nboct = 0
    2331            0 :    totoct = 0
    2332              :  end if
    2333              : 
    2334              : !new offset
    2335            0 :  wff%offwff=wff%offwff + totoct
    2336            0 :  return
    2337              : #endif
    2338              : 
    2339              :  write(msg,'(a,i0,a)')' The value of wff%iomode=',wff%iomode,' is not allowed.'
    2340              :  ABI_WARNING(msg)
    2341              : 
    2342              : end subroutine xderiveRead_int2d
    2343              : !!***
    2344              : 
    2345              : !----------------------------------------------------------------------
    2346              : 
    2347              : 
    2348              : !!****f* m_wffile/xderiveRead_dp
    2349              : !! NAME
    2350              : !!  xderiveRead_dp
    2351              : !!
    2352              : !! FUNCTION
    2353              : !!  Generic routine to read/write wf files with MPI I/O.
    2354              : !!  Target: double precision scalar.
    2355              : !!
    2356              : !! INPUTS
    2357              : !! (none)
    2358              : !!
    2359              : !! OUTPUT
    2360              : !!  xval= data buffer
    2361              : !!  ierr= exit status, a non-zero value meaning there is an error
    2362              : !!
    2363              : !! SIDE EFFECTS
    2364              : !!  wff= structured info for reading/writing the wavefunctions
    2365              : !!
    2366              : !! SOURCE
    2367              : 
    2368            0 : subroutine xderiveRead_dp(wff,xval,ierr)
    2369              : 
    2370              : !Arguments ------------------------------------
    2371              :  type(wffile_type),intent(inout) :: wff
    2372              :  integer,intent(out) :: ierr
    2373              :  real(dp),intent(out) :: xval
    2374              : 
    2375              : !Local variables-------------------------------
    2376              : #if defined HAVE_MPI_IO
    2377              :  integer :: statux(MPI_STATUS_SIZE)
    2378              :  real(dp) :: arr_xval(1)
    2379              : #endif
    2380              :  character(len=500) :: msg
    2381              : 
    2382              : ! *********************************************************************
    2383              : 
    2384            0 :  xval=zero ; ierr=0
    2385              :  if(.false.)write(std_out,*)wff%me
    2386              : #if defined HAVE_MPI_IO
    2387            0 :  call MPI_FILE_READ_AT(wff%fhwff,wff%offwff,arr_xval,1,MPI_DOUBLE_PRECISION,statux,ierr)
    2388            0 :  xval=arr_xval(1)
    2389            0 :  wff%offwff = wff%offwff + wff%nbOct_dp
    2390            0 :  return
    2391              : #endif
    2392              : 
    2393              :  write(msg,'(a,i0,a)')' The value of wff%iomode=',wff%iomode,' is not allowed.'
    2394              :  ABI_WARNING(msg)
    2395              : 
    2396              : end subroutine xderiveRead_dp
    2397              : !!***
    2398              : 
    2399              : !----------------------------------------------------------------------
    2400              : 
    2401              : 
    2402              : !!****f* ABINIT/xderiveRead_dp1d
    2403              : !! NAME
    2404              : !!  xderiveRead_dp1d
    2405              : !!
    2406              : !! FUNCTION
    2407              : !!  Generic routine to read/write wf files with MPI I/O.
    2408              : !!  Target: one-dimensional double precision arrays.
    2409              : !!
    2410              : !! INPUTS
    2411              : !!  n1= first dimension of the array
    2412              : !!  spaceComm= MPI communicator
    2413              : !!
    2414              : !! OUTPUT
    2415              : !!  ierr= exit status, a non-zero value meaning there is an error
    2416              : !!  xval= data buffer array
    2417              : !!
    2418              : !! SIDE EFFECTS
    2419              : !!  wff= structured info for reading/writing the wavefunctions
    2420              : !!
    2421              : !! SOURCE
    2422              : 
    2423           16 :  subroutine xderiveRead_dp1d(wff,xval,n1,spaceComm,ierr)
    2424              : 
    2425              : !Arguments ------------------------------------
    2426              :  type(wffile_type),intent(inout) :: wff
    2427              :  integer,intent(in) :: n1,spaceComm
    2428              :  integer,intent(out) :: ierr
    2429              :  real(dp),intent(out) :: xval(:)
    2430              : 
    2431              : !Local variables-------------------------------
    2432              : #if defined HAVE_MPI_IO
    2433              :  integer(kind=MPI_OFFSET_KIND) :: delim_record,nboct,dispoct(1),posit,totoct
    2434              :  integer :: statux(MPI_STATUS_SIZE)
    2435              : #endif
    2436              :  character(len=500) :: msg
    2437              : 
    2438              : !*********************************************************************
    2439              : 
    2440          816 :  xval(:)=zero ; ierr=0 ! Initialization, for the compiler
    2441              :  if(.false.)write(std_out,*)wff%me,n1,spaceComm
    2442              : 
    2443              : #if defined HAVE_MPI_IO
    2444           16 :  nboct = wff%nbOct_dp * n1
    2445           16 :  posit = wff%offwff
    2446           16 :  delim_record = posit - wff%off_recs + wff%lght_recs - wff%nbOct_recMarker
    2447              : 
    2448           16 :  if (delim_record >= nboct) then
    2449              : !  Compute offset for local part
    2450              : !  dispoct = sum (nboct, rank=0..me)
    2451           16 :    if (spaceComm/=MPI_COMM_SELF) then
    2452            0 :      call MPI_SCAN([nboct],dispoct,1,wff%offset_mpi_type,MPI_SUM,spaceComm,ierr)
    2453            0 :      posit = posit + dispoct(1) - nboct
    2454              :    end if
    2455              : 
    2456           16 :    call MPI_FILE_READ_AT(wff%fhwff,posit,xval,n1,MPI_DOUBLE_PRECISION,statux,ierr)
    2457              : 
    2458              : !  get the total number of bits wrote by processors
    2459           16 :    if (spaceComm/=MPI_COMM_SELF) then
    2460            0 :      call xmpi_max(dispoct(1),totoct,spaceComm,ierr)
    2461              :      !call MPI_ALLREDUCE(dispoct,totoct,1,wff%offset_mpi_type,MPI_MAX,spaceComm,ierr)
    2462              :    else
    2463           16 :      totoct=nboct
    2464              :    end if
    2465              :  else
    2466            0 :    ierr = 1
    2467            0 :    nboct = 0
    2468            0 :    totoct = 0
    2469              :  end if
    2470              : 
    2471              : !new offset
    2472           16 :  wff%offwff=wff%offwff + totoct
    2473           16 :  return
    2474              : #endif
    2475              : 
    2476              :  write(msg,'(a,i0,a)')' The value of wff%iomode=',wff%iomode,' is not allowed.'
    2477              :  ABI_WARNING(msg)
    2478              : 
    2479              : end subroutine xderiveRead_dp1d
    2480              : !!***
    2481              : 
    2482              : !----------------------------------------------------------------------
    2483              : 
    2484              : !!****f* m_wffile/xderiveRead_dp2d
    2485              : !! NAME
    2486              : !!  xderiveRead_dp2d
    2487              : !!
    2488              : !! FUNCTION
    2489              : !!  Generic routine to read/write wf files with MPI I/O.
    2490              : !!  Target: double precision two-dimensional arrays.
    2491              : !!
    2492              : !! INPUTS
    2493              : !!  n1= first dimension of the array
    2494              : !!  n2= second dimension of the array
    2495              : !!  spaceComm= MPI communicator
    2496              : !!
    2497              : !! OUTPUT
    2498              : !!  ierr= exit status, a non-zero value meaning there is an error
    2499              : !!  xval= data buffer array
    2500              : !!
    2501              : !! SIDE EFFECTS
    2502              : !!  wff= structured info for reading/writing the wavefunctions
    2503              : !!
    2504              : !! SOURCE
    2505              : 
    2506            0 : subroutine xderiveRead_dp2d(wff,xval,n1,n2,spaceComm,ierr)
    2507              : 
    2508              : !Arguments ------------------------------------
    2509              :  type(wffile_type),intent(inout) :: wff
    2510              :  integer,intent(in) :: n1,n2,spaceComm
    2511              :  integer,intent(out) :: ierr
    2512              :  real(dp),intent(out) :: xval(:,:)
    2513              : 
    2514              : !Local variables-------------------------------
    2515              : #if defined HAVE_MPI_IO
    2516              :  integer(kind=MPI_OFFSET_KIND) :: delim_record,nboct,dispoct(1),posit,totoct
    2517              :  integer :: statux(MPI_STATUS_SIZE)
    2518              : #endif
    2519              :  character(len=500) :: msg
    2520              : 
    2521              : ! *********************************************************************
    2522              : 
    2523            0 :  xval(:,:)=zero ; ierr=0 ! Initialization, for the compiler
    2524              :  if(.false.)write(std_out,*)wff%me,n1,n2,spaceComm
    2525              : 
    2526              : #if defined HAVE_MPI_IO
    2527            0 :  nboct = wff%nbOct_dp * n1 *n2
    2528            0 :  posit = wff%offwff
    2529            0 :  delim_record = posit - wff%off_recs + wff%lght_recs - wff%nbOct_recMarker
    2530              : 
    2531            0 :  if (delim_record >= nboct) then
    2532              : !  Compute offset for local part
    2533              : !  dispoct = sum (nboct, rank=0..me)
    2534            0 :    if (spaceComm/=MPI_COMM_SELF) then
    2535            0 :      call MPI_SCAN([nboct],dispoct,1,wff%offset_mpi_type,MPI_SUM,spaceComm,ierr)
    2536            0 :      posit = posit + dispoct(1) - nboct
    2537              :    end if
    2538            0 :    call MPI_FILE_READ_AT(wff%fhwff,posit,xval,n1*n2,MPI_DOUBLE_PRECISION,statux,ierr)
    2539              : 
    2540              : !  get the total number of bits wrote by processors
    2541            0 :    if (spaceComm/=MPI_COMM_SELF) then
    2542            0 :      call xmpi_max(dispoct(1),totoct,spaceComm,ierr)
    2543              :      !call MPI_ALLREDUCE(dispoct,totoct,1,wff%offset_mpi_type,MPI_MAX,spaceComm,ierr)
    2544              :    else
    2545            0 :      totoct=nboct
    2546              :    end if
    2547              :  else
    2548            0 :    ierr = 1
    2549            0 :    nboct = 0
    2550            0 :    totoct = 0
    2551              :  end if
    2552              : 
    2553              : !new offset
    2554            0 :  wff%offwff=wff%offwff + totoct
    2555            0 :  return
    2556              : #endif
    2557              : 
    2558              :  write(msg,'(a,i0,a)')' The value of wff%iomode=',wff%iomode,' is not allowed.'
    2559              :  ABI_WARNING(msg)
    2560              : 
    2561              : end subroutine xderiveRead_dp2d
    2562              : !!***
    2563              : 
    2564              : !----------------------------------------------------------------------
    2565              : 
    2566              : 
    2567              : !!****f* m_wffile/xderiveRead_int2d_displ
    2568              : !! NAME
    2569              : !!  xderiveRead_int2d_displ
    2570              : !!
    2571              : !! FUNCTION
    2572              : !!  Generic routine to read/write wf files with MPI I/O.
    2573              : !!  Target: two-dimensional integer arrays.
    2574              : !!
    2575              : !! INPUTS
    2576              : !!  n1= first dimension of the array
    2577              : !!  n2= second dimension of the array
    2578              : !!  spaceComm= MPI communicator
    2579              : !!  displace= number of elements for the offset
    2580              : !!
    2581              : !! OUTPUT
    2582              : !!  ierr= exit status, a non-zero value meaning there is an error
    2583              : !!  xval= data buffer array
    2584              : !!
    2585              : !! SIDE EFFECTS
    2586              : !!  wff= structured info for reading/writing the wavefunctions
    2587              : !!
    2588              : !! SOURCE
    2589              : 
    2590            0 : subroutine xderiveRead_int2d_displ(wff,xval,n1,n2,spaceComm,displace,ierr)
    2591              : 
    2592              : !Arguments ------------------------------------
    2593              :  type(wffile_type),intent(inout) :: wff
    2594              :  integer,intent(in) :: n1,n2,spaceComm
    2595              :  integer,intent(out) :: ierr
    2596              :  integer,intent(out):: xval(:,:)
    2597              :  integer,intent(in):: displace(:)
    2598              : 
    2599              : !Local variables-------------------------------
    2600              : #if defined HAVE_MPI_IO
    2601              : !scalars
    2602              :  integer :: filetype,i1,i2,ipos,nb,nbval,totsize,wfftempo
    2603              : !arrays
    2604              :  integer :: statux(MPI_STATUS_SIZE)
    2605            0 :  integer,allocatable :: buf_val(:),length1(:),type1(:),val(:)
    2606            0 :  integer(kind=MPI_OFFSET_KIND),allocatable :: depl(:),depl1(:),depl_val(:)
    2607              : #endif
    2608              :  character(len=500) :: msg
    2609              : 
    2610              : ! *********************************************************************
    2611              : 
    2612            0 :  xval(:,:)=0 ; ierr=0
    2613              :  if(.false.)write(std_out,*)wff%me,n1,n2,spaceComm,displace
    2614              : 
    2615              : #if defined HAVE_MPI_IO
    2616            0 :  nb=n1*n2
    2617            0 :  call xmpi_sum(nb,totsize,spaceComm,ierr)
    2618            0 :  ABI_MALLOC(depl_val,(0:totsize-1))
    2619            0 :  ABI_MALLOC(depl,(nb))
    2620            0 :  ABI_MALLOC(buf_val,(0:totsize-1))
    2621            0 :  ABI_MALLOC(val,(nb))
    2622              : 
    2623              : !Map displacements
    2624            0 :  depl_val(0:totsize-1)=-1
    2625            0 :  do i2=1,n2
    2626            0 :    do i1=1,n1
    2627            0 :      ipos=(displace(i2)-1)*n1 + i1-1
    2628            0 :      depl_val(ipos)=ipos
    2629              :    end do
    2630              :  end do
    2631              : !To save time, the location described by array map must be in increasing order
    2632            0 :  nbval=0
    2633            0 :  do i1=0,totsize-1
    2634            0 :    if (depl_val(i1)/=-1) then
    2635            0 :      nbval=nbval+1
    2636            0 :      depl(nbval)=depl_val(i1)
    2637              :    end if
    2638              :  end do
    2639              : 
    2640              : !Build MPI datatype for view
    2641            0 :  ABI_MALLOC(length1,(nbval+2))
    2642            0 :  ABI_MALLOC(depl1,(nbval+2))
    2643            0 :  ABI_MALLOC(type1,(nbval+2))
    2644            0 :  length1(1)=1;depl1(1)=0;type1(1)=MPI_LB
    2645            0 :  do i1=2,nbval+1
    2646            0 :    length1(i1) = 1
    2647            0 :    depl1(i1)= depl(i1-1)*wff%nbOct_int
    2648            0 :    type1(i1)= MPI_INTEGER
    2649              :  end do
    2650            0 :  length1(nbval+2)=1;depl1(nbval+2)=totsize*wff%nbOct_int;type1(nbval+2)=MPI_UB
    2651            0 :  call xmpio_type_struct(nbval+2,length1,depl1,type1,filetype,ierr)
    2652            0 :  call MPI_TYPE_COMMIT(filetype,ierr)
    2653            0 :  ABI_FREE(length1)
    2654            0 :  ABI_FREE(depl1)
    2655            0 :  ABI_FREE(type1)
    2656              : 
    2657              : !Write data
    2658            0 :  call MPI_FILE_OPEN(spaceComm,wff%fname,MPI_MODE_RDWR,MPI_INFO_NULL,wfftempo,ierr)
    2659            0 :  ABI_CHECK_MPI(ierr, sjoin("MPI_FILE_OPEN:", wff%fname))
    2660            0 :  call MPI_FILE_SET_VIEW(wfftempo,wff%offwff,MPI_BYTE,filetype,"native",MPI_INFO_NULL,ierr)
    2661            0 :  call MPI_FILE_READ_ALL(wfftempo,val,nbval,MPI_INTEGER,statux,ierr)
    2662            0 :  call MPI_FILE_CLOSE(wfftempo,ierr)
    2663              : 
    2664              : !Retrieve xval
    2665            0 :  nbval=0
    2666            0 :  do i1=0,totsize-1
    2667            0 :    if (depl_val(i1)/=-1) then
    2668            0 :      nbval=nbval+1
    2669            0 :      buf_val(i1)=val(nbval)
    2670              :    end if
    2671              :  end do
    2672            0 :  do i2=1,n2
    2673            0 :    do i1=1,n1
    2674            0 :      ipos=(displace(i2)-1)*n1 + i1-1
    2675            0 :      xval(i1,i2)=buf_val(ipos)
    2676              :    end do
    2677              :  end do
    2678              : 
    2679              : !Update offset
    2680            0 :  wff%offwff = wff%offwff + totsize*wff%nbOct_int
    2681              : 
    2682              : !Free memory
    2683            0 :  call MPI_TYPE_FREE(filetype,ierr)
    2684            0 :  ABI_FREE(depl)
    2685            0 :  ABI_FREE(depl_val)
    2686            0 :  ABI_FREE(buf_val)
    2687            0 :  ABI_FREE(val)
    2688              :  return
    2689              : #endif
    2690              : 
    2691              :  write(msg,'(a,i0,a)')' The value of wff%iomode=',wff%iomode,' is not allowed.'
    2692              :  ABI_WARNING(msg)
    2693              : 
    2694              : 
    2695            0 : end subroutine xderiveRead_int2d_displ
    2696              : !!***
    2697              : 
    2698              : !----------------------------------------------------------------------
    2699              : 
    2700              : !!****f* m_wffile/xderiveRead_dp2d_displ
    2701              : !! NAME
    2702              : !!  xderiveRead_dp2d_displ
    2703              : !!
    2704              : !! FUNCTION
    2705              : !!  Generic routine to read/write wf files with MPI I/O.
    2706              : !!  Target: double precision two-dimensional arrays.
    2707              : !!
    2708              : !! INPUTS
    2709              : !!  n1= first dimension of the array
    2710              : !!  n2= second dimension of the array
    2711              : !!  spaceComm= MPI communicator
    2712              : !!  displace= number of elements for the offset
    2713              : !!
    2714              : !! OUTPUT
    2715              : !!  ierr= exit status, a non-zero value meaning there is an error
    2716              : !!  xval= data buffer array
    2717              : !!
    2718              : !! SIDE EFFECTS
    2719              : !!  wff= structured info for reading/writing the wavefunctions
    2720              : !!
    2721              : !! SOURCE
    2722              : 
    2723            0 : subroutine xderiveRead_dp2d_displ(wff,xval,n1,n2,spaceComm,displace,ierr)
    2724              : 
    2725              : !Arguments ------------------------------------
    2726              :  type(wffile_type),intent(inout) :: wff
    2727              :  integer,intent(in) :: n1,n2,spaceComm
    2728              :  integer,intent(out) :: ierr
    2729              :  real(dp),intent(out):: xval(:,:)
    2730              :  integer,intent(in):: displace(:)
    2731              : 
    2732              : !Local variables-------------------------------
    2733              : #if defined HAVE_MPI_IO
    2734              : !scalars
    2735              :  integer :: filetype,i1,i2,ipos,nb,nbval,totsize,wfftempo
    2736              : !arrays
    2737              :  integer :: statux(MPI_STATUS_SIZE)
    2738            0 :  integer,allocatable :: length1(:),type1(:)
    2739            0 :  integer(kind=MPI_OFFSET_KIND),allocatable :: depl(:),depl1(:),depl_val(:)
    2740            0 :  real(dp), allocatable :: buf_val(:),val(:)
    2741              : #endif
    2742              : 
    2743              : ! *********************************************************************
    2744              : 
    2745            0 :  xval(:,:)=zero ; ierr=0
    2746              :  if(.false.)write(std_out,*)wff%me,n1,n2,displace,spaceComm
    2747              : 
    2748              : #if defined HAVE_MPI_IO
    2749            0 :  nb=n1*n2
    2750            0 :  call xmpi_sum(nb,totsize,spaceComm,ierr)
    2751            0 :  ABI_MALLOC(depl_val,(0:totsize-1))
    2752            0 :  ABI_MALLOC(depl,(nb))
    2753            0 :  ABI_MALLOC(buf_val,(0:totsize-1))
    2754            0 :  ABI_MALLOC(val,(nb))
    2755              : 
    2756              : !Map displacements
    2757            0 :  depl_val(0:totsize-1)=-1
    2758            0 :  do i2=1,n2
    2759            0 :    do i1=1,n1
    2760            0 :      ipos=(displace(i2)-1)*n1 + i1-1
    2761            0 :      depl_val(ipos)=ipos
    2762              :    end do
    2763              :  end do
    2764              : !To save time, the location describe by array map must be in increasing order
    2765            0 :  nbval=0
    2766            0 :  do i1=0,totsize-1
    2767            0 :    if (depl_val(i1)/=-1) then
    2768            0 :      nbval=nbval+1
    2769            0 :      depl(nbval)=depl_val(i1)
    2770              :    end if
    2771              :  end do
    2772              : 
    2773              : !Build MPI datatype for view
    2774            0 :  ABI_MALLOC(length1,(nbval+2))
    2775            0 :  ABI_MALLOC(depl1,(nbval+2))
    2776            0 :  ABI_MALLOC(type1,(nbval+2))
    2777            0 :  length1(1)=1;depl1(1)=0;type1(1)=MPI_LB
    2778            0 :  do i1=2,nbval+1
    2779            0 :    length1(i1) = 1
    2780            0 :    depl1(i1)= depl(i1-1)*wff%nbOct_dp
    2781            0 :    type1(i1)= MPI_DOUBLE_PRECISION
    2782              :  end do
    2783            0 :  length1(nbval+2)=1;depl1(nbval+2)=totsize*wff%nbOct_dp;type1(nbval+2)=MPI_UB
    2784            0 :  call xmpio_type_struct(nbval+2,length1,depl1,type1,filetype,ierr)
    2785            0 :  call MPI_TYPE_COMMIT(filetype,ierr)
    2786            0 :  ABI_FREE(length1)
    2787            0 :  ABI_FREE(depl1)
    2788            0 :  ABI_FREE(type1)
    2789              : 
    2790              : !Write data
    2791            0 :  call MPI_FILE_OPEN(spaceComm,wff%fname,MPI_MODE_RDWR,MPI_INFO_NULL,wfftempo,ierr)
    2792            0 :  ABI_CHECK_MPI(ierr, sjoin("MPI_FILE_OPEN:", wff%fname))
    2793            0 :  call MPI_FILE_SET_VIEW(wfftempo,wff%offwff,MPI_BYTE,filetype,"native",MPI_INFO_NULL,ierr)
    2794            0 :  call MPI_FILE_READ_ALL(wfftempo,val,nbval,MPI_DOUBLE_PRECISION,statux,ierr)
    2795            0 :  call MPI_FILE_CLOSE(wfftempo,ierr)
    2796              : 
    2797              : !Retrieve xval
    2798            0 :  nbval=0
    2799            0 :  do i1=0,totsize-1
    2800            0 :    if (depl_val(i1)/=-1) then
    2801            0 :      nbval=nbval+1
    2802            0 :      buf_val(i1)=val(nbval)
    2803              :    end if
    2804              :  end do
    2805            0 :  do i2=1,n2
    2806            0 :    do i1=1,n1
    2807            0 :      ipos=(displace(i2)-1)*n1 + i1-1
    2808            0 :      xval(i1,i2)=buf_val(ipos)
    2809              :    end do
    2810              :  end do
    2811              : 
    2812              : !Update offset
    2813            0 :  wff%offwff = wff%offwff + totsize*wff%nbOct_dp
    2814              : 
    2815              : !Free memory
    2816            0 :  call MPI_TYPE_FREE(filetype,ierr)
    2817            0 :  ABI_FREE(depl)
    2818            0 :  ABI_FREE(depl_val)
    2819            0 :  ABI_FREE(buf_val)
    2820            0 :  ABI_FREE(val)
    2821              : #endif
    2822              : 
    2823            0 : end subroutine xderiveRead_dp2d_displ
    2824              : !!***
    2825              : 
    2826              : !----------------------------------------------------------------------
    2827              : 
    2828              : !!****f* m_wffile/xderiveReadVal_char
    2829              : !! NAME
    2830              : !!  xderiveReadVal_char
    2831              : !!
    2832              : !! FUNCTION
    2833              : !!  Generic routine to read/write wf files with MPI I/O.
    2834              : !!  Target: character string.
    2835              : !!
    2836              : !! INPUTS
    2837              : !!  n= number of elements in the array
    2838              : !!
    2839              : !! OUTPUT
    2840              : !!  xval= data buffer array
    2841              : !!  ierr= exit status, a non-zero value meaning there is an error
    2842              : !!
    2843              : !! SIDE EFFECTS
    2844              : !!  wff= structured info for reading/writing the wavefunctions
    2845              : !!
    2846              : !! SOURCE
    2847              : 
    2848            0 : subroutine xderiveReadVal_char(wff,xval,n,ierr)
    2849              : 
    2850              : !Arguments ------------------------------------
    2851              :  type(wffile_type),intent(inout) :: wff
    2852              :  integer,intent(in) :: n
    2853              :  integer,intent(out) :: ierr
    2854              :  character(len=*),intent(out),target :: xval
    2855              : 
    2856              : !Local variables-------------------------------
    2857              : #if defined HAVE_MPI_IO
    2858              :  integer :: statux(MPI_STATUS_SIZE)
    2859              :  character,pointer :: arr_xval(:)
    2860              :  type(c_ptr) :: cptr
    2861              : #endif
    2862              : 
    2863              : ! *********************************************************************
    2864              : 
    2865            0 :  xval=' ' ; ierr=0
    2866              :  if(.false.)write(std_out,*)wff%me,n
    2867              : 
    2868              : #if defined HAVE_MPI_IO
    2869            0 :  cptr=c_loc(xval) ; call c_f_pointer(cptr,arr_xval,[n])
    2870            0 :  call MPI_FILE_READ_AT(wff%fhwff,wff%offwff,arr_xval,n,MPI_CHARACTER,statux,ierr)
    2871            0 :  wff%offwff = wff%offwff + wff%nbOct_ch * n
    2872              : #endif
    2873              : 
    2874            0 : end subroutine xderiveReadVal_char
    2875              : !!***
    2876              : 
    2877              : !----------------------------------------------------------------------
    2878              : 
    2879              : !!****f* m_wffile/xmpi_read_int2d
    2880              : !! NAME
    2881              : !!  xmpi_read_int2d
    2882              : !!
    2883              : !! FUNCTION
    2884              : !!  Generic routine to read arrays with MPI I/O.
    2885              : !!  Target: integer two-dimensional arrays.
    2886              : !!
    2887              : !! INPUTS
    2888              : !!  sc_mode=
    2889              : !!    xmpio_single     ==> Local reading.
    2890              : !!    xmpio_collective ==> Collective reading.
    2891              : !!  spaceComm= MPI communicator
    2892              : !!
    2893              : !! OUTPUT
    2894              : !!  xval= data buffer array
    2895              : !!  ierr= exit status, a non-zero value meaning there is an error
    2896              : !!
    2897              : !! SIDE EFFECTS
    2898              : !!  wff= structured info for reading/writing the wavefunctions
    2899              : !!
    2900              : !! SOURCE
    2901              : 
    2902            0 : subroutine xmpi_read_int2d(wff,xval,spaceComm,sc_mode,ierr)
    2903              : 
    2904              : !Arguments ------------------------------------
    2905              : !scalars
    2906              :  integer,intent(in) :: spaceComm,sc_mode
    2907              :  integer,intent(out) :: ierr
    2908              :  type(wffile_type),intent(inout) :: wff
    2909              : !array
    2910              :  integer,intent(out) :: xval(:,:)
    2911              : 
    2912              : !Local variables-------------------------------
    2913              :  integer :: n1,n2
    2914              : #ifdef HAVE_MPI_IO
    2915              :  integer(kind=MPI_OFFSET_KIND) :: delim_record,nboct,posit,totoct
    2916              :  character(len=500) :: msg
    2917              : !arrays
    2918              :  integer :: statux(MPI_STATUS_SIZE)
    2919              : #endif
    2920              : 
    2921              : ! *********************************************************************
    2922              : 
    2923            0 :  ierr=0
    2924            0 :  n1 = SIZE(xval,DIM=1)
    2925            0 :  n2 = SIZE(xval,DIM=2)
    2926              : 
    2927              : #ifdef HAVE_MPI_IO
    2928            0 :  nboct = wff%nbOct_int * n1 *n2
    2929            0 :  posit = wff%offwff
    2930            0 :  delim_record = posit - wff%off_recs + wff%lght_recs - wff%nbOct_recMarker
    2931              : 
    2932            0 :  if (delim_record >= nboct) then
    2933              : 
    2934            0 :    select case (sc_mode)
    2935              :      case (xmpio_single)
    2936            0 :        call MPI_FILE_READ_AT(wff%fhwff,posit,xval,n1*n2,MPI_INTEGER,statux,ierr)
    2937              : 
    2938              :      case (xmpio_collective)
    2939            0 :        call MPI_FILE_READ_AT_ALL(wff%fhwff,posit,xval,n1*n2,MPI_INTEGER,statux,ierr)
    2940              : 
    2941              :      case default
    2942            0 :        write(msg,('(a,i0)'))" Wrong value for sc_mode: ",sc_mode
    2943            0 :        ABI_ERROR(msg)
    2944              :    end select
    2945              : 
    2946              :    totoct=nboct
    2947              :  else
    2948            0 :    write(msg,('(a,2(i0,1x))'))" delim_record < nboct: ",delim_record,nboct
    2949            0 :    ABI_WARNING(msg)
    2950            0 :    ierr=MPI_ERR_UNKNOWN
    2951            0 :    totoct=0
    2952              :  end if
    2953              : !
    2954              : !Increment the offset.
    2955            0 :  wff%offwff=wff%offwff + totoct
    2956              : #endif
    2957              : 
    2958            0 :  RETURN
    2959              :  ABI_UNUSED(xval(1,1))
    2960              :  ABI_UNUSED((/wff%me,spaceComm,sc_mode/))
    2961              : 
    2962              : end subroutine xmpi_read_int2d
    2963              : !!***
    2964              : 
    2965              : !----------------------------------------------------------------------
    2966              : 
    2967              : !!****f* m_wffile/xderiveWrite_int
    2968              : !! NAME
    2969              : !!  xderiveWrite_int
    2970              : !!
    2971              : !! FUNCTION
    2972              : !!  Generic routine to read/write wf files with MPI I/O.
    2973              : !!  Target: integer scalar.
    2974              : !!
    2975              : !! INPUTS
    2976              : !!  xval= data buffer
    2977              : !!
    2978              : !! OUTPUT
    2979              : !!  ierr= exit status, a non-zero value meaning there is an error
    2980              : !!
    2981              : !! SIDE EFFECTS
    2982              : !!  wff= structured info for reading/writing the wavefunctions
    2983              : !!
    2984              : !! SOURCE
    2985              : 
    2986           45 : subroutine xderiveWrite_int(wff,xval,ierr)
    2987              : 
    2988              : !Arguments ------------------------------------
    2989              :  integer,intent(out) :: ierr
    2990              :  integer,intent(in):: xval
    2991              :  type(wffile_type),intent(inout) :: wff
    2992              : 
    2993              : !Local variables-------------------------------
    2994              : #if defined HAVE_MPI_IO
    2995              :  integer :: statux(MPI_STATUS_SIZE),arr_xval(1)
    2996              : #endif
    2997              : ! *********************************************************************
    2998              : 
    2999           45 :  ierr=0
    3000              :  if(.false.)write(std_out,*)wff%me,xval
    3001              : #if defined HAVE_MPI_IO
    3002           45 :  arr_xval(1) = xval
    3003           45 :  call MPI_FILE_WRITE_AT(wff%fhwff,wff%offwff,arr_xval,1,MPI_INTEGER,statux,ierr)
    3004           45 :  wff%offwff = wff%offwff+wff%nbOct_int
    3005              : #endif
    3006              : 
    3007           45 : end subroutine xderiveWrite_int
    3008              : !!***
    3009              : 
    3010              : !----------------------------------------------------------------------
    3011              : 
    3012              : 
    3013              : !!****f* m_wffile/xderiveWrite_int1d
    3014              : !! NAME
    3015              : !!  xderiveWrite_int1d
    3016              : !!
    3017              : !! FUNCTION
    3018              : !!  Generic routine to read/write wf files with MPI I/O.
    3019              : !!  Target: one-dimensional integer arrays.
    3020              : !!
    3021              : !! INPUTS
    3022              : !!  n1= first dimension of the array
    3023              : !!  spaceComm= MPI communicator
    3024              : !!  xval= data buffer array
    3025              : !!
    3026              : !! OUTPUT
    3027              : !!  ierr= exit status, a non-zero value meaning there is an error
    3028              : !!
    3029              : !! SIDE EFFECTS
    3030              : !!  wff= structured info for reading/writing the wavefunctions
    3031              : !!
    3032              : !! SOURCE
    3033              : 
    3034            0 : subroutine xderiveWrite_int1d(wff,xval,n1,spaceComm,ierr)
    3035              : 
    3036              : !Arguments ------------------------------------
    3037              :  integer,intent(in) :: n1,spaceComm
    3038              :  integer,intent(out) :: ierr
    3039              :  integer,intent(in):: xval(:)
    3040              :  type(wffile_type),intent(inout) :: wff
    3041              : 
    3042              : !Local variables-------------------------------
    3043              : #if defined HAVE_MPI_IO
    3044              :  integer(kind=MPI_OFFSET_KIND) :: nboct,dispoct(1),posit,totoct
    3045              :  integer :: statux(MPI_STATUS_SIZE)
    3046              : #endif
    3047              : ! *********************************************************************
    3048              : 
    3049            0 :  ierr=0
    3050              :  if(.false.)write(std_out,*)wff%me,n1,spaceComm,xval
    3051              : #if defined HAVE_MPI_IO
    3052            0 :  nboct = n1*wff%nbOct_int
    3053            0 :  posit = wff%offwff
    3054              : 
    3055              : !dispoct = sum (nboct, rank=0..me)
    3056            0 :  if (spaceComm/=MPI_COMM_SELF) then
    3057            0 :    call MPI_SCAN([nboct],dispoct,1,wff%offset_mpi_type,MPI_SUM,spaceComm,ierr)
    3058            0 :    posit = posit + dispoct(1) - nboct
    3059              :  end if
    3060            0 :  call MPI_FILE_WRITE_AT(wff%fhwff,posit,xval,n1,MPI_INTEGER,statux,ierr)
    3061              : !gather the bigest offset
    3062              : 
    3063            0 :  if (spaceComm/=MPI_COMM_SELF) then
    3064            0 :    call xmpi_max(dispoct(1),totoct,spaceComm,ierr)
    3065              :    !call MPI_ALLREDUCE(dispoct,totoct,1,wff%offset_mpi_type,MPI_MAX,spaceComm,ierr)
    3066              :  else
    3067            0 :    totoct=nboct
    3068              :  end if
    3069            0 :  wff%offwff = wff%offwff + totoct
    3070              : 
    3071              : !Disable old code
    3072              : #endif
    3073              : 
    3074            0 : end subroutine xderiveWrite_int1d
    3075              : !!***
    3076              : 
    3077              : !----------------------------------------------------------------------
    3078              : 
    3079              : !!****f* m_wffile/xderiveWrite_int2d
    3080              : !! NAME
    3081              : !!  xderiveWrite_int2d
    3082              : !!
    3083              : !! FUNCTION
    3084              : !!  Generic routine to read/write wf files with MPI I/O.
    3085              : !!  Target: two-dimensional integer arrays.
    3086              : !!
    3087              : !! INPUTS
    3088              : !!  n1= first dimension of the array
    3089              : !!  n2= second dimension of the array
    3090              : !!  spaceComm= MPI communicator
    3091              : !!  xval= data buffer array
    3092              : !!
    3093              : !! OUTPUT
    3094              : !!  ierr= exit status, a non-zero value meaning there is an error
    3095              : !!
    3096              : !! SIDE EFFECTS
    3097              : !!  wff= structured info for reading/writing the wavefunctions
    3098              : !!
    3099              : !! SOURCE
    3100              : 
    3101            0 : subroutine xderiveWrite_int2d(wff,xval,n1,n2,spaceComm,ierr)
    3102              : 
    3103              : !Arguments ------------------------------------
    3104              :  integer,intent(in) :: n1,n2,spaceComm
    3105              :  integer,intent(out) :: ierr
    3106              :  integer,intent(in):: xval(:,:)
    3107              :  type(wffile_type),intent(inout) :: wff
    3108              : 
    3109              : !Local variables-------------------------------
    3110              : #if defined HAVE_MPI_IO
    3111              :  integer(kind=MPI_OFFSET_KIND) :: nboct,dispoct(1),posit,totoct
    3112              :  integer  :: statux(MPI_STATUS_SIZE)
    3113              : #endif
    3114              : 
    3115              : ! *********************************************************************
    3116              : 
    3117            0 :  ierr=0
    3118              :  if(.false.)write(std_out,*)wff%me,n1,n2,spaceComm,xval
    3119              : #if defined HAVE_MPI_IO
    3120            0 :  nboct = n1*n2*wff%nbOct_int
    3121            0 :  posit = wff%offwff
    3122              : 
    3123              : !dispoct = sum(nboct, rank=0..me)
    3124            0 :  if (spaceComm/=MPI_COMM_SELF) then
    3125            0 :    call MPI_SCAN([nboct],dispoct,1,wff%offset_mpi_type,MPI_SUM,spaceComm,ierr)
    3126            0 :    posit = posit + dispoct(1) - nboct
    3127              :  end if
    3128            0 :  call MPI_FILE_WRITE_AT(wff%fhwff,posit,xval,n1*n2,MPI_INTEGER,statux,ierr)
    3129              : !gather the biggest offset
    3130            0 :  if (spaceComm/=MPI_COMM_SELF) then
    3131            0 :    call xmpi_max(dispoct(1),totoct,spaceComm,ierr)
    3132              :    !call MPI_ALLREDUCE(dispoct,totoct,1,wff%offset_mpi_type,MPI_MAX,spaceComm,ierr)
    3133              :  else
    3134            0 :    totoct=nboct
    3135              :  end if
    3136            0 :  wff%offwff = wff%offwff + totoct
    3137              : #endif
    3138              : 
    3139            0 : end subroutine xderiveWrite_int2d
    3140              : !!***
    3141              : 
    3142              : !----------------------------------------------------------------------
    3143              : 
    3144              : 
    3145              : !!****f* m_wffile/xderiveWrite_dp
    3146              : !! NAME
    3147              : !!  xderiveWrite_dp
    3148              : !!
    3149              : !! FUNCTION
    3150              : !!  Generic routine to read/write wf files with MPI I/O.
    3151              : !!  Target: double precision scalar.
    3152              : !!
    3153              : !! INPUTS
    3154              : !!  xval= data buffer
    3155              : !!
    3156              : !! OUTPUT
    3157              : !!  ierr= exit status, a non-zero value meaning there is an error
    3158              : !!
    3159              : !! SIDE EFFECTS
    3160              : !!  wff= structured info for reading/writing the wavefunctions
    3161              : !!
    3162              : !! SOURCE
    3163              : 
    3164            0 : subroutine xderiveWrite_dp(wff,xval,ierr)
    3165              : 
    3166              : !Arguments ------------------------------------
    3167              :  integer,intent(out) :: ierr
    3168              :  real(dp),intent(in):: xval
    3169              :  type(wffile_type),intent(inout) :: wff
    3170              : 
    3171              : !Local variables-------------------------------
    3172              : #if defined HAVE_MPI_IO
    3173              :  integer :: statux(MPI_STATUS_SIZE)
    3174              : #endif
    3175              : ! *********************************************************************
    3176              : 
    3177            0 :  ierr=0
    3178              :  if(.false.)write(std_out,*)wff%me,xval
    3179              : #if defined HAVE_MPI_IO
    3180            0 :  call MPI_FILE_WRITE_AT(wff%fhwff,wff%offwff,[xval],1,MPI_DOUBLE_PRECISION,statux,ierr)
    3181            0 :  wff%offwff = wff%offwff+wff%nbOct_dp
    3182              : #endif
    3183              : 
    3184            0 : end subroutine xderiveWrite_dp
    3185              : !!***
    3186              : 
    3187              : !----------------------------------------------------------------------
    3188              : 
    3189              : 
    3190              : !!****f* m_wffile/xderiveWrite_dp1d
    3191              : !! NAME
    3192              : !!  xderiveWrite_dp1d
    3193              : !!
    3194              : !! FUNCTION
    3195              : !!  Generic routine to read/write wf files with MPI I/O.
    3196              : !!  Target: one-dimensional double precision arrays.
    3197              : !!
    3198              : !! INPUTS
    3199              : !!  n1= first dimension of the array
    3200              : !!  spaceComm= MPI communicator
    3201              : !!  xval= data buffer array
    3202              : !!
    3203              : !! OUTPUT
    3204              : !!  ierr= exit status, a non-zero value meaning there is an error
    3205              : !!
    3206              : !! SIDE EFFECTS
    3207              : !!  wff= structured info for reading/writing the wavefunctions
    3208              : !!
    3209              : !! SOURCE
    3210              : 
    3211           30 : subroutine xderiveWrite_dp1d(wff,xval,n1,spaceComm,ierr)
    3212              : 
    3213              : !Arguments ------------------------------------
    3214              :  integer,intent(in) :: n1,spaceComm
    3215              :  integer,intent(out) :: ierr
    3216              :  real(dp),intent(in):: xval(:)
    3217              :  type(wffile_type),intent(inout) :: wff
    3218              : 
    3219              : !Local variables-------------------------------
    3220              : #if defined HAVE_MPI_IO
    3221              :  integer(kind=MPI_OFFSET_KIND) :: nboct,dispoct(1),posit,totoct
    3222              :  integer  :: statux(MPI_STATUS_SIZE)
    3223              : #endif
    3224              : 
    3225              : ! *********************************************************************
    3226              : 
    3227           30 :  ierr=0
    3228              :  if(.false.)write(std_out,*)wff%me,n1,spaceComm,xval
    3229              : #if defined HAVE_MPI_IO
    3230           30 :  nboct = n1*wff%nbOct_dp
    3231           30 :  posit = wff%offwff
    3232              : !dispoct = sum (nboct, rank = 0..me)
    3233           30 :  if (spaceComm/=MPI_COMM_SELF) then
    3234            0 :    call MPI_SCAN([nboct],dispoct,1,wff%offset_mpi_type,MPI_SUM,spaceComm,ierr)
    3235            0 :    posit = posit + dispoct(1) - nboct
    3236              :  end if
    3237           30 :  call MPI_FILE_WRITE_AT(wff%fhwff,posit,xval,n1,MPI_DOUBLE_PRECISION,statux,ierr)
    3238              : !Gather the biggest offset
    3239           30 :  if (spaceComm/=MPI_COMM_SELF) then
    3240            0 :    call xmpi_max(dispoct(1),totoct,spaceComm,ierr)
    3241              :    !call MPI_ALLREDUCE(dispoct,totoct,1,wff%offset_mpi_type,MPI_MAX,spaceComm,ierr)
    3242              :  else
    3243           30 :    totoct=nboct
    3244              :  end if
    3245           30 :  wff%offwff = wff%offwff + totoct
    3246              : #endif
    3247              : 
    3248           30 : end subroutine xderiveWrite_dp1d
    3249              : !!***
    3250              : 
    3251              : !----------------------------------------------------------------------
    3252              : 
    3253              : !!****f* m_wffile/xderiveWrite_dp2d
    3254              : !! NAME
    3255              : !!  xderiveWrite_dp2d
    3256              : !!
    3257              : !! FUNCTION
    3258              : !!  Generic routine to read/write wf files with MPI I/O.
    3259              : !!  Target: double precision two-dimensional arrays.
    3260              : !!
    3261              : !! INPUTS
    3262              : !!  n1= first dimension of the array
    3263              : !!  n2= second dimension of the array
    3264              : !!  spaceComm= MPI communicator
    3265              : !!  xval= data buffer array
    3266              : !!
    3267              : !! OUTPUT
    3268              : !!  ierr= exit status, a non-zero value meaning there is an error
    3269              : !!
    3270              : !! SIDE EFFECTS
    3271              : !!  wff= structured info for reading/writing the wavefunctions
    3272              : !!
    3273              : !! SOURCE
    3274              : 
    3275            0 : subroutine xderiveWrite_dp2d(wff,xval,n1,n2,spaceComm,ierr)
    3276              : 
    3277              : !Arguments ------------------------------------
    3278              :  integer,intent(in) :: n1,n2,spaceComm
    3279              :  integer,intent(out) :: ierr
    3280              :  real(dp),intent(in):: xval(:,:)
    3281              :  type(wffile_type),intent(inout) :: wff
    3282              : 
    3283              : !Local variables-------------------------------
    3284              : #if defined HAVE_MPI_IO
    3285              :  integer(kind=MPI_OFFSET_KIND) :: nboct,dispoct(1),posit,totoct
    3286              :  integer :: statux(MPI_STATUS_SIZE)
    3287              : #endif
    3288              : 
    3289              : ! *********************************************************************
    3290              : 
    3291            0 :  ierr=0
    3292              :  if(.false.)write(std_out,*)wff%me,xval,n1,n2,spaceComm
    3293              : 
    3294              : #if defined HAVE_MPI_IO
    3295            0 :  nboct = n1*n2*wff%nbOct_dp
    3296            0 :  posit = wff%offwff
    3297              : !dispoct = sum(nboct, rank=0..me)
    3298            0 :  if (spaceComm/=MPI_COMM_SELF) then
    3299            0 :    call MPI_SCAN([nboct],dispoct,1,wff%offset_mpi_type,MPI_SUM,spaceComm,ierr)
    3300            0 :    posit = posit + dispoct(1) - nboct
    3301              :  end if
    3302            0 :  call MPI_FILE_WRITE_AT(wff%fhwff,posit,xval,n1*n2,MPI_DOUBLE_PRECISION,statux,ierr)
    3303            0 :  posit = posit + nboct
    3304              : !gather the biggest offset
    3305            0 :  if (spaceComm/=MPI_COMM_SELF) then
    3306            0 :    call xmpi_max(dispoct(1),totoct,spaceComm,ierr)
    3307              :    !call MPI_ALLREDUCE(dispoct,totoct,1,wff%offset_mpi_type,MPI_MAX,spaceComm,ierr)
    3308              :  else
    3309            0 :    totoct=nboct
    3310              :  end if
    3311            0 :  wff%offwff = wff%offwff + totoct
    3312              : #endif
    3313              : 
    3314            0 : end subroutine xderiveWrite_dp2d
    3315              : !!***
    3316              : 
    3317              : !----------------------------------------------------------------------
    3318              : 
    3319              : !!****f* m_wffile/xderiveWrite_dp2d_seq
    3320              : !! NAME
    3321              : !!  xderiveWrite_dp2d_seq
    3322              : !!
    3323              : !! FUNCTION
    3324              : !!  Generic routine to read/write wf files with MPI I/O.
    3325              : !!  Target: double precision two-dimensional arrays.
    3326              : !!
    3327              : !! INPUTS
    3328              : !!  xval= data buffer array
    3329              : !!
    3330              : !! OUTPUT
    3331              : !!  ierr= exit status, a non-zero value meaning there is an error
    3332              : !!
    3333              : !! SIDE EFFECTS
    3334              : !!  wff= structured info for reading/writing the wavefunctions
    3335              : !!
    3336              : !! SOURCE
    3337              : 
    3338            0 : subroutine xderiveWrite_dp2d_seq(wff,xval,ierr)
    3339              : 
    3340              : !Arguments ------------------------------------
    3341              :  integer,intent(out) :: ierr
    3342              :  real(dp),intent(in):: xval(:,:)
    3343              :  type(wffile_type),intent(inout) :: wff
    3344              : 
    3345              : !Local variables-------------------------------
    3346              : #if defined HAVE_MPI_IO
    3347              :  integer :: n1,n2
    3348              :  integer :: statux(MPI_STATUS_SIZE)
    3349              : #endif
    3350              : ! *********************************************************************
    3351              : 
    3352            0 :  ierr=0
    3353              :  if(.false.)write(std_out,*)wff%me,xval
    3354              : #if defined HAVE_MPI_IO
    3355            0 :  n1=size(xval,1);n2=size(xval,2)
    3356            0 :  call MPI_FILE_WRITE_AT(wff%fhwff,wff%offwff,xval,n1*n2,MPI_DOUBLE_PRECISION,statux,ierr)
    3357            0 :  wff%offwff = wff%offwff+wff%nbOct_dp*n1*n2
    3358              : #endif
    3359              : 
    3360            0 : end subroutine xderiveWrite_dp2d_seq
    3361              : !!***
    3362              : 
    3363              : !----------------------------------------------------------------------
    3364              : 
    3365              : 
    3366              : !!****f* m_wffile/xderiveWrite_int2d_displ
    3367              : !! NAME
    3368              : !!  xderiveWrite_int2d_displ
    3369              : !!
    3370              : !! FUNCTION
    3371              : !!  Generic routine to read/write wf files with MPI I/O.
    3372              : !!  Target: two-dimensional integer arrays.
    3373              : !!
    3374              : !! INPUTS
    3375              : !!  n1= first dimension of the array
    3376              : !!  n2= second dimension of the array
    3377              : !!  spaceComm= MPI communicator
    3378              : !!  xval= data buffer array
    3379              : !!  displace= number of elements for the offset
    3380              : !!
    3381              : !! OUTPUT
    3382              : !!  ierr= exit status, a non-zero value meaning there is an error
    3383              : !!
    3384              : !! SIDE EFFECTS
    3385              : !!  wff= structured info for reading/writing the wavefunctions
    3386              : !!
    3387              : !! SOURCE
    3388              : 
    3389           38 : subroutine xderiveWrite_int2d_displ(wff,xval,n1,n2,spaceComm,displace,ierr)
    3390              : 
    3391              : !Arguments ------------------------------------
    3392              :  integer,intent(in) :: n1,n2,spaceComm
    3393              :  integer,intent(out) :: ierr
    3394              :  integer,intent(in):: displace(:),xval(:,:)
    3395              :  type(wffile_type),intent(inout) :: wff
    3396              : 
    3397              : !Local variables-------------------------------
    3398              : #if defined HAVE_MPI_IO
    3399              : !scalars
    3400              :  integer :: filetype,i1,i2,ipos,nb,nbval,totsize,wfftempo
    3401              : !arrays
    3402              :  integer :: statux(MPI_STATUS_SIZE)
    3403           38 :  integer, allocatable :: buf_val(:),length1(:),type1(:),val(:)
    3404           38 :  integer(kind=MPI_OFFSET_KIND),allocatable :: depl(:),depl1(:),depl_val(:)
    3405              : #endif
    3406              : 
    3407              : ! *********************************************************************
    3408              : 
    3409              :  ierr=0
    3410              :  if(.false.)write(std_out,*)wff%me,xval,n1,n2,spaceComm,displace
    3411              : 
    3412              : #if defined HAVE_MPI_IO
    3413           38 :  nb = n1*n2
    3414           38 :  call xmpi_sum(nb,totsize,spaceComm,ierr)
    3415          114 :  ABI_MALLOC(depl_val,(0:totsize-1))
    3416          114 :  ABI_MALLOC(depl,(nb))
    3417          114 :  ABI_MALLOC(buf_val,(0:totsize-1))
    3418          114 :  ABI_MALLOC(val,(nb))
    3419              : 
    3420              : !Map displacements
    3421              : !Put xval in a buffer at its position
    3422        50648 :  depl_val(0:totsize-1)=-1
    3423         7613 :  do i2=1,n2
    3424        30338 :    do i1=1,n1
    3425              : !    ipos location of xval(i1,i2) in the array associated with record to be written
    3426        22725 :      ipos=(displace(i2)-1)*n1 + i1-1
    3427        22725 :      buf_val(ipos) = xval(i1,i2)
    3428        30300 :      depl_val(ipos) = ipos
    3429              :    end do
    3430              :  end do
    3431              : !To save time, the location describe by array map must be in increasing order
    3432           38 :  nbval=0
    3433        50648 :  do i1=0,totsize-1
    3434        50648 :    if (depl_val(i1)/=-1) then
    3435        22725 :      nbval=nbval+1
    3436        22725 :      val(nbval)=buf_val(i1)
    3437        22725 :      depl(nbval)=depl_val(i1)
    3438              :    end if
    3439              :  end do
    3440              : 
    3441              : !Build MPI datatype for view
    3442          114 :  ABI_MALLOC(length1,(nbval+2))
    3443          114 :  ABI_MALLOC(depl1,(nbval+2))
    3444           76 :  ABI_MALLOC(type1,(nbval+2))
    3445           38 :  length1(1)=1;depl1(1)=0;type1(1)=MPI_LB
    3446        22763 :  do i1=2,nbval+1
    3447        22725 :    length1(i1) = 1
    3448        22725 :    depl1(i1)= depl(i1-1)*wff%nbOct_int
    3449        22763 :    type1(i1)= MPI_INTEGER
    3450              :  end do
    3451           38 :  length1(nbval+2)=1;depl1(nbval+2)=totsize*wff%nbOct_int;type1(nbval+2)=MPI_UB
    3452           38 :  call xmpio_type_struct(nbval+2,length1,depl1,type1,filetype,ierr)
    3453           38 :  call MPI_TYPE_COMMIT(filetype,ierr)
    3454           38 :  ABI_FREE(length1)
    3455           38 :  ABI_FREE(depl1)
    3456           38 :  ABI_FREE(type1)
    3457              : 
    3458              : !Write data
    3459           38 :  call MPI_FILE_OPEN(spaceComm,wff%fname,MPI_MODE_RDWR,MPI_INFO_NULL,wfftempo,ierr)
    3460           38 :  ABI_CHECK_MPI(ierr, sjoin("MPI_FILE_OPEN:", wff%fname))
    3461           38 :  call MPI_FILE_SET_VIEW(wfftempo,wff%offwff,MPI_BYTE,filetype,"native",MPI_INFO_NULL,ierr)
    3462           38 :  call MPI_FILE_WRITE_ALL(wfftempo,val,nbval,MPI_INTEGER,statux,ierr)
    3463           38 :  call MPI_FILE_CLOSE(wfftempo,ierr)
    3464              : 
    3465              : !Update offset
    3466           38 :  wff%offwff = wff%offwff + totsize*wff%nbOct_int
    3467              : 
    3468              : !Free memory
    3469           38 :  call MPI_TYPE_FREE(filetype,ierr)
    3470           38 :  ABI_FREE(depl)
    3471           38 :  ABI_FREE(depl_val)
    3472           38 :  ABI_FREE(buf_val)
    3473           38 :  ABI_FREE(val)
    3474              : #endif
    3475              : 
    3476           38 : end subroutine xderiveWrite_int2d_displ
    3477              : !!***
    3478              : 
    3479              : !----------------------------------------------------------------------
    3480              : 
    3481              : !!****f* m_wffile/xderiveWrite_dp2d_displ
    3482              : !! NAME
    3483              : !!  xderiveWrite_dp2d_displ
    3484              : !!
    3485              : !! FUNCTION
    3486              : !!  Generic routine to read/write wf files with MPI I/O.
    3487              : !!  Target: two-dimensional double precision arrays.
    3488              : !!
    3489              : !! INPUTS
    3490              : !!  n1= first dimension of the array
    3491              : !!  n2= second dimension of the array
    3492              : !!  spaceComm= MPI communicator
    3493              : !!  xval= data buffer array
    3494              : !!  displace= number of elements for the offset
    3495              : !!
    3496              : !! OUTPUT
    3497              : !!  ierr= exit status, a non-zero value meaning there is an error
    3498              : !!
    3499              : !! SIDE EFFECTS
    3500              : !!  wff= structured info for reading/writing the wavefunctions
    3501              : !!
    3502              : !! SOURCE
    3503              : 
    3504            0 : subroutine xderiveWrite_dp2d_displ(wff,xval,n1,n2,spaceComm,displace,ierr)
    3505              : 
    3506              : !Arguments ------------------------------------
    3507              :  integer,intent(in) :: n1,n2,spaceComm
    3508              :  integer,intent(out) :: ierr
    3509              :  integer,intent(in):: displace(:)
    3510              :  real(dp),intent(in) :: xval(:,:)
    3511              :  type(wffile_type),intent(inout) :: wff
    3512              : 
    3513              : !Local variables-------------------------------
    3514              : #if defined HAVE_MPI_IO
    3515              : !scalars
    3516              :  integer :: filetype,i1,i2,ipos,nb,nbval,totsize,wfftempo
    3517              : !arrays
    3518              :  integer :: statux(MPI_STATUS_SIZE)
    3519            0 :  integer, allocatable :: length1(:),type1(:)
    3520            0 :  integer(kind=XMPI_ADDRESS_KIND),allocatable :: depl(:),depl1(:),depl_val(:)
    3521            0 :  real(dp),allocatable :: buf_val(:),val(:)
    3522              : #endif
    3523              : 
    3524              : ! *********************************************************************
    3525              : 
    3526              :  ierr=0
    3527              :  if(.false.)write(std_out,*)wff%me,xval,n1,n2,spaceComm,displace
    3528              : 
    3529              : #if defined HAVE_MPI_IO
    3530            0 :  nb = n1*n2
    3531            0 :  call xmpi_sum(nb,totsize,spaceComm,ierr)
    3532            0 :  ABI_MALLOC(depl_val,(0:totsize-1))
    3533            0 :  ABI_MALLOC(depl,(nb))
    3534            0 :  ABI_MALLOC(buf_val,(0:totsize-1))
    3535            0 :  ABI_MALLOC(val,(nb))
    3536              : 
    3537              : !Map displacements
    3538              : !Put xval in a buffer at its position
    3539            0 :  depl_val(0:totsize-1)=-1
    3540            0 :  do i2=1,n2
    3541            0 :    do i1=1,n1
    3542              : !    ipos location of xval(i1,i2) in the array associated with record to be written
    3543            0 :      ipos=(displace(i2)-1)*n1 + i1-1
    3544            0 :      buf_val(ipos) = xval(i1,i2)
    3545            0 :      depl_val(ipos) = ipos
    3546              :    end do
    3547              :  end do
    3548              : !To save time, the location describe by array map must be in increasing order
    3549            0 :  nbval=0
    3550            0 :  do i1=0,totsize-1
    3551            0 :    if (depl_val(i1)/=-1) then
    3552            0 :      nbval=nbval+1
    3553            0 :      val(nbval)=buf_val(i1)
    3554            0 :      depl(nbval)=depl_val(i1)
    3555              :    end if
    3556              :  end do
    3557              : 
    3558              : !Build MPI datatype for view
    3559            0 :  ABI_MALLOC(length1,(nbval+2))
    3560            0 :  ABI_MALLOC(depl1,(nbval+2))
    3561            0 :  ABI_MALLOC(type1,(nbval+2))
    3562            0 :  length1(1)=1;depl1(1)=0;type1(1)=MPI_LB
    3563            0 :  do i1=2,nbval+1
    3564            0 :    length1(i1) = 1
    3565            0 :    depl1(i1)= depl(i1-1)*wff%nbOct_dp
    3566            0 :    type1(i1)= MPI_DOUBLE_PRECISION
    3567              :  end do
    3568            0 :  length1(nbval+2)=1;depl1(nbval+2)=totsize*wff%nbOct_dp;type1(nbval+2)=MPI_UB
    3569            0 :  call xmpio_type_struct(nbval+2,length1,depl1,type1,filetype,ierr)
    3570            0 :  call MPI_TYPE_COMMIT(filetype,ierr)
    3571            0 :  ABI_FREE(length1)
    3572            0 :  ABI_FREE(depl1)
    3573            0 :  ABI_FREE(type1)
    3574              : 
    3575              : !Write data
    3576            0 :  call MPI_FILE_OPEN(spaceComm,wff%fname,MPI_MODE_RDWR,MPI_INFO_NULL,wfftempo,ierr)
    3577            0 :  ABI_CHECK_MPI(ierr, sjoin("MPI_FILE_OPEN:", wff%fname))
    3578            0 :  call MPI_FILE_SET_VIEW(wfftempo,wff%offwff,MPI_BYTE,filetype,"native",MPI_INFO_NULL,ierr)
    3579            0 :  call MPI_FILE_WRITE_ALL(wfftempo,val,nbval,MPI_DOUBLE_PRECISION,statux,ierr)
    3580            0 :  call MPI_FILE_CLOSE(wfftempo,ierr)
    3581              : 
    3582            0 :  wff%offwff = wff%offwff + totsize*wff%nbOct_dp
    3583              : 
    3584              : !Free memory
    3585            0 :  call MPI_TYPE_FREE(filetype,ierr)
    3586            0 :  ABI_FREE(depl)
    3587            0 :  ABI_FREE(depl_val)
    3588            0 :  ABI_FREE(buf_val)
    3589            0 :  ABI_FREE(val)
    3590              : #endif
    3591              : 
    3592            0 : end subroutine xderiveWrite_dp2d_displ
    3593              : !!***
    3594              : 
    3595              : !----------------------------------------------------------------------
    3596              : 
    3597              : 
    3598              : !!****f* m_wffile/xderiveWrite_char
    3599              : !! NAME
    3600              : !!  xderiveWrite_char
    3601              : !!
    3602              : !! FUNCTION
    3603              : !!  Generic routine to read/write wf files with MPI I/O.
    3604              : !!  Target: character string.
    3605              : !!
    3606              : !! INPUTS
    3607              : !!  xval= data buffer array
    3608              : !!  n= number of elements in the string
    3609              : !!
    3610              : !! OUTPUT
    3611              : !!  ierr= exit status, a non-zero value meaning there is an error
    3612              : !!
    3613              : !! SIDE EFFECTS
    3614              : !!  wff= structured info for reading/writing the wavefunctions
    3615              : !!
    3616              : !! SOURCE
    3617              : 
    3618            0 : subroutine xderiveWrite_char(wff,xval,n,ierr)
    3619              : 
    3620              : !Arguments ------------------------------------
    3621              :  type(wffile_type),intent(inout) :: wff
    3622              :  integer,intent(in) :: n
    3623              :  integer,intent(out) :: ierr
    3624              :  character(len=*),intent(in),target :: xval
    3625              : 
    3626              : !Local variables-------------------------------
    3627              : #if defined HAVE_MPI_IO
    3628              :  integer :: statux(MPI_STATUS_SIZE)
    3629              :  character,pointer :: buf(:)
    3630              :  type(c_ptr) :: cptr
    3631              : #endif
    3632              : ! *********************************************************************
    3633              : 
    3634            0 :  ierr=0
    3635              :  if(.false.)write(std_out,*)wff%me,xval,n
    3636              : 
    3637              : #if defined HAVE_MPI_IO
    3638            0 :    cptr=c_loc(xval) ; call c_f_pointer(cptr,buf,[n])
    3639            0 :  call MPI_FILE_WRITE_AT(wff%fhwff,wff%offwff,buf,n,MPI_CHARACTER,statux,ierr)
    3640            0 :  wff%offwff = wff%offwff + wff%nbOct_ch * n
    3641              : #endif
    3642              : 
    3643            0 : end subroutine xderiveWrite_char
    3644              : !!***
    3645              : 
    3646              : !!****f* m_wffile/xdefineOff
    3647              : !! NAME
    3648              : !!  xdefineOff
    3649              : !!
    3650              : !! FUNCTION
    3651              : !!  In case of MPI I/O, defines the offset for each processor
    3652              : !!
    3653              : !! INPUTS
    3654              : !!  formeig option (format of the eigenvalues and occupations) :
    3655              : !!   0 => ground-state format (initialisation of eigenvectors with
    3656              : !!        random numbers, vector of eigenvalues, occupations are present)
    3657              : !!   1 => respfn format (initialisation of eigenvectors with 0 s,
    3658              : !!        hermitian matrix of eigenvalues)
    3659              : !!  nkpt = number of k points
    3660              : !!  nspinor = total number of spinorial components of the wavefunctions
    3661              : !!  nsppol = number of channels for spin-polarization (1 or 2)
    3662              : !!  nband(nkpt*nsppol) = number of bands at each k point, for each polarization
    3663              : !!  npwarr(nkpt) = number of planewaves at each k point
    3664              : !!  mpi_enreg <type(MPI_type)> = information about MPI parallelization
    3665              : !!
    3666              : !! OUTPUT
    3667              : !!  (no output)
    3668              : !!
    3669              : !! SIDE EFFECTS
    3670              : !!  wff <type(wffile_type)> =
    3671              : !!
    3672              : !! SOURCE
    3673              : 
    3674            0 : subroutine xdefineOff(formeig,wff,mpi_enreg,nband,npwarr,nspinor,nsppol,nkpt)
    3675              : 
    3676              : !Arguments ------------------------------------
    3677              :  integer, intent(in) ::  nsppol,nkpt,nspinor,formeig
    3678              :  integer, intent(in) ::  nband(nkpt*nsppol),npwarr(nkpt)
    3679              :  type(wffile_type),intent(inout) :: wff
    3680              :  type(MPI_type),intent(in) :: mpi_enreg
    3681              : 
    3682              : !Local variables-------------------------------
    3683              : #if defined HAVE_MPI_IO
    3684              : !scalars
    3685              :  integer :: comm,iproc
    3686              :  integer :: nband_k,npw_k,nproc,me,ipp
    3687              :  integer :: nbrec,isppol,ikpt,nbint,nbreal,nbd,ippband
    3688              :  integer :: nrecnpw,nreckg
    3689              :  integer(kind=XMPI_OFFSET_KIND) :: pos_start
    3690              : !arrays
    3691            0 :  integer(kind=XMPI_OFFSET_KIND),allocatable  :: offproc(:)
    3692              : #endif
    3693              : 
    3694              : ! *************************************************************************
    3695              : !nbOct_int octet number of int value
    3696              : !nbOct_dp octet number of dp value
    3697              : !nbOct_ch octet number of character value
    3698              : !lght_recs length of record
    3699              : 
    3700              :  if(.false.)write(std_out,*)wff%me,mpi_enreg%nproc,formeig,nband,npwarr,nspinor,nkpt
    3701              : #if defined HAVE_MPI_IO
    3702            0 :  if(wff%iomode==IO_MODE_MPI)then
    3703              : 
    3704            0 :    comm=mpi_enreg%comm_cell
    3705            0 :    me=xmpi_comm_rank(comm)
    3706            0 :    nproc=xmpi_comm_size(comm)
    3707            0 :    pos_start=wff%offwff
    3708              : 
    3709            0 :    ABI_MALLOC(offproc,(0:nproc))
    3710            0 :    offproc = 0
    3711              :    nbrec =2
    3712              :    nrecnpw=3+nbrec
    3713              : 
    3714            0 :    do isppol=1,nsppol
    3715            0 :      do ikpt=1,nkpt
    3716            0 :        nband_k=nband(ikpt+(isppol-1)*nkpt)
    3717            0 :        npw_k=npwarr(ikpt)
    3718            0 :        iproc=mpi_enreg%proc_distrb(ikpt,1,isppol)
    3719              :        if (mpi_enreg%paralbd==1) iproc=mpi_enreg%proc_distrb(ikpt,1,isppol)
    3720              : !      record kg
    3721            0 :        nreckg=nbrec+ wff%kgwff*3*npw_k
    3722              : 
    3723              : !      Record npw,nspinor,nband, Record kg
    3724            0 :        offproc(iproc) = offproc(iproc) + wff%nbOct_int*(nrecnpw+nreckg)
    3725              : 
    3726            0 :        if (formeig == 0) then
    3727              : !        Records eigen,occ
    3728            0 :          nbint=nbrec
    3729            0 :          nbreal =  2 *nband_k
    3730            0 :          offproc(iproc) = offproc(iproc) + (wff%nbOct_int*nbint+wff%nbOct_dp*nbreal)
    3731              : 
    3732              : !        Records cg
    3733              :          offproc(iproc) = offproc(iproc) &
    3734            0 : &         + (wff%nbOct_int*nbrec+wff%nbOct_dp*2*npw_k*nspinor)*nband_k
    3735              : 
    3736            0 :          ippband=iproc
    3737            0 :          do nbd=1,nband_k
    3738            0 :            ipp=mpi_enreg%proc_distrb(ikpt,nbd,isppol)
    3739            0 :            if (ipp /= ippband ) then
    3740            0 :              ippband=ipp
    3741            0 :              offproc(ippband)=offproc(ippband)+ wff%nbOct_int*(nrecnpw+nreckg)
    3742              :              offproc(ippband) = offproc(ippband) + (wff%nbOct_int*nbint &
    3743            0 : &             +wff%nbOct_dp*nbreal)
    3744              :              offproc(ippband) = offproc(ippband) + (wff%nbOct_int*nbrec &
    3745            0 : &             + wff%nbOct_dp*2*npw_k*nspinor)*nband_k
    3746              :            end if
    3747              :          end do
    3748            0 :        else if (formeig == 1) then
    3749              : !        record eigen
    3750              :          offproc(iproc) = offproc(iproc) + (wff%nbOct_int*2*nbrec  &
    3751              : &         + wff%nbOct_dp*2*npw_k*nspinor &
    3752            0 : &         + wff%nbOct_dp*2*nband_k)*nband_k
    3753            0 :          ippband=iproc
    3754            0 :          do nbd=1,nband_k
    3755            0 :            ipp=mpi_enreg%proc_distrb(ikpt,nbd,isppol)
    3756            0 :            if (ipp /= ippband) then
    3757            0 :              ippband=ipp
    3758            0 :              offproc(ippband)=offproc(ippband)+ wff%nbOct_int*(nrecnpw+nreckg)
    3759              :              offproc(ippband) = offproc(ippband) + (wff%nbOct_int*2*nbrec  &
    3760              : &             + wff%nbOct_dp*2*npw_k*nspinor &
    3761            0 : &             + wff%nbOct_dp*2*nband_k)*nband_k
    3762              :            end if
    3763              :          end do
    3764              :        end if   ! formeig
    3765              :      end do ! ikpt
    3766              : 
    3767              :    end do ! isppol
    3768              : 
    3769              : !  pos_start=wff%offwff
    3770              : !  wff%offwff = pos_start
    3771              : 
    3772            0 :    if (me/=0)then
    3773            0 :      do iproc=0,me-1
    3774            0 :        wff%offwff=wff%offwff+offproc(iproc)
    3775              :      end do
    3776              :    end if
    3777            0 :    ABI_FREE(offproc)
    3778              : 
    3779              :  end if ! iomode
    3780              : #endif
    3781              : 
    3782            0 : end subroutine xdefineOff
    3783              : !!***
    3784              : 
    3785            0 : END MODULE m_wffile
    3786              : !!***
        

Generated by: LCOV version 2.3-1