Clear a variable in fortran subroutine

Click For Summary

Discussion Overview

The discussion revolves around the challenge of clearing a variable within a Fortran subroutine from a calling function, particularly when the subroutine contains persistent or static variables. Participants explore various strategies to achieve this without modifying the original subroutine, which is being unit tested.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Experimental/applied

Main Points Raised

  • One participant describes the need to clear a variable in a Fortran subroutine similar to how it can be done in MATLAB using a loop and a clear function.
  • Another participant suggests adding a logical argument to the subroutine to control its behavior, or creating a module to manage the variables and reset them.
  • A participant expresses concern about whether a module can reset variables that are only referenced in the subroutine, given that they cannot modify the subroutine itself.
  • There is a proposal to implement a module with a reset subroutine that sets a variable to zero, but questions arise about the scope and persistence of variables across function calls.
  • One participant notes that they cannot modify the subroutine and must keep a declaration that initializes a variable on each call, complicating the reset process.
  • Another participant emphasizes the importance of keeping the variable's state between calls and suggests that the reset subroutine should be able to affect the variable used in the main subroutine.
  • A later reply discusses the possibility of using a global common block to manage persistent variables, but also mentions the complexity of directly manipulating memory addresses if that is not an option.
  • Finally, a participant acknowledges the need to run unit tests under various use cases to gather profiling results, indicating an ongoing exploration of the problem.

Areas of Agreement / Disagreement

Participants express differing views on the best approach to reset variables in a subroutine without modifying it. There is no consensus on a single solution, and multiple competing ideas are presented throughout the discussion.

Contextual Notes

Limitations include the inability to modify the original subroutine, which restricts the options available for resetting variables. Additionally, there are unresolved questions regarding the scope of variables and how they interact across different subroutines.

Somefantastik
Messages
226
Reaction score
0
Hello,

I am trying to figure out how to clear a variable inside a subroutine from a calling function. The variable in the subroutine acts as a persistent(MATLAB) or static(C), but once in so many calls I want it to be reset to empty as if the subroutine is being called for the first time.

I can do this in MATLAB by calling the subroutine in a for loop. On the kth run, clear functions, call subroutine. The subroutine is now called with persistent variables cleared:

function y = foo(a)
n = 6;
k = 3;
for ii = 1:n
if ii == k
clear functions​
end
x(ii) = subfoo(a)​
end

Any help would be appreciated,

Candice
 
Technology news on Phys.org
Go ahead and post your Fortran code to get a better understanding of what you mean and are trying to do.

Other than that, you could write your function in a way that takes an additional argument, say, of logical type...if it is set to true, the function behaves as if it was the very first time is being called; if it is false, it does not.

Alternately, you could write a module with its set of variables and a couple of functions, one you call to perform something, the other one to reset variables to their initial values.
 
Hi gsal, thank you for your response.

Unfortunately, I cannot post my code, and I cannot modify the subroutine in any way (I am unit testing it).

If I write a module with its set of variables to reset to initial values, can I call that from my parent function? Or are those variable names only pointing to the correct place in memory while in the subroutine? I cannot reset the variables inside my subroutine as I cannot modify my subroutine.
 
I was thinking something like this
Code:
module bla
integer :: b = 0
contains
subroutine bla_reset()
   b = 0
end subroutine bla_reset()
function bla_do()
   b = b + 3
   return b
end function bla_do()
end module bla
Then, in reference to your MATLAB code that you posted above, instead of "clear functions" you do "call bla_reset()" and instead of "x(ii) = subfoo(a)" you do "x(ii) = bla_do(a).
 
gsal said:
I was thinking something like this
Code:
module bla
integer :: b = 0
contains
subroutine bla_reset()
   b = 0
end subroutine bla_reset()
function bla_do()
   b = b + 3
   return b
end function bla_do()
end module bla
Then, in reference to your MATLAB code that you posted above, instead of "clear functions" you do "call bla_reset()" and instead of "x(ii) = subfoo(a)" you do "x(ii) = bla_do(a).

will this work if the variable b belongs solely to (and is not returned by) bla_do? In my subroutine (bla_do), it is declared equal to 1. Like this:
Code:
module bla
integer  b 
contains
subroutine bla_reset()
   b = 1
end subroutine bla_reset()
function bla_do()
integer  b \1\
   b = b + 3
end function bla_do()
end module bla

I'm learning on-the-fly how fortran's "workspace" (for lack of a better term) is available between functions.
 
I would remove the integer declaration inside bla_do...otherwise, it looks like you keep re-initailizing it every call...instead, let it keep increasing by 3 every time you call ...then, once in a while, you call bla_reset...

...if I understand what you are trying to do
 
Because I am testing bla_do(), I can't modify it. So I can't remove the declaration in the beginning. But I am certain that the way the fortran is set up in my real code, that variable is declared equal to 1 only on the first iteration ; thereafter it takes on the last value when the function was called previously.

My intention, is to (at some point inside a forloop that calls bla_do) reset that variable so when bla_do() is called, it acts as it would the first time it is called. It's a weird thing to need; it is an artifact of testing bla_do rather than developing.

Code:
module bla
integer  b
for i = 1:100
if i = 50
   CALL bla_reset() //reset b back to 1 at iteration 50
endif
CALL bla_do() // do whatever blah does
end module bla

subroutine bla_reset()
   b = 1
end subroutine bla_reset()
subroutine  bla_do()
integer  b \1\ //this syntax should set b = 1 only on first call; otherwise b retains value from last call (or hopefully from when it is set to 1 in bla_reset)
   b = b + 3
end subroutine bla_do()

I'm curious that b can be reset in the separate subroutine bla_reset and it is felt by bla_do, even when bla_reset and bla_do don't have b as input or output arguments.
 
This thing about bla_reset and bla_do not needing to declare b, yet being aware of it, is a benefit of using modules...but I see in your latest post that you have messed things up :-(

First, you have kicked bla_reset and bla_do out of the module...you should go back and review how I did it...inside the module but after the "contains" keyword.

Also, a module is not a main program...you should take the code you have in the module (latest post) and make it a separate main procedure, like
Code:
module bla
.
.
.
end module bla

program main
   use bla
   for i = 1:100
   if i = 50
      CALL bla_reset() //reset b back to 1 at iteration 50
   endif
   CALL bla_do() // do whatever bla does
end program main
 
Ah, I see. Unfortunately bla_do() is a subroutine, and I can't touch it (I must view it as a black box), so I can't change it into a module. I think because of this problem, I can't use the method you are suggesting.
 
  • #10
If the persistent variables are in a global common block, you can easily include them and clear them using another subroutine. Otherwise, you may have to get the address of the persistent variables by finding the addresses in the binary or compiler outputs and write a subroutine that pokes initial values into those addresses. The first situation is not a difficult task for any programmer, but the second situation will require a more expert programmer. I'm afraid that your code is probably the second situation.

You may be better off with a script or program that will terminate the program under test and restart it clean. That is the best way to do a series of formal tests anyway.
 
  • #11
Hi FactChecker; thank you for your response. Yes it now seems that I will run the unit tests under several use-cases and try to merge the profiling results.
 

Similar threads

  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 11 ·
Replies
11
Views
2K
  • · Replies 12 ·
Replies
12
Views
4K
  • · Replies 4 ·
Replies
4
Views
4K
  • · Replies 4 ·
Replies
4
Views
11K
  • · Replies 1 ·
Replies
1
Views
3K