Blame test/mpi/f08/io/miscfilef90.f90

Packit Service c5cf8c
! -*- Mode: Fortran; -*-
Packit Service c5cf8c
!
Packit Service c5cf8c
!  (C) 2008 by Argonne National Laboratory.
Packit Service c5cf8c
!      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
!
Packit Service c5cf8c
      program main
Packit Service c5cf8c
      use mpi_f08
Packit Service c5cf8c
! iooffset.h provides a variable "offset" that is of type MPI_Offset
Packit Service c5cf8c
! (in Fortran 90, kind=MPI_OFFSET_KIND)
Packit Service c5cf8c
      integer (kind=MPI_OFFSET_KIND) offset
Packit Service c5cf8c
Packit Service c5cf8c
! iodisp.h declares disp as an MPI_Offset integer
Packit Service c5cf8c
      integer (kind=MPI_OFFSET_KIND) disp
Packit Service c5cf8c
Packit Service c5cf8c
      integer rank, size
Packit Service c5cf8c
      type(MPI_File) fh
Packit Service c5cf8c
      type(MPI_Group) group, worldgroup
Packit Service c5cf8c
      integer i, result
Packit Service c5cf8c
Packit Service c5cf8c
      integer ierr, errs
Packit Service c5cf8c
      integer BUFSIZE
Packit Service c5cf8c
      parameter (BUFSIZE=1024)
Packit Service c5cf8c
      integer buf(BUFSIZE)
Packit Service c5cf8c
      character*(50) filename
Packit Service c5cf8c
      character*(MPI_MAX_DATAREP_STRING) datarep
Packit Service c5cf8c
      integer amode
Packit Service c5cf8c
      logical atomicity
Packit Service c5cf8c
      type(MPI_Datatype) newtype, etype, filetype
Packit Service c5cf8c
      integer integer_size, type_size
Packit Service c5cf8c
!
Packit Service c5cf8c
      errs = 0
Packit Service c5cf8c
      call mtest_init( ierr )
Packit Service c5cf8c
      call mpi_comm_rank( MPI_COMM_WORLD, rank, ierr )
Packit Service c5cf8c
      call mpi_comm_size( MPI_COMM_WORLD, size, ierr )
Packit Service c5cf8c
!
Packit Service c5cf8c
! Create a file that we'll then query properties
Packit Service c5cf8c
      filename = "testfile.txt"
Packit Service c5cf8c
      call mpi_file_open( MPI_COMM_WORLD, filename, MPI_MODE_CREATE +       &
Packit Service c5cf8c
      &     MPI_MODE_RDWR, MPI_INFO_NULL, fh, ierr )
Packit Service c5cf8c
      if (ierr .ne. MPI_SUCCESS) then
Packit Service c5cf8c
         print *, "Unable to create file ", filename
Packit Service c5cf8c
         call mpi_abort( MPI_COMM_WORLD, 1, ierr )
Packit Service c5cf8c
      endif
Packit Service c5cf8c
!
Packit Service c5cf8c
! Fill in some data
Packit Service c5cf8c
      do i=1, BUFSIZE
Packit Service c5cf8c
         buf(i) = i
Packit Service c5cf8c
      enddo
Packit Service c5cf8c
      call mpi_file_write( fh, buf, BUFSIZE, MPI_INTEGER,                &
Packit Service c5cf8c
      &     MPI_STATUS_IGNORE, ierr )
Packit Service c5cf8c
      call MPI_File_sync( fh, ierr )
Packit Service c5cf8c
!
Packit Service c5cf8c
! Now, query properties of the file and the file handle
Packit Service c5cf8c
      call MPI_File_get_amode(fh, amode, ierr )
Packit Service c5cf8c
      if (amode .ne. MPI_MODE_CREATE + MPI_MODE_RDWR) then
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
         print *, " Amode was different than expected"
Packit Service c5cf8c
      endif
Packit Service c5cf8c
!
Packit Service c5cf8c
      call MPI_File_get_atomicity( fh, atomicity, ierr )
Packit Service c5cf8c
      if (atomicity) then
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
         print *, " Atomicity was true but should be false"
Packit Service c5cf8c
      endif
Packit Service c5cf8c
!
Packit Service c5cf8c
      call MPI_File_set_atomicity( fh, .true., ierr )
Packit Service c5cf8c
      call MPI_File_get_atomicity( fh, atomicity, ierr )
Packit Service c5cf8c
      if (.not. atomicity) then
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
         print *, " Atomicity was set to true but ",                    &
Packit Service c5cf8c
      &        "get_atomicity returned false"
Packit Service c5cf8c
      endif
Packit Service c5cf8c
      call MPI_File_set_atomicity( fh, .false., ierr )
Packit Service c5cf8c
!
Packit Service c5cf8c
! FIXME: original code use 10,10,20, and the following code
Packit Service c5cf8c
! assumed the original
Packit Service c5cf8c
!
Packit Service c5cf8c
! Create a vector type of 10 elements, each of 20 elements, with a stride of
Packit Service c5cf8c
! 30 elements
Packit Service c5cf8c
      call mpi_type_vector( 10, 20, 30, MPI_INTEGER, newtype, ierr )
Packit Service c5cf8c
      call mpi_type_commit( newtype, ierr )
Packit Service c5cf8c
!
Packit Service c5cf8c
! All processes are getting the same view, with a 1000 byte offset
Packit Service c5cf8c
      offset = 1000
Packit Service c5cf8c
      call mpi_file_set_view( fh, offset, MPI_INTEGER, newtype, "native"  &
Packit Service c5cf8c
      &     , MPI_INFO_NULL, ierr )
Packit Service c5cf8c
Packit Service c5cf8c
      call mpi_file_get_view( fh, offset, etype, filetype, datarep, ierr  &
Packit Service c5cf8c
      &     )
Packit Service c5cf8c
      if (offset .ne. 1000) then
Packit Service c5cf8c
         print *, " displacement was ", offset, ", expected 1000"
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
      endif
Packit Service c5cf8c
      if (datarep .ne. "native") then
Packit Service c5cf8c
         print *, " data representation form was ", datarep,              &
Packit Service c5cf8c
      &        ", expected native"
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
      endif
Packit Service c5cf8c
Packit Service c5cf8c
! Find the byte offset, given an offset of 20 etypes relative to the
Packit Service c5cf8c
! current view (the same as the blockcount of the filetype, which
Packit Service c5cf8c
! places it at the beginning of the next block, hence a stride
Packit Service c5cf8c
! distance away).
Packit Service c5cf8c
      offset = 20
Packit Service c5cf8c
      call mpi_file_get_byte_offset( fh, offset, disp, ierr )
Packit Service c5cf8c
      call mpi_type_size( MPI_INTEGER, integer_size, ierr )
Packit Service c5cf8c
      if (disp .ne. 1000 + 30 * integer_size) then
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
         print *, " (offset20)Byte offset = ", disp, ", should be ",         &
Packit Service c5cf8c
      &            1000+20*integer_size
Packit Service c5cf8c
      endif
Packit Service c5cf8c
!
Packit Service c5cf8c
!     We should also compare file and etypes.  We just look at the
Packit Service c5cf8c
!     sizes and extents for now
Packit Service c5cf8c
Packit Service c5cf8c
      call mpi_type_size( etype, type_size, ierr )
Packit Service c5cf8c
      if (type_size .ne. integer_size) then
Packit Service c5cf8c
         print *, " Etype has size ", type_size, ", but should be ",      &
Packit Service c5cf8c
      &        integer_size
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
      endif
Packit Service c5cf8c
      call mpi_type_size( filetype, type_size, ierr )
Packit Service c5cf8c
      if (type_size .ne. 10*20*integer_size) then
Packit Service c5cf8c
         print *, " filetype has size ", type_size, ", but should be ",   &
Packit Service c5cf8c
      &        10*20*integer_size
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
      endif
Packit Service c5cf8c
!
Packit Service c5cf8c
! Only free derived type
Packit Service c5cf8c
      call mpi_type_free( filetype, ierr )
Packit Service c5cf8c
Packit Service c5cf8c
      call mpi_file_get_group( fh, group, ierr )
Packit Service c5cf8c
      call mpi_comm_group( MPI_COMM_WORLD, worldgroup, ierr )
Packit Service c5cf8c
      call mpi_group_compare( group, worldgroup, result, ierr )
Packit Service c5cf8c
Packit Service c5cf8c
      if (result .ne. MPI_IDENT) then
Packit Service c5cf8c
         print *, " Group of file does not match group of comm_world"
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
      endif
Packit Service c5cf8c
      call mpi_group_free( group, ierr )
Packit Service c5cf8c
      call mpi_group_free( worldgroup, ierr )
Packit Service c5cf8c
Packit Service c5cf8c
      offset = 1000+25*integer_size
Packit Service c5cf8c
      call mpi_file_set_size(fh, offset, ierr )
Packit Service c5cf8c
      call mpi_barrier(MPI_COMM_WORLD, ierr )
Packit Service c5cf8c
      call mpi_file_sync(fh, ierr )
Packit Service c5cf8c
      call mpi_file_get_size( fh, offset, ierr )
Packit Service c5cf8c
Packit Service c5cf8c
      if (offset .ne. 1000+25*integer_size) then
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
         print *, " File size is ", offset, ", should be ", 1000 + 25     &
Packit Service c5cf8c
      &        * integer_size
Packit Service c5cf8c
      endif
Packit Service c5cf8c
!
Packit Service c5cf8c
! File size is 1000+25ints.  Seek to end.  Note that the file size
Packit Service c5cf8c
! places the end of the file into the gap in the view, so seeking
Packit Service c5cf8c
! to the end, which is relative to the view, needs to give the end
Packit Service c5cf8c
! of the first block of 20 ints)
Packit Service c5cf8c
      offset = 0
Packit Service c5cf8c
      call mpi_file_seek( fh, offset, MPI_SEEK_END, ierr )
Packit Service c5cf8c
      call mpi_file_get_position( fh, disp, ierr )
Packit Service c5cf8c
      if (disp .ne. 20) then
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
         print *, "File pointer position = ", disp, ", should be 20"
Packit Service c5cf8c
         if (disp .eq. 25) then
Packit Service c5cf8c
! See MPI 2.1, section 13.4, page 399, lines 7-8. The disp must be
Packit Service c5cf8c
! relative to the current view, in the etype units of the current view
Packit Service c5cf8c
             print *, " MPI implementation failed to position the "//      &
Packit Service c5cf8c
      &                "displacement within the current file view"
Packit Service c5cf8c
         endif
Packit Service c5cf8c
! Make sure we use the expected position in the next step.
Packit Service c5cf8c
         disp = 20
Packit Service c5cf8c
      endif
Packit Service c5cf8c
      call mpi_file_get_byte_offset(fh, disp, offset, ierr )
Packit Service c5cf8c
      if (offset .ne. 1000+30*integer_size) then
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
         print *, " (seek)Byte offset = ", offset, ", should be ", 1000     &
Packit Service c5cf8c
      &        +30*integer_size
Packit Service c5cf8c
      endif
Packit Service c5cf8c
Packit Service c5cf8c
      call mpi_barrier(MPI_COMM_WORLD, ierr )
Packit Service c5cf8c
Packit Service c5cf8c
      offset = -20
Packit Service c5cf8c
      call mpi_file_seek(fh, offset, MPI_SEEK_CUR, ierr )
Packit Service c5cf8c
      call mpi_file_get_position(fh, disp, ierr )
Packit Service c5cf8c
      call mpi_file_get_byte_offset(fh, disp, offset, ierr )
Packit Service c5cf8c
      if (offset .ne. 1000) then
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
         print *, " File pointer position in bytes = ", offset,           &
Packit Service c5cf8c
      &        ", should be 1000"
Packit Service c5cf8c
      endif
Packit Service c5cf8c
Packit Service c5cf8c
      offset = 8192
Packit Service c5cf8c
      call mpi_file_preallocate(fh, offset, ierr )
Packit Service c5cf8c
      offset = 0
Packit Service c5cf8c
      call mpi_file_get_size( fh, offset, ierr )
Packit Service c5cf8c
      if (offset .lt. 8192) then
Packit Service c5cf8c
         errs = errs + 1
Packit Service c5cf8c
         print *, " Size after preallocate is ", offset,                  &
Packit Service c5cf8c
      &        ", should be at least 8192"
Packit Service c5cf8c
      endif
Packit Service c5cf8c
      call mpi_file_close( fh, ierr )
Packit Service c5cf8c
Packit Service c5cf8c
      call mpi_barrier(MPI_COMM_WORLD, ierr )
Packit Service c5cf8c
Packit Service c5cf8c
      if (rank .eq. 0) then
Packit Service c5cf8c
         call MPI_File_delete(filename, MPI_INFO_NULL, ierr )
Packit Service c5cf8c
      endif
Packit Service c5cf8c
Packit Service c5cf8c
      call mpi_type_free( newtype, ierr )
Packit Service c5cf8c
Packit Service c5cf8c
      call mtest_finalize( errs )
Packit Service c5cf8c
      end