Fortran pointers, and aliasing

In C, the restrict keyword allows a programmer to make a promise to the compiler, saying approximately “I promise that this pointer doesn’t overlap with memory referred to by other pointers that are passed to this function”. That’s the default state in Fortran, for assumed-shape arrays, for example. But what bout when actually using pointers in Fortran? If the programmer knows that there is no aliasing, is there a way to communicate that to the compiler? Or is it unnecessary, since only targets could possibly alias, so if you pass a pointer to a function that has no target dummy arguments, there’s no chance of aliasing?

2 Likes

I don’t know the answer for aliasing between variables.

But when using pointers or assumed-shape arrays it can be handy to use the attribute contiguous which makes it easier for the compiler to enable certain optimizations:

See also:

2 Likes

A similar question occurred previously at the Intel Fortran forum:

Searching for “aliasing” in the Intel Fortran compiler documentation, does give some suggestions:

If I understood your question accurately enough, a minimum working example would be something like this:

program pointer_alias
implicit none

real, target :: a(10)
real, pointer :: b(:) => null(), c(:) => null()

a = [1,2,3,4,5,6,7,8,9,10]

b(1:5) => a(1:5)
c(1:5) => a(5:9) 

! b and c both alias element a(5), potential flow dependency
call add_in_place(b,c)
print *, b

a = [1,2,3,4,5,6,7,8,9,10]
b(1:5) => a(1:5)
c(1:5) => a(6:10) 
call add_in_place_v2(b,c)
print *, b

contains

! unsafe if executed in parallel due to write/read order of array b
subroutine add_in_place(b,c)
real, intent(inout) :: b(:)
real, intent(in) :: c(size(b))
!$omp parallel workshare
b = b + c  
!$omp end parallel workshare
end subroutine

! "restrict" version, use of do concurrent implies no data dependencies
! between elements of b and c
subroutine add_in_place_v2(b,c)
real, intent(inout) :: b(:)
real, intent(in) :: c(size(b))
integer :: i
do concurrent (i=1:size(b))
b(i) = b(i) + c(i)
end do
end subroutine

end program
1 Like

Thanks @ivanpribec for helping to look into this. It’s ironic that this question arises at all, since restrict was introduced into C in order to enable optimizations that fortran compilers could already make! But it sounds like at the end of the day, while the compiler can work out some cases of possible aliasing and prove that there is none, that’s not the case always, and there’s no in-standard way to tell the compiler to make that assumption (other than to avoid the use of pointers).