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

Stack overflow with array section

Arjen_Markus
Honored Contributor II
984 Views
Hello,

this is probably a problem that has been known for some time, but I still want to point it out.
The following program produces a stack overflow (using Intel Fortran version 10 on Windows XP):

program ww
real, dimension(:,:), allocatable :: x

allocate( x(10,2000000) )

call random_number( x )

open( 10, file = 'ww.out', form = 'unformatted' )
write( 10 ) x(2,:)
close( 10 )

end program


The problem disappears when you replace the write statement by:

write( 10 ) ( x(2,i), i=1,size(x,2) )

Apparently a temporary array is created by taking the array section - in my test of the actual
program it all worked, because the array was only 2*ten thousand.

What is the command-line option to make the creation of such temporary arrays visible?
(/check:arg_temp_created did not give any report)

Regards,

Arjen
0 Kudos
4 Replies
Ron_Green
Moderator
984 Views
Quoting - arjenmarkus
Hello,

this is probably a problem that has been known for some time, but I still want to point it out.
The following program produces a stack overflow (using Intel Fortran version 10 on Windows XP):

program ww
real, dimension(:,:), allocatable :: x

allocate( x(10,2000000) )

call random_number( x )

open( 10, file = 'ww.out', form = 'unformatted' )
write( 10 ) x(2,:)
close( 10 )

end program


The problem disappears when you replace the write statement by:

write( 10 ) ( x(2,i), i=1,size(x,2) )

Apparently a temporary array is created by taking the array section - in my test of the actual
program it all worked, because the array was only 2*ten thousand.

What is the command-line option to make the creation of such temporary arrays visible?
(/check:arg_temp_created did not give any report)

Regards,

Arjen

As you noticed, /check:arg_temp_created only applies to temporaries created for arguments. This is provided to give users hints as to where they might be able to use interface blocks or modules to overcome some unnecesary temporary creation.

There is no option to display the creation of ALL temporaries. We have received this feature request in the past.

your array section x(2, : ) is discontiguous in memory (Fortran is column-major ordered), hence the need for the array temporary to collect all the elements of the row vector into contiguous memory - contiguous memory is essential for optimal IO performance.

To avoid the stack overflow, use /heap-arrays option to put the temporaries in heap rather than stack.

ron
0 Kudos
IanH
Honored Contributor III
984 Views

As you noticed, /check:arg_temp_created only applies to temporaries created for arguments. This is provided to give users hints as to where they might be able to use interface blocks or modules to overcome some unnecesary temporary creation.



Is that right for this case though? With /check:all on 11.0.* I get warnings such as...

forrtl: warning (402): fort: (1): In call to I/O Write routine, an array temporary was created for argument #7

when a temporary needs to be created for a formatted WRITE statement.

WRITE (lu,fmt) i, j, ..., my_rather_large_array(i,j,:)

I've actually been wondering if there was a way to turn off these array temporary warnings for IO only and leave them on for "normal" procedure calls. In this specific case the WRITE's are in an iteration loop just for debugging and the resuling 45 zillion lines of warning messages can make it a bit hard to spot "real" temporary warnings that I care about.

/check:arg_temp_created_except_for_write_statements_that_you_know_are_ok

(Alternatively I could put in the required implied do-loops like the OP has done, but it is easier to complain...)


0 Kudos
Arjen_Markus
Honored Contributor II
984 Views

As you noticed, /check:arg_temp_created only applies to temporaries created for arguments. This is provided to give users hints as to where they might be able to use interface blocks or modules to overcome some unnecesary temporary creation.

There is no option to display the creation of ALL temporaries. We have received this feature request in the past.

your array section x(2, : ) is discontiguous in memory (Fortran is column-major ordered), hence the need for the array temporary to collect all the elements of the row vector into contiguous memory - contiguous memory is essential for optimal IO performance.

To avoid the stack overflow, use /heap-arrays option to put the temporaries in heap rather than stack.

ron

Well, that is clear enough - it just took me by surprise, when last friday afternoon I supplied the program in response to a somewhat urgent request ;). Fortunately, the implied do-loop did the trick.

/heap-arrays will be a useful option, thanks.

Regards,

Arjen
0 Kudos
Ron_Green
Moderator
984 Views
Quoting - IanH


Is that right for this case though? With /check:all on 11.0.* I get warnings such as...

forrtl: warning (402): fort: (1): In call to I/O Write routine, an array temporary was created for argument #7

when a temporary needs to be created for a formatted WRITE statement.

WRITE (lu,fmt) i, j, ..., my_rather_large_array(i,j,:)

I've actually been wondering if there was a way to turn off these array temporary warnings for IO only and leave them on for "normal" procedure calls. In this specific case the WRITE's are in an iteration loop just for debugging and the resuling 45 zillion lines of warning messages can make it a bit hard to spot "real" temporary warnings that I care about.

/check:arg_temp_created_except_for_write_statements_that_you_know_are_ok

(Alternatively I could put in the required implied do-loops like the OP has done, but it is easier to complain...)



This is an superb feature request, and good timing as we're gathering features for the next major version! I'll roll that up into our feature requests for the product.

perhaps /check:arg_no_io

Good one, thanks, I'll champion this with the development team.

ron
0 Kudos
Reply