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

Cases where a temporary array is created

gn164
Beginner
503 Views

 

Hi,

According to the ifort developer guide:

Fortran language semantics sometimes require the compiler to make a temporary copy of an array or array slice. Situations where this can occur include:

  • Passing a non-contiguous array to a procedure that does not declare it as assumed-shape.

  • Array expressions, especially those involving RESHAPE, PACK, and MERGE.

  • Assignments of arrays where the array appears on both the left and right-hand sides of the assignment.

  • Assignments of POINTER arrays.

Could someone please provide some examples for cases 2,3,4 .

These are not related to function calls so are the temporaries created in those cases still detectable with the -check arg_temp_created option? 

0 Kudos
3 Replies
Steve_Lionel
Honored Contributor III
503 Views

You're correct that -check arg_temp_created won't detect these cases. Any function that returns an array, including intrinsics, may create a temporary array copy. The third item is for things such as:

A(i:j) = A(i-1:j-1)

The standard says that the right side of an assignment is completely evaluated before the left side is modified. The compiler tries to determine if a temp is needed or not, but errs on the conservative side.

As for pointer assignments, since pointers can create aliases, the compiler has to use temps to avoid errors.

0 Kudos
gn164
Beginner
503 Views

 

Hi Steve,

Thank you for your comment.

On the subject of array assignments, I notice that in the following code

     program realloc_test
        include "cmp.fi"

        real, allocatable :: a1(:)
        real, allocatable :: a2(:)

        allocate(a1(100))
        allocate(a2(100))

        a1  = 0.05
        a2  = a1

        print * , a2(1)
     end program realloc_test

The compiler seems to reallocate a2 before the assignment a2 = a1.

I see that there is a:

call      for_realloc_lhs                               #12.9

in the generated assembly code.

This goes away only if I use -nostandard-realloc-lhs in the compiler flags or if I change the assignment to a2(:) = a1(:)

Is it correct that the compiler would reallocate the lhs in this case? I would not expect so as a1 and a2 have the same shape.

If it does reallocate, I am wondering if that would cause any slowdowns  in a multi-threaded environment?

 

0 Kudos
Steve_Lionel
Honored Contributor III
503 Views

The call to for_realloc_lhs is there to satisfy language semantics - the routine checks first and then does the reallocate if necessary. The check is as fast as I could make it (I wrote this particular routine), but it is not zero time. Yes, if it does have to reallocate then there is the time to do the free and re-allocate. In your example, it would not do this because the shapes are the same.

Using (:) disables this language feature (I discuss that here.)

0 Kudos
Reply