Test contiguous pointers

Registered by Nick Papior on 2016-04-19

Currently all array assignments using pointers will create a temporary array to ensure contiguous memory.
However, in nearly all cases are the used pointer arrays of contiguous layout and one may reduce the creation of temporary arrays by using this keyword.

I have tested adding contiguous at a relatively large set of arrays. But for a tiny system (4 atoms), it seems not important for such a small system.
I suspect it may have influence on a larger system.

Blueprint information

Status:
Complete
Approver:
None
Priority:
Undefined
Drafter:
Nick Papior
Direction:
Needs approval
Assignee:
Nick Papior
Definition:
Obsolete
Series goal:
None
Implementation:
Blocked
Milestone target:
None
Started by
Nick Papior on 2016-10-04
Completed by
Nick Papior on 2016-10-04

Related branches

Sprints

Whiteboard

Hi Nick,

The 'contiguous' keyword appears in F2008, and its implementation is still subject to interpretation.
Here is a test file to explore things.

! Simple tests for "array temporaries" and the influence of:
!
! - the use of the "contiguous" keyword
! - the use of pointers instead of allocatable arrays or simple arrays
!
! Results:
!
! gfortran 5.2 (checks at compile time with -Warray-temporaries)
! (disable the call to is_contiguous, as it is not implemented...)
!
! The contiguous keyword has no effect.
! The use of pointers forces temporaries
! Non-contiguous sections are correctly flagged.
!
! intel 15.0.3 (checks at runtime). Use -check all -traceback
!
! The contiguous keyword is taken at face value, even if the
! case is obviously not contiguous, and no temporaries are produced.
! NOTE: According to Steve Lionel from Intel, this might have changed in recent
! versions
! (https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/508693#)
!
! On the other hand, the vanilla version of the routine correctly
! detects non-contiguous and contiguous cases (!!)

module m_interface
  CONTAINS
        SUBROUTINE MPI_BCAST( &
     & BUFFER, COUNT, DATATYPE, ROOT, COMM, IERROR)
          real, INTENT(INOUT) :: BUFFER(*)
          INTEGER, INTENT(IN) :: COUNT
          INTEGER, INTENT(IN) :: DATATYPE
          INTEGER, INTENT(IN) :: ROOT
          INTEGER, INTENT(IN) :: COMM
          INTEGER, INTENT(OUT) :: IERROR
          EXTERNAL MPI_BCAST_EXT
! CALL MPI_BCAST_EXT( &
! & BUFFER, COUNT, DATATYPE, ROOT, COMM, IERROR)
        END SUBROUTINE MPI_BCAST

              SUBROUTINE MPI_BCAST_CONT( &
     & BUFFER, COUNT, DATATYPE, ROOT, COMM, IERROR)
          real, INTENT(INOUT), contiguous :: BUFFER(:)
          INTEGER, INTENT(IN) :: COUNT
          INTEGER, INTENT(IN) :: DATATYPE
          INTEGER, INTENT(IN) :: ROOT
          INTEGER, INTENT(IN) :: COMM
          INTEGER, INTENT(OUT) :: IERROR
          EXTERNAL MPI_BCAST_EXT
          print *, is_contiguous(buffer)
! CALL MPI_BCAST_EXT( &
! & BUFFER, COUNT, DATATYPE, ROOT, COMM, IERROR)
        END SUBROUTINE MPI_BCAST_CONT
end module m_interface
!
program tt
  use m_interface

  integer, parameter :: n = 20
    real, dimension(n) :: a
    real, pointer :: b(:)

    real, dimension(n,n) :: c
    real, allocatable :: d(:)
    real, dimension(:,:), allocatable :: e

    integer :: root, comm, ierror, count, datatype

    allocate(b(n))
    allocate(d(n))
    allocate(e(n,n))

  root = 0
  datatype = 34
  comm = 333

  call mpi_bcast(a,n,datatype,root,comm,ierr)
  call mpi_bcast(b,n,datatype,root,comm,ierr)
  call mpi_bcast(c(2,:),n,datatype,root,comm,ierr) ! Not contiguous
  call mpi_bcast(c(:,2),n,datatype,root,comm,ierr)
  call mpi_bcast(d,n,datatype,root,comm,ierr)
  call mpi_bcast(e(2,:),n,datatype,root,comm,ierr) ! Not contiguous
  call mpi_bcast(e(:,2),n,datatype,root,comm,ierr)

  call mpi_bcast_cont(a,n,datatype,root,comm,ierr)
  call mpi_bcast_cont(b,n,datatype,root,comm,ierr)
  call mpi_bcast_cont(c(2,:),n,datatype,root,comm,ierr) ! Not contiguous
  call mpi_bcast_cont(c(:,2),n,datatype,root,comm,ierr)
  call mpi_bcast_cont(d,n,datatype,root,comm,ierr)
  call mpi_bcast_cont(e(2,:),n,datatype,root,comm,ierr) ! Not contiguous
  call mpi_bcast_cont(e(:,2),n,datatype,root,comm,ierr)

end program tt

(?)

Work Items

This blueprint contains Public information 
Everyone can see this information.