I have a potential solution that appears to work. The principle is relatively simple
- Create a dictionary (or any ‘map’) that maps the task ID to an
ODEProblemascribed to that specific task. TheODEProblemisdeepcopyd once in the beginning. - In the
prob_func, get the task ID usingcurrent_task(),deepcopythe originalODEProblemif it does not exist, otherwise mutate it.
The code looks like this, with some locks in place to prevent multiple tasks/threads writing to the dictionary at the same time:
#/ Create a dictionary to store task-local problems
tproblems = Dict{Task, ODEProblem}()
tlock = Threads.ReentrantLock()
function set_interactions(prob, k, nrepeats)
#~ Update prob by setting new interactions and initial conditions
tid = current_task()
if !haskey(tproblems, tid)
Threads.lock(tlock)
tproblems[tid] = deepcopy(prob)
Threads.unlock(tlock)
end
lprob = tproblems[tid]
interactionsetter(lprob, amatrices[k])
statesetter(lprob, rand(S))
return lprob
end
with the statesetter and interactionsetter as above. This seems to work and indeed uses as much memory as the initial set of deepcopy’s, but nothing more.
If this is not the way to go I’d be happy to learn how I should otherwise implement this.