Make a variable as a global variable within a function

Hi you all,
Probably the first question and example are too poor to understand my case.
I wrote my situation and what I wanna do in detail below:

Briefly speaking, I wanna save specific variables annotated by a macro (namely, @log).
More specifically, it is related to logging data in the use of DifferentialEquations.jl (abbrev.: DiffEq).

In DiffEq, I usually write a in-place DE (differential equation) like:

function sub_dynamics1!(dx, x, p, t)
    dx .= -1*x  # an example dynamics
end
function sub_dynamics2!(dx, x, p, t)
    dx .= -2*x  # an example dynamics
end

For nested systems, ODE sometimes calls subsystems’ ODE like:

function dynamics!(dx, x, p, t)
    sub_dynamics1!(dx.sub1, x.sub1, p.sub1, t)
    sub_dynamics2!(dx.sub2, x.sub2, p.sub2, t)
end

Note that the above “dot-access” (I mean, for example, dx.sub1) is possible via ComponentArrays.jl.

Now, I’d like to add a macro @log to indicate that the variable will be saved. For example, sub_dyanmics1! is changed as

function sub_dynamics1!(dx, x, p, t)
    @log x  # will be saved
    dx .= -1*x
end

This idea is based on SimulationLogs.jl. However, as discussed before, SimulationLogs.jl saves data “after simulation”.
This may be undesirable when the update of a simulation parameter (namely, p) occurs in stochastic sense. Also, I doubt that it works properly in the setting of thread-based parallel simulation.

So I wanna make (possibly some) macros, namely @log and @LOG, the former is for annotating saved variables and the latter is to transform dynamics! into a new function that contains a dictionary (which will contain variables annotated by @log).

I tested this functionality for some simple examples. The difficulty is, however, when a function (dynamics!) calls subsystems’ dynamics (sub_dynamics1! and sub_dynamics2!) and @log is added to sub_dynamics1! and sub_dynamics2!.

Here are my ideas:

  1. (probably the best) Make a dictionary, which acts as a global variable only in dynamics! (that is, it is merely a local variable outside dynamics! and accessible in sub_dynamics1! and sub_dynamics2!).
  2. (probably safe in terms of thread-based parallel simulation) Make some dictionaries, each of them acts as a global variable only in each thread, and add data to the thread-safe dictionaries.

Do you guys have solutions to my idea? Or, do you have a better idea?
Feel free to leave comments :slight_smile: