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

An array temporary was created for argument #x

bucaioni__thomas
New Contributor I
7,960 Views

Hello,

When activating the flag -check all, the following warning appears:

forrtl: warning (406): fort: (1): In call to MYFUNC, an array temporary was created for argument #1

Is temporary array creation something that should be avoided?

0 Kudos
1 Solution
andrew_4619
Honored Contributor III
7,929 Views

Yes a would not expect that to avoid the temp as your array slice is not contiguous. That is where the reverse definition of the array indices would help. If the coordinate is indeed that (xyz) the most common usages would be to want slices that are a single point not slices that have all the x's or all the y's.  It is probable that your choice makes the code very inefficient particularly if the array is very large as the x y z  for a point will be stored a long way from each other rather than adjacent address. 

View solution in original post

0 Kudos
8 Replies
jimdempseyatthecove
Honored Contributor III
7,960 Views

Array temporaries are generated when the called procedure accepts an array argument that is required to have a stride-1 cell placement. For example passing Array(1,1:10) to be received as a Dummy(1:10). In this case the temporary cannot be avoided. Array temporaries can also be generated in expressions. This may or may not significantly affect performance. When it adversely affects performance, changing the expression into a DO loop can remove the temporary array.

I wouldn't worry about array temporaries during initial development. I would suggest deferring investigation until into your optimization phase of development. Get it right first, faster second.

Jim Dempsey

0 Kudos
bucaioni__thomas
New Contributor I
7,943 Views

All the procedures are in a module so no need for interface, and all the parameters have an INTENT according to their use. The warnings I tracked down all came from an array extraction:

my_proc(my_coordinates(my_index,1:3))

Since the procedures are in a module, does it worth having a local array in the module and affect it before the procedure call? It would avoid the temporary array creation at call

0 Kudos
andrew_4619
Honored Contributor III
7,934 Views

In answer to the last question, there are only 3 elements for which data is being copied so the effect is very small even if you do it many times. My questions is the use of 

my_coordinates(my_index,1:3)

 

It depends how you use it but maybe if you had made it the way below it would be better. If 1:3 is the full extent use : instead of 1:3 as in some instances I have seen that optimise better and it looks neater!

my_coordinates(1:3,my_index)

 

0 Kudos
bucaioni__thomas
New Contributor I
7,932 Views

The warning is triggered by the neater version too:

 

my_proc(my_coordinates(my_index,:))

 

but thank you for the advice

0 Kudos
andrew_4619
Honored Contributor III
7,930 Views

Yes a would not expect that to avoid the temp as your array slice is not contiguous. That is where the reverse definition of the array indices would help. If the coordinate is indeed that (xyz) the most common usages would be to want slices that are a single point not slices that have all the x's or all the y's.  It is probable that your choice makes the code very inefficient particularly if the array is very large as the x y z  for a point will be stored a long way from each other rather than adjacent address. 

0 Kudos
Steve_Lionel
Honored Contributor III
7,960 Views

Yes, because it means that your data was copied to (and probably from) a temporary array and that can hurt performance. If you are passing a non-contiguous array section it may be better if in the called procedure the dummy argument is declared assumed-shape with (:) bounds. It is worth doing timing tests of both ways to see which is better. Note that if you do make the dummy argument assumed-shape, an explicit interface is required to be visible in the caller.

0 Kudos
jimdempseyatthecove
Honored Contributor III
7,960 Views

Additional comment about passing non-stride-1 array arguments.

Performance-wise, assure that the called procedure has an interface .AND. use the INTENT(...) attribute to identify the arguments as IN, OUT or INOUT. When there is no interface, or interface with no INTENT(...), the default is assumed to be INOUT.

When INTENT(INOUT) is attributed (or assumed) with a temporary array:

1) obtain memory for temporary (either stack or heap)
2) copy actual data array slice to temporary array
3) call function using temporary in place of actual
4) copy temporary data array to actual data array slice
5) release memory allocation

For INTENT(IN) arguments, step 4) will be omitted. For INTENT(OUT) arguments, step 3) will be omitted.

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
7,960 Views

Additional, additional comment.

Situations where array temporaries are (may be) desirable are where the called procedure can effectively use vector instructions with contiguous arrays. IOW the time lost performing the 1) 2) call 4) 5) overhead is significantly less than the time recovered with the vectorized code. As to what these times are, this will have to be determined during testing.

Jim Dempsey

0 Kudos
Reply