- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[fortran]program main integer :: n double precision,pointer :: d(:,:) n=10000 allocate(d(n,n)) call happy(n,d) d= sad(n) print *,"D(1,1) =",d(1,1),"D(n,n) =",d(n,n) deallocate(d) contains subroutine happy(n,d) integer :: n double precision :: d(:,:) d=n*2 print *,"Hapy :)" end subroutine function sad(n) result (d) integer :: n double precision :: d(n,n) d=n*3 print *,"Sad :(" end function end program[/fortran]My question is, why program crash on call "sad" function (segmentation fault) when I run it - and why subroutine "happy" work? The second questrion is how to change "sad" function to work well?
Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
sad has to return it's RESULT in a temporary, on stack by default. Read this for some insight:
http://software.intel.com/en-us/articles/determining-root-cause-of-sigsegv-or-sigbus-errors/
Unlimit your stack.
http://software.intel.com/en-us/articles/determining-root-cause-of-sigsegv-or-sigbus-errors/
Unlimit your stack.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So it means that function must have extra space for temporary tables and extra time to copy result from temporary to destination?So using function isimpractical when we have arrays? So better way to work with arrays(as calculatrion result) is use SUBROUTINES than use functions?
I have right?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>sad (function)has to return it's RESULT in a temporary, on stack by default.
It doesn't have to do this (temporary on stack)
It cannot use the stack within the function sad (since it is cleaned up on return from sad)
If it uses the stack of the caller (where else should it get stack space from), then if the caller is compiled with heap arrays, then the temporary is heap allocated (iow - .not. has to return on stack).
Also, the compiler optimizer should be able to determine the code generated is:
construct temp for return value (either on stack or heap allocated)
function call to sad with temp asresult
copy temp (result) to destination
destroy temp (result)
And replace this with:
function call to sad with destination as result
N.B. the substitutioncould be made whenever the destination is not an argument to the function (or aliased)
.or.
was an argument to the function call.and. the compiler could determine a non-interference situation
Jim Dempsey
It doesn't have to do this (temporary on stack)
It cannot use the stack within the function sad (since it is cleaned up on return from sad)
If it uses the stack of the caller (where else should it get stack space from), then if the caller is compiled with heap arrays, then the temporary is heap allocated (iow - .not. has to return on stack).
Also, the compiler optimizer should be able to determine the code generated is:
construct temp for return value (either on stack or heap allocated)
function call to sad with temp asresult
copy temp (result) to destination
destroy temp (result)
And replace this with:
function call to sad with destination as result
N.B. the substitutioncould be made whenever the destination is not an argument to the function (or aliased)
.or.
was an argument to the function call.and. the compiler could determine a non-interference situation
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You're partly right, you have constructed an example illustrating how an array valued function can encounter surprising performance problems.
A fairly commonly encountered example is with the use of MATMUL, as compared with BLAS ?GEMM. The latter avoids allocation and use of additional arrays, which has potential serious cache performance effects (when the data set is large enough for efficient BLAS usage, e.g. 20x20).
I would not go so far as to recommend against array valued functions where they might clarify your source code, until you determine there is a serious performance problem.
A fairly commonly encountered example is with the use of MATMUL, as compared with BLAS ?GEMM. The latter avoids allocation and use of additional arrays, which has potential serious cache performance effects (when the data set is large enough for efficient BLAS usage, e.g. 20x20).
I would not go so far as to recommend against array valued functions where they might clarify your source code, until you determine there is a serious performance problem.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I try to summary it:
Functions that return arrays - advantages:
+ clarify source code (?)
Functions that return arrays - disadvantages:
- use extra space for result array
- use extra time for copy result
- unreliable(in example above - stop working for big 'n' - and you must use non standard compiler options or use some system commands(ulimit) to rectify situation)
- unportable (on gfortran it works, on ifort not)
-------------
When we use convenction like this for "array returned function" substitute:
subroutine happy_f(r,n)
Where last letter of subroutine name is "_f" and first argument is always result array. We get the same clarify code as functions but beter performance, portability, memory usage and reliability.
-------------
I'm not experienced fortran programmer, but I must write big part of fotran 95 code. Can you help me and tell -Doesuseaboveconvention for "array return" is a good practice? Or maby you know better way?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You could alsoclarify with comments
call happy(
r, & ! result
a, b & ! tweedle dee, tweedle dum
)
Or use a function and have the return value be a scalar or logical representative of an error or status
ok = happy(ret,a,b)
if(.not. ok) goto lalaland
Think of C functions where a scalar can be returned (int/size_t/char*,...) but the output array references are passed in the argument list (usually first but not always).
Jim Dempsey
call happy(
r, & ! result
a, b & ! tweedle dee, tweedle dum
)
Or use a function and have the return value be a scalar or logical representative of an error or status
ok = happy(ret,a,b)
if(.not. ok) goto lalaland
Think of C functions where a scalar can be returned (int/size_t/char*,...) but the output array references are passed in the argument list (usually first but not always).
Jim Dempsey

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page