Parallel IO

The example demonstrates writes using individual and shared file pointers and explicit offsets.

The source code is shown below:

!******************************************************************************
!    Parallel I/O example:
!
!    This example uses some of the file access routines. A file is created and
!    different file write mehtods are used, one using explicit offsets, one
!    using the shared file pointer, and one using individual file pointers for
!    each process. After each write has been performed the file content is read
!    and dumped to stdout.
!
!    More specifically:
!   --------------------------------
!      - A file is created and opened for both reading and writing.
!      - The file view is set to MPI_INT for all processes.
!      - Set the file's size so that it has room for one MPI_INT per process.
!      - Write to the file using explicit offsets.
!      - Write to the file using the shared file pointer.
!      - Write to the file using individual file pointers.
!      - Close the file and exit.
!   --------------------------------
!
!    Copyright 2003 (c) Critical Software SA
!    . http://www.criticalsoftware.com
!    . http://www.criticalsoftware.com/hpc
!    . csWMPI II@criticalsoftware.com
!
!******************************************************************************

      include "mpi_init.f"
      
!------------------------------------------------------------------------------

!******************************************************************************
!    This function dumps the content of the file using the process' individual
!    file pointer.
!******************************************************************************
      subroutine DumpFileContent(mf_file,n_comm_size,n_comm_rank)
      implicit none
      include 'mpif.h'
      integer mf_file, n_comm_size, n_comm_rank, ierr
      integer  nCounter, nFileData

      call MPI_FILE_SEEK(mf_file, 0, MPI_SEEK_SET, ierr)
      print *,'  - File content: '
      do nCounter = 0,n_comm_size-1
            call MPI_FILE_READ(mf_file, nFileData, 1, MPI_INTEGER,
     +                  MPI_STATUS_IGNORE, ierr)
        print *,' (',nFileData,')'
      end do
      print *,''
      end !subroutine DumpFileContent

!******************************************************************************
!    This function computes an interval for a single process.
!******************************************************************************
      program main
      implicit none
      include 'mpif.h'
      integer nCommSize, nCommRank, ierr

!     The filename to use for the shared file
!     Rank of the process to act as file server
      character*(*) FILENAME,SERVERRANK
      parameter (FILENAME='sharedfile.mpi',SERVERRANK='0')

      integer miInfo,mfFile

!     Initialize csWMPI II II:
      call MPI_INIT(ierr)

!     Determine what the world looks like and our own position in it:
      call MPI_COMM_SIZE(MPI_COMM_WORLD, nCommSize, ierr)
      call MPI_COMM_RANK(MPI_COMM_WORLD, nCommRank, ierr)
      print *,'I am rank',nCommRank,' of ',nCommSize,
     +         ' in MPI_COMM_WORLD'

!     Create an instance of MPI_Info and set the server_rank key,
!     specifying which rank should act as the file server, to SERVER_RANK:
      call MPI_INFO_CREATE(miInfo,ierr)

      call MPI_INFO_SET(miInfo, 'server_rank', SERVERRANK, ierr)

!     Try creating a file (and open it in read/write mode)
      print *,'Opening file: ',FILENAME,' (server_rank=',
     +         SERVERRANK,')..'

      call MPI_FILE_OPEN(MPI_COMM_WORLD,FILENAME,
     +                MPI_MODE_RDWR + MPI_MODE_CREATE,
     +                miInfo, mfFile, ierr)
      print *,'OK!'
      print *,''
      print *,''


!     Free the info object:
      call MPI_INFO_FREE(miInfo, ierr)

!     Set the file view (all use the displacement 0, elementary datatype
!     and filetype MPI_INT). The data representation is set to "native".
!     Hence, we have a file of MPI_INTs viewed identically by all
!     processes:
      call MPI_FILE_SET_VIEW(mfFile, 0, MPI_INTEGER, MPI_INTEGER,
     +                        'native', MPI_INFO_NULL, ierr)


!     Make room in the file for one MPI_INT per process
      call MPI_FILE_SET_SIZE(mfFile, nCommSize, ierr)

!     Use explicit offsets (offset equal to rank) to write one MPI_INT to
!     the file. The result should be a file containing integers ascending
!     from 0 to the size of MPI_COMM_WORLD - 1.
      print *,'Write to file using explicit offsets..........'
      call MPI_FILE_WRITE_AT(mfFile,nCommRank,nCommRank,
     +                        1,MPI_INTEGER, MPI_STATUS_IGNORE, ierr)
      print *,'OK!'
      print *,''

      call MPI_BARRIER(MPI_COMM_WORLD, ierr)
      call DumpFileContent (mfFile, nCommSize, nCommRank)
      call MPI_BARRIER (MPI_COMM_WORLD, ierr)

!     Use a shared file pointer to write to the file. Since there is no
!     synchronization between the processes, the result is
!     non-deterministic, however the file should contain one MPI_INT for
!     every process in MPI_COMM_WORLD.
      print *,'Write to file using the shared file pointer...'
      call MPI_FILE_WRITE_SHARED(mfFile, nCommRank, 1, MPI_INTEGER,
     +                           MPI_STATUS_IGNORE, ierr)
      print *,'OK'
      print *,''
      call MPI_BARRIER(MPI_COMM_WORLD, ierr)
      call DumpFileContent (mfFile, nCommSize, nCommRank)
      call MPI_BARRIER(MPI_COMM_WORLD, ierr)

!     Use individual file pointers to write to the file. First a seek is
!     performed to from the _end_ of the file. Hence the should be a file
!     containing integers descending from size of MPI_COMM_WORLD - 1 to 0.
      print *,'Write to file using individual file pointers..'
      call MPI_FILE_SEEK(mfFile, -(nCommRank+1), MPI_SEEK_END, ierr)

      call MPI_FILE_WRITE(mfFile, nCommRank, 1, MPI_INTEGER,
     +                    MPI_STATUS_IGNORE, ierr)
      print *,'OK!'
      print *,''

      call MPI_BARRIER(MPI_COMM_WORLD, ierr)
      call DumpFileContent (mfFile, nCommSize, nCommRank)
      call MPI_BARRIER(MPI_COMM_WORLD, ierr)

!     Close the file and finalize MPI:
      call MPI_FILE_CLOSE(mfFile, ierr)
      call MPI_FINALIZE(ierr)

!     Pause rank 0 so that the output can be verified:
      if (nCommRank == 0) then
        pause 'Press ENTER to exit...'
      end if

      stop
      end



© 2009 Critical Software SA. All trademarks and copyrights on this page are owned by their respective owners.
csWMPI II II™, csWMPI II™ and PatentMPI™ are trademarks of Critical Software SA. All Rights Reserved.