Skip to content

Module variable aliasing

Suppose you have two (or more) modules, in which you have variables that have a similar name and that should be used on the device, should these two variable point to the same memory location?

module one
  integer :: a(:)
  !$acc declare create(a)
end module
module two
  integer :: a(:)
  !$acc declare create(a)
end module
To test this we have written the following program, which does a simple reduction for both variables.

module mod1
    implicit none
    private
    integer, parameter :: n = 1000
    integer, allocatable, dimension(:) :: buffer
    !$acc declare create(buffer)

    public :: init1, sum1

    contains

    subroutine init1(val)
        integer, intent(in) :: val
        allocate(buffer(n))
        buffer = val
        !$acc update device(buffer)
    end subroutine init1

    subroutine sum1(val)
        integer, intent(out) :: val
        integer :: i

        val = 0
        !$acc parallel loop reduction(+:val)
        do i=1,n
            val = val + buffer(i)
        end do
    end subroutine sum1

end module mod1

module mod2
    implicit none
    private
    integer, parameter :: n = 1000
    integer, allocatable, dimension(:) :: buffer
    !$acc declare create(buffer)

    public :: init2, sum2

    contains

    subroutine init2(val)
        integer, intent(in) :: val
        allocate(buffer(n))
        buffer = val
        !$acc update device(buffer)
    end subroutine init2

    subroutine sum2(val)
        integer, intent(out) :: val
        integer :: i

        val = 0
        !$acc parallel loop reduction(+:val)
        do i=1,n
            val = val + buffer(i)
        end do
    end subroutine sum2

end module mod2

program aliasing
    use mod1
    use mod2
    implicit none
    integer :: val1, val2

    call init1(1)
    call init2(2)
    call sum1(val1)
    call sum2(val2)

    if (val1 == 1000 .and. val2 == 2000) then
      write(*,*) "Success, no aliasing"
    else
      write(*,*) "Fail, val1 and val2 are aliased:", val1, val2
    endif
end program aliasing

The OpenACC specification is ambiguous on this and states in section 2.13 (OpenACC 3.3):

OpenACC 3.3, section 2.13

The associated region is the implicit region associated with the function, subroutine, or program in which the directive appears. If the directive appears in the declaration section of a Fortran module subprogram, for a Fortran common block, or in a C or C++ global or namespace scope, the associated region is the implicit region for the whole program

Compiler behaviour

Cray compiler

According to HPE (Cray compiler) it is allowed according the specification to let these variables point to the same location in device memory. Therefore our example program does not succeed

Nvidia

Nvidia treats these variables as separate in device memory. Therefore our example program succeeds.