Skip to content

Commit d964abd

Browse files
committed
Fix issues with simulation id and models not running properly. Many loose ends to investigate
1 parent da65ff7 commit d964abd

1 file changed

Lines changed: 59 additions & 60 deletions

File tree

src/run.jl

Lines changed: 59 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -453,77 +453,76 @@ function run_node_multiscale!(
453453
node_ratio = node.timestep / Day(1)
454454

455455
# Check if the model needs to run this timestep
456-
if (1 + (i-1) % node_ratio) != node_ratio
456+
if (1 + (i - 1) % node_ratio) != node_ratio
457457

458458
# TODO : This does prevent the node form being updated by two different parents but probably should be changed
459-
if any([p.simulation_id[1] >= node.simulation_id[1] for p in node.parent])
459+
if any([p.simulation_id[1] > node.simulation_id[1] for p in node.parent])
460460
node.simulation_id[1] += 1
461461
end
462-
return nothing
463-
end
464-
465-
# run!(status(object), dependency_node, meteo, constants, extra)
466-
# Check if all the parents have been called before the child:
467-
if !AbstractTrees.isroot(node) && any([p.simulation_id[1] <= node.simulation_id[1] for p in node.parent])
468-
# If not, this node should be called via another parent
469-
return nothing
470-
end
462+
else
471463

472-
node_statuses = status(object)[node.scale] # Get the status of the nodes at the current scale
473-
models_at_scale = models[node.scale]
464+
# run!(status(object), dependency_node, meteo, constants, extra)
465+
# Check if all the parents have been called before the child:
466+
if !AbstractTrees.isroot(node) && any([p.simulation_id[1] <= node.simulation_id[1] for p in node.parent])
467+
# If not, this node should be called via another parent
468+
return nothing
469+
end
474470

475-
# TODO : is empty check should be pre simulation
476-
if isnothing(node.timestep_mapping_data) || isempty(node.timestep_mapping_data)
477-
# Samuel : this is the happy path, no further timestep mapping checks needed
471+
node_statuses = status(object)[node.scale] # Get the status of the nodes at the current scale
472+
models_at_scale = models[node.scale]
478473

479-
for st in node_statuses # for each node status at the current scale (potentially in parallel over nodes)
480-
# Actual call to the model:
481-
run!(node.value, models_at_scale, st, meteo, constants, extra)
482-
end
483-
node.simulation_id[1] += 1 # increment the simulation id, to remember that the model has been called already
474+
# TODO : is empty check should be pre simulation
475+
if isnothing(node.timestep_mapping_data) || isempty(node.timestep_mapping_data)
476+
# Samuel : this is the happy path, no further timestep mapping checks needed
484477

485-
# Recursively visit the children (soft dependencies only, hard dependencies are handled by the model itself):
486-
for child in node.children
487-
#! check if we can run this safely in a @floop loop. I would say no,
488-
#! because we are running a parallel computation above already, modifying the node.simulation_id,
489-
#! which is not thread-safe yet.
490-
run_node_multiscale!(object, child, i, models, meteo, constants, extra, check, executor)
491-
end
492-
else
493-
# we have a child with a different timestep than the parent,
494-
# which requires accumulation/reduce and running only some of the time
495-
496-
for st in node_statuses
497-
run!(node.value, models_at_scale, st, meteo, constants, extra)
498-
# TODO do the accumulation
499-
# then write into the child's status if need be ?
500-
for tmst in node.timestep_mapping_data
501-
ratio = Int(tmst.node_to.timestep / node.timestep)
502-
# TODO assert etc.
503-
# do the accumulation for each variable
504-
accumulation_index = 1 + ((i-1)%ratio)
505-
tmst.mapping_data[node_id(st.node)][accumulation_index] = st[tmst.variable_from]
506-
507-
# if we have completed a *full* cycle, then presumably we need to write out the value to
508-
# the mapped model
509-
# A full cycle isn't just the ratio to the parent, it's the ratio to the finest-grained timestep
510-
if accumulation_index == ratio
511-
node_statuses_to = status(object)[tmst.node_to.scale]
512-
513-
# TODO : INCORRECT in a scale with multiple mtg nodes
514-
for st_to in node_statuses_to
515-
# TODO might be able to catch mapping_function type incompatibility errors and make them clearer
516-
st_to[tmst.variable_to] = tmst.mapping_function(tmst.mapping_data[node_id(st.node)])
478+
for st in node_statuses # for each node status at the current scale (potentially in parallel over nodes)
479+
# Actual call to the model:
480+
run!(node.value, models_at_scale, st, meteo, constants, extra)
481+
end
482+
node.simulation_id[1] += 1 # increment the simulation id, to remember that the model has been called already
483+
484+
# Recursively visit the children (soft dependencies only, hard dependencies are handled by the model itself):
485+
for child in node.children
486+
#! check if we can run this safely in a @floop loop. I would say no,
487+
#! because we are running a parallel computation above already, modifying the node.simulation_id,
488+
#! which is not thread-safe yet.
489+
run_node_multiscale!(object, child, i, models, meteo, constants, extra, check, executor)
490+
end
491+
else
492+
# we have a child with a different timestep than the parent,
493+
# which requires accumulation/reduce and running only some of the time
494+
495+
for st in node_statuses
496+
run!(node.value, models_at_scale, st, meteo, constants, extra)
497+
# TODO do the accumulation
498+
# then write into the child's status if need be ?
499+
for tmst in node.timestep_mapping_data
500+
ratio = Int(tmst.node_to.timestep / node.timestep)
501+
# TODO assert etc. This is all assuming the ratio is an integer, whereas it can be, like 1/7
502+
# do the accumulation for each variable
503+
index = Int(i*Day(1) / node.timestep)
504+
accumulation_index = 1 + ((index - 1) % ratio)
505+
tmst.mapping_data[node_id(st.node)][accumulation_index] = st[tmst.variable_from]
506+
507+
# if we have completed a *full* cycle, then presumably we need to write out the value to
508+
# the mapped model
509+
# A full cycle isn't just the ratio to the parent, it's the ratio to the finest-grained timestep
510+
if accumulation_index == ratio
511+
node_statuses_to = status(object)[tmst.node_to.scale]
512+
513+
# TODO : INCORRECT in a scale with multiple mtg nodes
514+
for st_to in node_statuses_to
515+
# TODO might be able to catch mapping_function type incompatibility errors and make them clearer
516+
st_to[tmst.variable_to] = tmst.mapping_function(tmst.mapping_data[node_id(st.node)])
517+
end
517518
end
518519
end
519-
end
520-
end
521-
522-
node.simulation_id[1] += 1
520+
end
523521

524-
for child in node.children
525-
526-
run_node_multiscale!(object, child, i, models, meteo, constants, extra, check, executor)
522+
node.simulation_id[1] += 1
527523
end
528524
end
525+
for child in node.children
526+
run_node_multiscale!(object, child, i, models, meteo, constants, extra, check, executor)
527+
end
529528
end

0 commit comments

Comments
 (0)