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

Transpose causes stack overflow on allocated pointer

eos_pengwern
Beginner
1,385 Views
I've noticed that

[bash]A = transpose(B)[/bash]causes a stack overflow if A and B are defined via

[bash]real(kind(1d0)), pointer, dimension(:,:) :: A, B allocate(A(700,700), B(700,700))[/bash]
and yet not if A and B are defined as allocatable arrays of the same size.

Is there a reason for this,or is it just a quirk of the way that the transpose command is implemented by the Intel compiler (I'm using 12.1.4.325)?

In my own application, it would be slightly more convenient for Aand B to be pointers, so I'd have theoption either of allocatingthem explicitly or of getting them to point to something already allocated somewhere else. Unfortunately this behaviour rules that out, so I've been forced toworkaround it.

0 Kudos
1 Solution
IanH
Honored Contributor III
1,385 Views
Further, note when A and B do not have the pointer attribute the compiler knows that the storage areas for the two variables are distinct - they cannot overlap.

If the variables are pointers (or one is a pointer and the other has the target attribute) then it is very possible that the storage areas overlap (the variables are aliased in some way). The code generated by the compiler needs to be defensive to this in the general case. Creating a temporary copy is one way of doing this - another option is to test at runtime for overlap and then decide dynamically whether a temporary is required. For small arrays the execution penalty of the test might exceed the penalty of the temporary copy.

In simple specific cases the compiler may be able to follow the logic of the whole program and determine statically that the storage areas never overlap, but that sort of static analysis is not straightforward unless the code is trivial.

If the programmer knows that the storage areas will always be distinct, then they can code appropriately. For example, they could pass the arrays to a worker routine that takes them as non-pointer dummy arrays and then do the assignment in that worker routine.

View solution in original post

0 Kudos
4 Replies
mecej4
Honored Contributor III
1,385 Views
In many situations where the right hand side of a Fortran assignment statement is an array expression, a temporary array may need to be allocated on the stack. If stack space is insufficient, the program may fail. The "/heap-arrays:n" compiler option may alleviate the problem somewhat.
0 Kudos
TimP
Honored Contributor III
1,385 Views
In general, intrinsics such as transpose and matmul must allocate a temporary matrix to receive the result. Certain compilers suppress the temporary when there is assignment directly to a suitable array, but ifort does not. ifort does perform optimizations to elide transpose in a context such as matmul(a,tranpose(a)).
As mecej4 mentioned, /heap-arrays will avoid using stack space. The :n option applies only where the size of the allocation is known at compile time.
0 Kudos
IanH
Honored Contributor III
1,386 Views
Further, note when A and B do not have the pointer attribute the compiler knows that the storage areas for the two variables are distinct - they cannot overlap.

If the variables are pointers (or one is a pointer and the other has the target attribute) then it is very possible that the storage areas overlap (the variables are aliased in some way). The code generated by the compiler needs to be defensive to this in the general case. Creating a temporary copy is one way of doing this - another option is to test at runtime for overlap and then decide dynamically whether a temporary is required. For small arrays the execution penalty of the test might exceed the penalty of the temporary copy.

In simple specific cases the compiler may be able to follow the logic of the whole program and determine statically that the storage areas never overlap, but that sort of static analysis is not straightforward unless the code is trivial.

If the programmer knows that the storage areas will always be distinct, then they can code appropriately. For example, they could pass the arrays to a worker routine that takes them as non-pointer dummy arrays and then do the assignment in that worker routine.
0 Kudos
eos_pengwern
Beginner
1,385 Views
That sounds like the solution; allocatable arrays are obviously distinct from one another, whereas pointer arrays may not be. In my actual application thereis another degree of indirection, since the pointer-defined arrays were components of derived types which were themselves addressed via pointers. The compiler is obviously able to see through this latter level, but plays safe when it encounters the arrays themselves.
0 Kudos
Reply