Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Important Update: Community Platform Migration​. Learn more​>

fortran overflow

Intel_C_Intel
Employee
1,906 Views

I get stack overflow with some function :

1 : the matmul function

double precision, dimension(:,:),pointer :: a,b,c

a, bandc are allocated

if the size of a,b, c is too high, i have a stack overflow when i use c = matmul(a,b)

i have no stack overflow when i do the array multiplication using manual loop, but its too slow !!!!

2 : a matrix assignement

I have the same problem as above when i do, for example, a(:,:) = b(:,:) produce a stack overflow when the size of array is too high but doing this using manual loop does not produce stack overflow

3 : using the command fortran : "where" whith big array or vector

I specify that i have put the stack allocation to the maximum !

Do you have some solution to these problems ? I have try the use of allocatable arrays, it seems to be better, but why ??and what can i do to avoid this problem of stack allocation with very large array ?

thanks a lot for any answer or suggestion

0 Kudos
8 Replies
TimP
Honored Contributor III
1,906 Views
1. If you can solve the problem simply, by increasing stack (e.g. /link /stack:9999999), why not? For large matrices, MKL may be faster and should avoid the temporary allocation. Usually, it is entirely possible to approach the speed of MKL with user written code, until the problem becomes large enough to require multiple threads. Depending how you do it, some of the optimizations may be reserved for full optimization options, e.g. -QxW -O3. I agree that use of MATMUL is preferable for conciseness.
2. It is generally advised to use a = b rather than a(:,:) = b(:,:). If it is important to you to perform an optimization which is missing, file an issue on your premier.intel.com account.
3. where() tends to be inefficient because of the creation of an implied logical array. If it is important to you to use where(), and you have a case where other compilers optimize it better, you could report it on premier.intel.com.
0 Kudos
Steven_L_Intel1
Employee
1,906 Views
Tim gives good advice here. Ideally, you want to eliminate the temporary from being created.

If you can't eliminate it, and if you are using a relatively recent (since September '06) compiler, you can use the /heap-arrays switch to tell the compiler to allocate array temps dynamically. Not having the temps at all is better.
0 Kudos
jond
Novice
1,906 Views

This is somewhat unrelated to the original topic of the thread, but I am curious about one point that Tim made:

> It is generally advised to use a = b rather than a(:,:) = b(:,:).

I use a(:,:) = b(:,:) mainly to remind myself later when reading the code that a and b are arrays not scalars. So does this syntax have a detrimental effect on the optimization? And if so, is this a compiler specifiec issue?

Thanks,

Jon

0 Kudos
Steven_L_Intel1
Employee
1,906 Views
The compiler has to work harder to recognize that you're assigning whole arrays when you use the (:,:) syntax. In the past, the Intel compiler sometimes didn't do that. I think that current versions generally figure this out, but I tend to advise against using array slice syntax unnecessarily. There's no particular language semantics difference here.
0 Kudos
Intel_C_Intel
Employee
1,906 Views

Thanks for you and Tim

I have however an question about the ALLOCATABLE array. What is the main difference with POINTER array ? Is it the fact that ALLOCATABLE are contiguus array ? If it is true, do you think that the use of ALLOCATABLE instead of POINTER can resolve my problem ?

Thanks a lot

Stephane

0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,906 Views

I have however an question about the ALLOCATABLE array. What is the main difference with POINTER array ? Is it the fact that ALLOCATABLE are contiguus array ? If it is true, do you think that the use of ALLOCATABLE instead of POINTER can resolve my problem ?



Well, there are several differences, and the most referred ones are in lifetime and potential for memory leaks. However, yes, your observation is true -- an allocatable array is always contiguous and known not to be aliased* so the compiler has a better leeway for optimization.

The Intel compiler is now supposed to** have run-time detection of contiguity, i.e. can decide whether to apply "memmove" or "memcpy" approach rather than equivalent of do-loops.

*) Aliasing can occur only with pointers and (potentially, although Fortran standard disallows this) dummy arguments. Take for example:
INTEGER, POINTER:: A(:), B(:)
INTEGER, TARGET:: C(100)
A=>C(1:60)
B=>C(100:41:-1)
A(:) = B(:)
here, since A and B overlap, the compiler must not just "memcpy" B to A, nor it may safely attempt a "do-loop" equivalent (as it's difficult to figure out the correct order): thus, it has to create an array temporary.

**) Steve can you please confirm this?
0 Kudos
TimP
Honored Contributor III
1,906 Views
This discussion has branched out in multiple directions. So my 2 follow-up comments aren't mutually related:
a) I happened upon a case where ifort doesn't optimize expressions where whole-array notation is mixed with section notation.
dot_product(a(j:j+size(b)),b)
where it does optimize when both operands are expressed as array sections.
b)
INTEGER, POINTER:: A(:), B(:)
INTEGER, TARGET:: C(100)
A=>C(1:60)
B=>C(100:41:-1)
A(:) = B(:)
On current Intel Xeon family CPUs, there isn't anything which memmove() could do which would improve performance, and I don't believe ifort attempts to make any such substitution. IA-64 compilers do perform such automatic substitutions. However, it can't be done in this case, since the operation can't be expressed as a byte-wise move with a uniform stride. If it were changed to
B=>C(41:100)
then it would be only a question of overlap, not reversal, and memmove() would be applicable.

In principle, over-lapping operations (without mixing stride 1 and -1) could be vectorized by a compiler which analyzes to see whether reversing stride overcomes dependencies. Up to now, requests to add such capability to ifort have been rejected. It is recognized as a standard optimization, which gfortran has begun to implement. Try the search term 'gfortran loop reversal'
0 Kudos
Wendy_Doerner__Intel
Valued Contributor I
1,906 Views

Steve is on vacation but I have checked with engineering and the asnwer to:

The Intel compiler is now supposed to** have run-time detection of contiguity, i.e. can decide whether to apply "memmove" or "memcpy" approach rather than equivalent of do-loops.

is

There is not a clear yes/no to the question of whether the Intel Visual Fortran Compiler will perform runtime checks for array continuity. Yes, the Intel Fortran compiler front end does do some run-time detection of contiguity. For example, this runtime check is done for deferred-shape arrays that are being passed to routines expecting explicit-shape arrays. This allows us to avoid creation of a temp and copy-in/copy-out. Note, though, that this is only for deferred-shape arrays that are being passed as arguments in a call statement or function call.

In the more general case given in this thread, if the loop stride and array section stride can be determined at compile time then the compiler is able to make use of fast memcpy/memset operations. It is not always obvious when this will be done, as inlining and constant propagation can sometime help determine the array stride at compile time. However, you will note that these checks are done at compile time as opposed to runtime. This is an open area of research for us so this may change at some point in the future.




0 Kudos
Reply