- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider the following minimal example:
module m
type node_t
type(node_t),pointer::next=>NULL()
end type
type list_t
integer::n
type(node_t)::zeroth
type(node_t),pointer::last=>NULL()
contains
procedure::f
end type
type obj_t
type(list_t)::list
contains
procedure::a
procedure::g
end type
interface obj_t
procedure::new_obj
end interface
contains
subroutine f(this,a)
class(list_t)::this
real::a(this%n)
call RANDOM_NUMBER(a)
end
function new_obj()result(this)
type(obj_t),target::this
this%list%n=0
this%list%last=>this%list%zeroth
end
subroutine a(this)
class(obj_t),target::this
this%list%n=this%list%n+1
allocate(this%list%last%next)
this%list%last=>this%list%last%next
end
subroutine g(this)
class(obj_t)::this
real::a(this%list%n)
call this%list%f(a) ! segfault occurs due to this call
end
end
program p
use m
type(obj_t)::obj
obj=obj_t()
do i=1,3000000 ! this integer must be large to cause the segfault
call obj%a()
enddo
call obj%g()
end
Running the executable compiled from this code using ifx 2024.2.1 with debug flags (`-g -traceback`) ends with a segmentation fault. The problem is caused by the call to subroutine `f` inside of subroutine `g`. Strangely, this problem can be fixed if the integer in the loop is smaller (e.g. 2000000 instead of 3000000). Therefore, I suppose, that ifx generates wrong code.
The debug flags are necessary because otherwise optimization removes the lines causing the problem. (I also have a larger working example that causes segfault even without the debug flags.)
Interestingly, gfortran 13.2.0 also fails to produce working code. However, the NAG compiler (nagfor 7.1) has no problems with this example.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The statement in g and/or f:
real::a(this%list%n)
with n=3000000
is causing a stack overflow.
To correct this, enable heap arrays, .or., make a allocatable and allocate.
Note, increasing stack size may also work, but this may cause other errors in your program.
Jim Dempsey
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The statement in g and/or f:
real::a(this%list%n)
with n=3000000
is causing a stack overflow.
To correct this, enable heap arrays, .or., make a allocatable and allocate.
Note, increasing stack size may also work, but this may cause other errors in your program.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are right! Thank you for this solution.
I'd rather avoid adding any additional compiler flags in my program, that's why I'll use the solution with `allocate`. So is it better to allocate arrays explicitly inside of procedures than to use automatic arrays? The explicit allocation avoids stack overflow, but are there some performance differences between two approaches?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>So is it better to allocate arrays explicitly inside of procedures than to use automatic arrays?
This depends on the size of the arrays. Use automatic for small arrays, allocatable for large arrays.
>>are there some performance differences between two approaches?
With an array size of 3000000, the amount of processing time to use that array will (should) greatly outweigh the additional overhead.
Note, if your code is .NOT. parallel, then consider making the array ALLOCATABLE, SAVE .or. ALLOCATABLE and in a module THEN in your procedure test for allocated, if not, allocate. IOW incur the allocation overhead only once.
Or, if the procedure is entered in a parallel region, consider placing the array in a module and declaring it THREADPRIVATE.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your detailed answer!
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page