Background
PR #674 added average_scenario_creator to examples/farmer/farmer.py and examples/netdes/netdes.py for --*-try-jensens-first. A follow-up branch (DLWoodruff/mpi-sppy-1#feasible-xhat-creator) is adding a sibling feasible_xhat_creator convention (used by downstream tools that need a candidate xhat feasible to pin in every real scenario subproblem).
The cumulative effect is that farmer.py -- the example most first-time users read -- is accumulating helpers that those users do not need. netdes.py is heading the same direction.
Proposal
Adopt a convention: example-specific auxiliary functions that are not part of the core scenario-creator interface live in examples/<model>/<model>_auxiliary.py. The introductory example file (farmer.py, netdes.py, sslp.py, ...) stays focused on scenario_creator, scenario_names_creator, kw_creator, inparser_adder, sample_tree_scen_creator, scenario_denouement -- the functions a user has to read to understand how the model plugs into mpi-sppy.
Functions to migrate:
average_scenario_creator (currently in farmer.py and netdes.py)
feasible_xhat_creator (the prototype branch already lands these directly in examples/netdes/netdes_auxiliary.py and examples/sslp/sslp_auxiliary.py, so the netdes copy is already correctly placed there; only the farmer copy needs to move out of farmer.py)
- The
_scenario_data / _build_model underscore-helper split in netdes.py exists to support average_scenario_creator. Once average_scenario_creator moves, those helpers can either move with it or stay (depending on whether scenario_creator itself benefits from the split).
Wiring
mpisppy/cylinders/_jensens_mixin.py and mpisppy/generic/decomp.py:64 look up average_scenario_creator via getattr(module, ...). Either:
- The auxiliary module re-exports
average_scenario_creator so callers keep doing getattr(model_module, ...), or
- The lookup falls back to
<model>_auxiliary.py's namespace.
(1) is less invasive. (2) is more discoverable but adds a convention to the wiring layer.
Migration cost
mpisppy/tests/test_jensens.py calls farmer.average_scenario_creator(...) directly several times -- those references would need to be updated to import from farmer_auxiliary (or the test could import via the same getattr lookup the cylinders use). Same for any run_all.py entries that thread the function through CLI flags (those go through the model module by name, so no change needed there).
Prototype reference
The pattern is in place on the feasible-xhat-creator branch on a fork:
examples/netdes/netdes_auxiliary.py
examples/sslp/sslp_auxiliary.py
mpisppy/utils/xhat_helpers.py (shared helper called from the auxiliaries)
Why now
Concern raised on that branch: "I am already worried that we have cluttered the farmer example that many first-time users need by adding the average data function that most new users don't need and we are now making it worse."
Background
PR #674 added
average_scenario_creatortoexamples/farmer/farmer.pyandexamples/netdes/netdes.pyfor--*-try-jensens-first. A follow-up branch (DLWoodruff/mpi-sppy-1#feasible-xhat-creator) is adding a siblingfeasible_xhat_creatorconvention (used by downstream tools that need a candidate xhat feasible to pin in every real scenario subproblem).The cumulative effect is that
farmer.py-- the example most first-time users read -- is accumulating helpers that those users do not need.netdes.pyis heading the same direction.Proposal
Adopt a convention: example-specific auxiliary functions that are not part of the core scenario-creator interface live in
examples/<model>/<model>_auxiliary.py. The introductory example file (farmer.py,netdes.py,sslp.py, ...) stays focused onscenario_creator,scenario_names_creator,kw_creator,inparser_adder,sample_tree_scen_creator,scenario_denouement-- the functions a user has to read to understand how the model plugs into mpi-sppy.Functions to migrate:
average_scenario_creator(currently infarmer.pyandnetdes.py)feasible_xhat_creator(the prototype branch already lands these directly inexamples/netdes/netdes_auxiliary.pyandexamples/sslp/sslp_auxiliary.py, so the netdes copy is already correctly placed there; only the farmer copy needs to move out offarmer.py)_scenario_data/_build_modelunderscore-helper split innetdes.pyexists to supportaverage_scenario_creator. Onceaverage_scenario_creatormoves, those helpers can either move with it or stay (depending on whetherscenario_creatoritself benefits from the split).Wiring
mpisppy/cylinders/_jensens_mixin.pyandmpisppy/generic/decomp.py:64look upaverage_scenario_creatorviagetattr(module, ...). Either:average_scenario_creatorso callers keep doinggetattr(model_module, ...), or<model>_auxiliary.py's namespace.(1) is less invasive. (2) is more discoverable but adds a convention to the wiring layer.
Migration cost
mpisppy/tests/test_jensens.pycallsfarmer.average_scenario_creator(...)directly several times -- those references would need to be updated to import fromfarmer_auxiliary(or the test could import via the samegetattrlookup the cylinders use). Same for anyrun_all.pyentries that thread the function through CLI flags (those go through the model module by name, so no change needed there).Prototype reference
The pattern is in place on the
feasible-xhat-creatorbranch on a fork:examples/netdes/netdes_auxiliary.pyexamples/sslp/sslp_auxiliary.pympisppy/utils/xhat_helpers.py(shared helper called from the auxiliaries)Why now
Concern raised on that branch: "I am already worried that we have cluttered the farmer example that many first-time users need by adding the average data function that most new users don't need and we are now making it worse."