Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29284 Discussions

Does array constructor in actual argument create dummy on stack?

abhimodak
New Contributor I
1,186 Views
Hi

In the sample below, I think there will be a copy and thus array I in subroutine Method will be on stack? (Although I don't get a message with /check:arg_temp_created.)

I am trying to see a possibility of numerics changing in a big program that uses MKL and there is a call with such array constructor. As mentioned in another post, I get slightly different numbers if I add more arguments.

Abhi

----

Module OM
Implicit None
Character(10) :: test = 'Test'
Contains
Subroutine Method(I)
Integer :: I(:)
print *, I
End Subroutine Method
End Module OM

Program Test_ArrayConstructor

Use OM

Implicit none

Integer :: k, l, m

k = 0
l = 1
m = 2

Call Method([k,l,m])

End Program Test_ArrayConstructor
0 Kudos
8 Replies
Steven_L_Intel1
Employee
1,186 Views
The constructor value has to go somewhere. It will almost certainly go on the stack. /check:arg_temp_created really shouldn't issue a message about this, but I have seen in some cases that it does.
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,186 Views
[k,l,m] is an explicitly declared array which is on the stack (in situations were k,l,m are variables not parameters, were they parameters, the compiler might just as well create a static object). Although this creates an object on the stack in the scope of the statement, grammatically you might NOT consider this a temporary array (since it is explicitly stated/declared).

Whereas

([k,l,m]) * 2

is an expression, implicitly creating a temporary object from the product of an explicitly declared array and a scalar.

"Temporary array created" is not equivilent to "array created on the stack"

recursive subroutine foo()
real :: vec(3)

is an (explicit) array created on the stack .AND. which is not a temporary array.

While one could argue [k,l,m] is temporary because its lifetime is the duration of the statement rather than the scope of the subroutine/function, it also has the distinction of being explicitly declared. Consider

Method([k,l,m])
OtherMethod([k,l,m])

Isthe compiler permitted to create and use but one instance of [k,l,m]? (as it would for using vec in both calls). If so, then clearly [k,l,m] behavior is not that of a temporary (it has persistence).

I have not tested the above for truth or falsehood, simply making an argument.

Jim


0 Kudos
Steven_L_Intel1
Employee
1,186 Views
The compiler will reconstruct the array expression for the second call, as Method might have written to it. (Such a program would be non-standard.)
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,186 Views
Is the true when the interface to Method specifies INTENT IN for the passed array?

It would seem that this would be an opportunity for an optimization, especially in the case were [...] assembles a large array.

Jim
0 Kudos
Steven_L_Intel1
Employee
1,186 Views
You're right that it could keep it, but my guess is that it does not.
0 Kudos
abhimodak
New Contributor I
1,186 Views
Jim and Steve

The points discussed here are exactly in line with what prompted me to ask this question; the important situation being when the actual argument is an array constructor while the corresponding dummy argument being an assumed-shape array "with Intent(IN)".

I have very little, if any, understanding of what compilers do and hence have a too naive a way of thinking what "compiler should be doing". :)

We have been seeing array alignment and numerical reproducibility issues (since we started to use MKL). In my other post, I have mentioned that the numerics are slightly different when array constructor actual argument is involved (Steve, I don't have a short test version; I am still trying). Currently, I am attributing these differences to the stack copy and hence possible alignment issues.

Abhi
0 Kudos
Steven_L_Intel1
Employee
1,186 Views
Abhi, for your purposes, the INTENT(IN) aspect is not relevant. What you care about is how the compiler builds an array constructor, and I assume that it probably doesn't align it any more than "natural" alignment. You can certainly test this by declaring an array variable with the desired alignment, assigning the array constructor to it and passing that - now you're in control of the alignment.
0 Kudos
abhimodak
New Contributor I
1,186 Views
Yes Steve. That's what I am doing. As I said I had an over-over-simplified (aka wrong!) idea of what the compiler "should" be doing.

Abhi
0 Kudos
Reply