You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Integrate loading of dynamic code with develop branch after STATE data PR Devstate #119
Enables the end user to include a python file that defines functions that can be used inside the model timestep to modify elements of the STATE data model. (see Testing below).
Allows modelers to modify runtime state and/or specific parameters of the model with project specific python code.
Uses "magic" name import, i.e., given hdf5 file river_model.h5, automatically load code contained in local directory named river_model.py.
Provides an easy to implement example (see Testing below) of how to modify the withdrawal of a river segment at every time step with a short python function residing in the same directory as the model h5 file..
Establishes a set of functions that when supported allow several points of custom access during model execution.
Ex.: state_step_hydr() can modify STATE variables during the timestep execution of the HYDR/_hydr_ functions. See Dynamic Modifiers below.
Provides code that integrates modifications to the STATE variable during each timestep in the HYDR/_hydr_ function by calling state_step_hydr() if defined in the model run directory.
Provides a potential avenue for data modifications by special actions code. (See also SPEC-ACTIONS in hsp2 #90)
Limitations: The technique that is being used to dynamically import python code for runtime incurs an overhead because it forces recompile for any @njit function that supports the code. For example, using the dynjamic code in_hydr_() shown below adds about 6-8 seconds for each and every model run, regardless of whether or not the dynamic code has been changed. Perhaps there is a better way?
Tasks
Develop runtime loadable function for Dynamic Loading of Code (below)
Outline Supported Functions and naming conventions (init, step, etc)
Outline data model for enabling/disabling
Integrate dynamic loader into hsp2
Do pull request
Supported Functions & Special Variables
General supported functions are:
pre_step(): things that happen at the beginning of the code loop, after normal data loading has occurred
step(): things that happen during the computational portion of a model time-step
post_step(): things that happen after a timestep is completed (ex: logging)
get_ix: a special function to retrieve local variable names with an implied path to the current domain )
Naming convention:
state_pre_step_[operation]()
state_step_[operation]()
state_post_step_[operation]()
Special Variables:
state: this is a multi-typed dict (not numba compatible) that is used to pass all the other Dicts related to state
state['domain']: the current path to the /STATE/[operation]/[segment], this gets reset each time we switch segment or operation
state_paths: this is the path that contains pointers from the full hdf5 paths for state variables to the corresponding unique integer key for the state_ix Dict.
state_paths['domain'] = special entry in state_paths that contains the integer key for the current /STATE/[operation]/[segment]. This permits
hydr_ix: this is created automatically to hold shortcuts to HYDR variables for the current domain for brevity and fast code exec.
Minimal Code Support:
provide state dictionary in main.py - sets up basic shared numba Dict entries to pass to routines (includes state_paths, state_ix, dict_ix, ts_ix, operation, segment, ...)
Pass state_ix, dict_ix, ts_ix, state_info, state_paths as arguments when calling operation numba function
Add state_step_[operation] call if defined
Set state prior to calling state_step_[operation] (optional, performance) Provide _get_ix function for variables that wish to access state variable changes in the loop
Dynamic Loading of Code
Code implements methods to customize state variables during time steps:
Individual functions, if defined will be called as: state_step_hydr(model_exec_list, op_tokens, state_ix, dict_ix, ts_ix, hydr_ix, step)
importsysfromnumbaimportint8, float32, njit, types, typed# import the typesprint("Loaded a set of HSP2 code!")
@njitdefstate_step_hydr(state_info, state_paths, state_ix, dict_ix, ts_ix, hydr_ix, step):
if (step<=1):
print("Custom state_step_hydr() called for ", state_info['segment'])
print("operation", state_info['operation'])
print("state at start", state_ix)
print("domain info", state_info)
print("state_paths", state_paths)
# Do a simple withdrawal of 10 MGGD from R001if (state_info['segment'] =='R001') and (state_info['activity'] =='HYDR'):
state_ix[hydr_ix['O1']] =10.0*1.547# Route point source return from segment R001 demand to R005 inflow (IVOL)# For demo purposes this will only use the last state_ix value for R001 demand# Realistic approach would run all segments simultaneously or use value from ts_ix (ts_ix loading TBD)if (state_info['segment'] =='R005') and (state_info['activity'] =='HYDR'):
state_ix[hydr_ix['IVOL']] +=0.85*state_ix[state_paths['/STATE/RCHRES_R001/HYDR/O1']]
if (step<=1):
print("IVOL after", state_ix[hydr_ix['IVOL']])
return
The text was updated successfully, but these errors were encountered:
Overview (RFC)
This issue provides background information for pull request #119 which hs now been merged.
This PR contains code that:
develop
branch after STATE data PR Devstate #119river_model.h5
, automatically load code contained in local directory namedriver_model.py
.h5
file..state_step_hydr()
can modify STATE variables during the timestep execution of theHYDR/_hydr_
functions. See Dynamic Modifiers below.HYDR/_hydr_
function by callingstate_step_hydr()
if defined in the model run directory.@njit
function that supports the code. For example, using the dynjamic code in_hydr_()
shown below adds about 6-8 seconds for each and every model run, regardless of whether or not the dynamic code has been changed. Perhaps there is a better way?Tasks
Supported Functions & Special Variables
pre_step()
: things that happen at the beginning of the code loop, after normal data loading has occurredstep()
: things that happen during the computational portion of a model time-stepstate_step_hydr(state_ix, dict_ix, ts_ix, hydr_ix, step)
post_step()
: things that happen after a timestep is completed (ex: logging)get_ix
: a special function to retrieve local variable names with an implied path to the current domain )state_pre_step_[operation]()
state_step_[operation]()
state_post_step_[operation]()
state
: this is a multi-typed dict (not numba compatible) that is used to pass all the other Dicts related to statestate['domain']
: the current path to the/STATE/[operation]/[segment]
, this gets reset each time we switch segment or operationstate_paths
: this is the path that contains pointers from the full hdf5 paths for state variables to the corresponding unique integer key for thestate_ix
Dict.state_paths['domain']
= special entry instate_paths
that contains the integer key for the current/STATE/[operation]/[segment]
. This permitshydr_ix
: this is created automatically to hold shortcuts to HYDR variables for the current domain for brevity and fast code exec.state
dictionary inmain.py
- sets up basic sharednumba Dict
entries to pass to routines (includesstate_paths
,state_ix
,dict_ix
,ts_ix
,operation
,segment
, ...)state
as argument to operation function,def hydr(io_manager, siminfo, uci, ts, ftables, state):
state_ix, dict_ix, ts_ix, state_info, state_paths
as arguments to operationnumba
functionstate
becausenumba
cannot take mixed type Dictdef _hydr_(ui, ts, COLIND, OUTDGT, rowsFT, funct, Olabels, OVOLlabels, state_info, state_paths, state_ix, dict_ix, ts_ix)
state_ix, dict_ix, ts_ix, state_info, state_paths
as arguments when calling operationnumba
functionstate_step_[operation]
call if definedstate_step_[operation]
(optional, performance) Provide_get_ix
function for variables that wish to access state variable changes in the loopDynamic Loading of Code
state_step_hydr(model_exec_list, op_tokens, state_ix, dict_ix, ts_ix, hydr_ix, step)
Testing
statey
test10
test10.py
, editing the functionstate_step_hydr()
to explore interacting with state._hydr_()
has support implemented for STATE functions.IVOL
andOUTDGT
modifications are passed fromstate_ix
back into_hydr_
Code 1: Set a dynamic withdrawal in RCHRES R001. See also https://github.com/respec/HSPsquared/blob/99c0e629d88d0665bb45f10250691b2f0679967e/tests/test10/HSP2results/test10.py
The text was updated successfully, but these errors were encountered: