Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory location of Fortran allocatable arrays on assigment?

Suppose I have something like:

real, dimension(:), allocatable :: S
integer, dimension(:) :: idx
...
S = S(idx)

where S and idx are properly allocated/initialized before the assignment.

What does the Fortran standard(s) say, if anything, about the memory location (address) of S? Should it stay in the same place after the assigment? Is it unspecified (up to the compiler to decide)? Does it make a difference if S is not allocatable?

Full example:

$ cat test.f90 
program test
implicit none
real, dimension(:), allocatable :: S
integer :: i, idx(7) = [1,3,5,7,2,4,6]

allocate(S(size(idx)))
do i=1,size(S)
  S(i) = i*i
end do

write(6,*) S
write(6,*) loc(S)

S = S(idx)

write(6,*) S
write(6,*) loc(S)

S(:) = S(idx)

write(6,*) S
write(6,*) loc(S)

deallocate(S)

end program

$ sunf90 -V
f90: Studio 12.6 Fortran 95 8.8 Linux_i386 2017/05/30

$ sunf90 test.f90 ; ./a.out 
 1.0 4.0 9.0 16.0 25.0 36.0 49.0
 37518752
 1.0 9.0 25.0 49.0 4.0 16.0 36.0
 37519840
 1.0 25.0 4.0 36.0 9.0 49.0 16.0
 37519840

(assuming loc gives something related to the address of the array)

like image 380
Jellby Avatar asked Oct 15 '25 17:10

Jellby


2 Answers

In your example, it matters whether idx has the same extent (number of elements) as S. If it does, then the shape of S(idx) is the same as that of S and the standard says that no reallocation of S occurs. But if they are different, then the standard says S is deallocated, then reallocated to the shape of S(idx). If this deallocation/reallocation occurs, it is unpredictable (and probably unlikely) if the base address remains the same.

You then asked what if S was not allocatable - in this case, the shapes must match and it's just a copy of data, though possibly via a temporary array since there is overlap.

-- Edit August 24, 2019 --

I polled the J3 (US Fortran standards committee) email list on this. The consensus was that, in the absence of TARGET, the "changing address" was standard-conforming, though more than one member questioned whether it was a good idea. The compiler developers evidently feel that allocating new storage and doing a single copy is faster than keeping the same storage and doing two copies (one to a temp and then one back to S.) I might see this as beneficial if a lot of data was being copied - maybe - but not in smaller cases.

In any event you can, as you discovered, disable this behavior by giving S the TARGET attribute.

like image 78
Steve Lionel Avatar answered Oct 18 '25 01:10

Steve Lionel


The Fortran standard says little about "memory locations". It does, however, have (Fortran 2018, Note 16.24):

It is expected that the implementation of allocatable objects will typically involve descriptors to locate the allocated storage

In the case of the question, though, it can be reasonably expected that no implementation will always keep S having the same address for the first element after assignment: S after the assignment may be arbitrarily larger than S before the assignment. In such cases a new allocation of memory may be required.

If S is not allocatable (strictly, of deferred length) its size won't change as a result of the assignment: however, it would be compatible (in many but not all cases) with the standard for the base address of S to move to a new location comparable to an array-temporary.

In cases where storage association is required (which does restrict the moving of variables in memory), the use of allocatable variables is heavily restricted.

like image 40
francescalus Avatar answered Oct 18 '25 01:10

francescalus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!