- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My c code is repeatedly calling a FORTRAN subroutine. The being called FORTRAN subroutine also calls many other FORTRAN subroutines. Those subroutines have "SAVE" statement which are used to retain the variable values after return (useful for the FORTRAN calculations). But now I need to clear up those save values after it returns from the main FORTRAN subroutine to C program so that it will be ready for next call.
I hope my description is clear enough. Is there an easy way to do this? There are way too many FORTRAN subroutines and variables involved. Any help is appreciated.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks for the quick response! but it is so sad to hear that:)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This suggestion will require some experimentation on your part and what works today may not necessarily work after the next update (IOW you may need to run a verification program when you upgrade your compiler/linker).
In the first FORTRAN program (or module) you link into your image add a static variable named "integer :: ZeroBegin" (or integer, SAVE :: ZeroBegin), and in the last file linked (SAVE or module static variable) as last variable "integer :: ZeroEnd" (or integer, SAVE :: ZeroEnd). Then at the point in your code where you want to initialize you can make a call to memset(LOC(ZeroBegin), 0, LOC(ZeroEnd)-LOC(ZeroBegin)).
** the experimentation you need to do is to examine the Dissassembly code for the load segment name for SAVE variables and for MODULE static variables and for COMMON variables and for PROGRAM global variables. If these are all in .BSS (or other same named load segment name) then you can (may be able to) use one memset to zero out the "static/saved) data. If there are multiple named segments then you may require multiple zeroing code sections.
I use a similar technique for wiping allocated thread local storage. In place of one generalized wipe (e.g. memset) I use per-type wipes
[fortran]! subroutine to wipe a list of n real variables starting at p ! This is typicaly used to wipe allocated memory of various ! structures. See MOD_TOSS for an example of use. subroutine WipeReals(p, n) integer :: n real, dimension(1:n) :: p p = 0.0 end subroutine WipeReals subroutine Wipe_Reals1D(A) real :: A(:) call WipeReals(A, size(A)) end subroutine Wipe_Reals1D subroutine Wipe_Reals2D(A) real :: A(:,:) call WipeReals(A, size(A)) end subroutine Wipe_Reals2D ! subroutine to wipe a list of n integer variables starting at p subroutine WipeIntegers(p, n) integer :: n integer, dimension(1:n) :: p p = 0 end subroutine WipeIntegers subroutine Wipe_Integers1D(A) integer :: A(:) call WipeIntegers(A, size(A)) end subroutine Wipe_Integers1D subroutine Wipe_Integers2D(A) integer :: A(:,:) call WipeIntegers(A, size(A)) end subroutine Wipe_Integers2D [/fortran]...
[bash]subroutine WipeFiniteSolution(s) use MOD_TOSS type(TypeFiniteSolution) :: s integer :: n, nb, ni, nr nb = loc(s.LastReal)-loc(s.FirstReal) nr = (nb / sizeof(s.FirstReal)) + 1 call WipeReals(s.FirstReal, nr) nb = loc(s.LastInteger)-loc(s.FirstInteger) ni = (nb / sizeof(s.FirstInteger)) + 1 call WipeIntegers(s.FirstInteger, ni) call WipeBeads(s) end subroutine WipeFiniteSolution subroutine InitFiniteSolution(s) use MOD_TOSS type(TypeFiniteSolution) :: s nb = loc(s.LastPointer)-loc(s.FirstPointer) ni = (nb / sizeof(s.FirstPointer)) + 1 ! use WipeIntegers for pointers call WipeIntegers(s.FirstPointer, ni) call WipeFiniteSolution(s) end subroutine InitFiniteSolution ...[/bash]
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One other idea:
Create a 'global module' into which you insert all the variables you need to 'save'.
So lets call it 'My_Local_Save' module.
Next,get rid of all your'save' options!! (messy! inefficieint! you're saving stuff you don't need)
Now, in the 'My local_save' module add all the variables you feel you need to save from the various fortran subroutines.
Then in each you simply Use My_Local_Save
you can even use the 'only' option to just access the variables you need from each routine.
(For convenience you might consider a prefix on each variable with the routine name to quickly remind you which routineuses which variable and to keep them all named different).
Then when you need to, from the C routine you call a subroutine which simply re-zero's all the 'local saved variables' in your module 'my_local_save'
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I might add an additional piece of information. In non-recursive, non-OpenMP subroutine any function array declaration defaults to SAVE. Therefore, when you hunt down SAVE's to port into the module, also look for arrays to port as well. You can then insert as first and last variable the dummy variable for the wipe. You can wipe everything to NULL or some magic number like 0xcacacaca (as does Debug build on Windows).
Jim Dempsey

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