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?
In C, the
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:
A similar question occurred previously at the Intel Fortran forum:
Searching for “aliasing” in the Intel Fortran compiler documentation, does give some suggestions:
- Using Automatic Vectorization
- Enabling Further Loop Parallelization for Multicore Platforms
assume (compiler flag
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
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).