- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I see that the recursive compiler switch means "all routine should be compiled for possible recursive execution."
Does that mean that you can have the switch "off" and that declaring a RECURSIVE SUBROUTINE still will work properly?
Is there any execution speed or size to turning it off if the answer to the question is Yes?
Linda
Does that mean that you can have the switch "off" and that declaring a RECURSIVE SUBROUTINE still will work properly?
Is there any execution speed or size to turning it off if the answer to the question is Yes?
Linda
Link Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - lklawrie
I see that the recursive compiler switch means "all routine should be compiled for possible recursive execution."
A subroutine with large local arrays could take longer to enter and exit when those arrays aren't subject to a default SAVE option.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The switch is the same as if you had added RECURSIVE to every procedure in your build. I would recommend, in general, using the keyword rather than the switch to indicate that a procedure may be called recursively. The major effect of this is that any variables and data structures the compiler might have allocated statically will now be allocated on the stack. This may reduce the size of the executable but may cause stack overflow issues if the stack size is not large enough (set with a linker option.) I have seen conflicting data as to which is faster - I'd guess that using the stack would help with cache locality.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry if this is a dup. it seemed to disappear in cyberspace.
so... for example
RECURSIVE SUBROUTINE(x,y,f,a)
where f is a function inthe calling module
INTERFACE
FUNCTION f(a)
END FUNCTION
END INTERFACE
does the INTERFACE need to say f is RECURSIVE or only the modules that need f to be RECURSIVE (re: Tim's comment).
I haven't done much recursive since Algol days -- one of my developers found it useful to program for this.
Linda
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Reading Tim18's and Steve's responses leads me to wonder about the precedence of switches and keywords. As in, how does the compiler handle having both the "compile all routines as recursive" and "default save everything" switches set?
Or, as currently the case for several routines in the code I'm migrating to IVF, when the "default save everything" switch is set, how does the compiler allocate storage of local variables in routines declared as recursive?
And, if that should happen to be part of the reason the program is disappearing down the recursive rabbit-hole, do I have the option of dropping a Save statement on crucial variables in those routines?
Or, as currently the case for several routines in the code I'm migrating to IVF, when the "default save everything" switch is set, how does the compiler allocate storage of local variables in routines declared as recursive?
And, if that should happen to be part of the reason the program is disappearing down the recursive rabbit-hole, do I have the option of dropping a Save statement on crucial variables in those routines?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
SAVE, according to Adams, Brainerd, et.al. "Fortran 95" is supported in RECURSIVE subprograms. There will be just one copy of SAVE objects, rather than each recursive instance getting its own copy. Either RECURSIVE or SAVE would take precedence over compiler switches like /Qsave or /Qauto.
Steve is advising the use of Fortran declarations RECURSIVE or SAVE where needed, so that a wrong compiler switch setting won't break it.
I'm wondering whether to be concerned about providing for OpenMP, but the Fortran standard itself doesn't have much relationship to threading until the next revision.
Steve is advising the use of Fortran declarations RECURSIVE or SAVE where needed, so that a wrong compiler switch setting won't break it.
I'm wondering whether to be concerned about providing for OpenMP, but the Fortran standard itself doesn't have much relationship to threading until the next revision.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In general, syntax overrides switches. The /Qsave switch documentation says "This option saves all variables in static allocation except local variables within a recursive routine and variables declared as AUTOMATIC."
This text is not completely true. It turns out that what it does is give SAVE semantics to all local variables (with the exceptions noted.) An issue has come up that this also affects ALLOCATABLE variables. As there is no other option for saying "give me static rather than stack", we're kinda stuck but are trying to figure out how to untangle allocatables.
You ALWAYS have the option of adding a SAVE, and I would strongly encourage you to do so if you have variables that depend on SAVE semantics rather than relying on a switch.
This text is not completely true. It turns out that what it does is give SAVE semantics to all local variables (with the exceptions noted.) An issue has come up that this also affects ALLOCATABLE variables. As there is no other option for saying "give me static rather than stack", we're kinda stuck but are trying to figure out how to untangle allocatables.
You ALWAYS have the option of adding a SAVE, and I would strongly encourage you to do so if you have variables that depend on SAVE semantics rather than relying on a switch.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, guys, for your answers. I had expected that, as Steve phrases it, "syntax overrides switches."
However, I don't understand what Steve means when writes that the switch gives "SAVE semantics" instead of "saving in static allocation." Are you referring to an inaccuracy in the description of which variables receive this dispensation, or are you implying that the compiler confersdifferent levels of salvation?
I must say that CVF didn't require me to pay attention to questions of static vs. stack allocation, and I am essentially uninformed regarding the use of the stack. If anyone can point me to an overview of stacks and heaps I'd certainly appreciate it.
Tim18, I'm afraid I'm not going to be able to avoid dealing with the OpenMP implications of all this. But first I have to get the program running under IVF.
However, I don't understand what Steve means when writes that the switch gives "SAVE semantics" instead of "saving in static allocation." Are you referring to an inaccuracy in the description of which variables receive this dispensation, or are you implying that the compiler confersdifferent levels of salvation?
I must say that CVF didn't require me to pay attention to questions of static vs. stack allocation, and I am essentially uninformed regarding the use of the stack. If anyone can point me to an overview of stacks and heaps I'd certainly appreciate it.
Tim18, I'm afraid I'm not going to be able to avoid dealing with the OpenMP implications of all this. But first I have to get the program running under IVF.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think Steve means that we shouldn't concern ourselves unnecessarily with the mechanism, but simply use the semantics of Fortran in the usual case where we don't need to know the details. We certainly shouldn't say stack allocation when that might be only one possibility for accomplishing the same job, such as those situations where /heap-arrays shifts allocation from stack to heap without changing semantics.
In general, RECURSIVE requires each instance of a subroutine to have its own copy of each data object.
Private or threadprivate objects in OpenMP have some of the same flavor.
In general, RECURSIVE requires each instance of a subroutine to have its own copy of each data object.
Private or threadprivate objects in OpenMP have some of the same flavor.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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