Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28630 Discussions

In-Place Array Assignment - Legal In Fortran?

ereisch
New Contributor II
491 Views

In the C world, highly-optimized C-library functions (such as memcpy()) tend to use techniques that break down when the source and destination operands overlap.  The manual page on Linux even explicitly warns the user that this has been the source of significant bugs, and to ensure the areas do not overlap.

 

In Fortran, is an array assignment subject to the same restrictions?  In other words, is:

REAL*4  A(1024), B
[...]
A = A * B

safe programming practice, or will optimizations or vector operations inside the processor start to break things because this is effectively an in-place modify operation?  I tried to search the Language Reference for verbiage on this, but am struggling as to what to call this; "in-place array assignment"?  The Intel Fortran page on the Array Assignment Statement suggests that isn't a problem because they do an array reverse using "A(1:20) = A(20:1:-1)", but I can't find any explicit rules one way or another.

0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
466 Views

In the specific case of A = A * B (vector * scalar), the compiler optimization "should" realize that there are no loop order dependencies, and result in not having to produce a temporary copy of the result for transfer to the LHS.  As to if it "does" eliminate the temporary, this is up to the compiler writer. The code generated must behave (results generated) as if a temporary was created.

In cases where there are loop order dependencies: A(2:20) = A(1:19) * B

The compiler would have to create a temporary result for the RHS before the copy (though advanced optimization techniques can work around this).

Note,  A(2:20) = A(1:19) * B is .NOT. equivalent to DO I=1,19; A(I+1) = A(I) * B; END DO

The former "requires" a temporary to avoid loop order dependencies (carry is not propagated), the latter requires no temporary and the carry is propagated.

 

Jim Dempsey

View solution in original post

0 Kudos
2 Replies
andrew_4619
Honored Contributor III
479 Views

That is not a problem if it is I have many broken codes!  The language rules are such the RHS is evaluated before the LHS is assigned, that could in some cases cause a temporary array I think but generally does not. 

jimdempseyatthecove
Honored Contributor III
467 Views

In the specific case of A = A * B (vector * scalar), the compiler optimization "should" realize that there are no loop order dependencies, and result in not having to produce a temporary copy of the result for transfer to the LHS.  As to if it "does" eliminate the temporary, this is up to the compiler writer. The code generated must behave (results generated) as if a temporary was created.

In cases where there are loop order dependencies: A(2:20) = A(1:19) * B

The compiler would have to create a temporary result for the RHS before the copy (though advanced optimization techniques can work around this).

Note,  A(2:20) = A(1:19) * B is .NOT. equivalent to DO I=1,19; A(I+1) = A(I) * B; END DO

The former "requires" a temporary to avoid loop order dependencies (carry is not propagated), the latter requires no temporary and the carry is propagated.

 

Jim Dempsey

0 Kudos
Reply