From 625232dbf4f6b5059069f22ffa33020c7f22871f Mon Sep 17 00:00:00 2001 From: Yonggang Yu Date: Wed, 8 Jul 2026 11:09:52 -0600 Subject: [PATCH 1/2] Add models[model_component]['ensemble_num_chunks'] to dict before templating suite_str for flow.cylc, in workflow case: {% for i in range( 1, models[model_component]['ensemble_num_chunks'] + 1 ) %} [[RunJediEdaControlPertExecutable_chunk{{i}}-{{model_component}}]] {% endfor %} --- .../prepare_config_and_suite.py | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/src/swell/deployment/prepare_config_and_suite/prepare_config_and_suite.py b/src/swell/deployment/prepare_config_and_suite/prepare_config_and_suite.py index 69987bf5f..1eef13165 100644 --- a/src/swell/deployment/prepare_config_and_suite/prepare_config_and_suite.py +++ b/src/swell/deployment/prepare_config_and_suite/prepare_config_and_suite.py @@ -457,6 +457,7 @@ def ask_questions_and_configure_suite(self) -> Tuple[dict, dict]: # At this point the user should have provided the model components answer. Check that it is # in the experiment dictionary and retrieve the response + render_dict = copy.deepcopy(self.experiment_dict) if 'model_components' not in self.experiment_dict: self.logger.abort('The model components question has not been answered.') @@ -473,6 +474,39 @@ def ask_questions_and_configure_suite(self) -> Tuple[dict, dict]: # Ask the question self.ask_a_question(model_dict, question_key, model) + # pass special model-dep task questions/variables to render_dict + # for suite_str (jinja2) in step 7. + if model_dict[question_key]['question_type'] == 'task': + + ensemble_list = ['ensemble_'+s for s in ['num_members', 'num_chunks']] + if question_key in ensemble_list: + + # a. Ensure the 'models' list exists + if 'models' not in render_dict: + render_dict['models'] = [] + + # b. Check if this model is already in our list + model_found = False + for m in render_dict['models']: + if model in m: + # c. If found, incrementally add the new key! + default_val = model_dict[question_key]['default_value'] + m[model][question_key] = default_val + model_found = True + break + + # d. If not found, add the model to the list for the first time + if not model_found: + default_val = model_dict[question_key]['default_value'] + render_dict['models'].append({ + model: { + question_key: default_val + } + }) + + # debug + # print(f'render_dict = {render_dict}') + # 7. Perform a more exhaustive resolving of suite file templates # -------------------------------------------------------------- # Note that we reset the suite file to avoid templates having been left unresolved @@ -480,9 +514,14 @@ def ask_questions_and_configure_suite(self) -> Tuple[dict, dict]: # of templates because there are things related to scheduling that are not yet able to be # resolved. In the future it might be good to bring some of that information into the # sphere of suite questions but that requires some careful thought so as not to overload - # the user with questions. - suite_str = template_string_jinja2(self.logger, self.suite_str, self.experiment_dict, - True) + # the user with questions. A few model dep variables are needed to corectly parse tasks, + # e.g., in Eda ControlPert. Hence we use a render_dict for jinja2 here, only to parse + # the for loop around model task in .cycl file, e.g., + # {% for i in range( 1, models[model_component]['ensemble_num_chunks'] + 1 ) %} + # [[RunJediEdaControlPertExecutable_chunk{{i}}-{{model_component}}]] + # {% endfor %} + + suite_str = template_string_jinja2(self.logger, self.suite_str, render_dict, True) # 8. Ask the new task questions that do not actually depend on the model # ----------------------------------------------------------------------- From 48de41f7fe36ae6078c362461c3ff118e7670c82 Mon Sep 17 00:00:00 2001 From: Yonggang Yu Date: Thu, 9 Jul 2026 09:33:03 -0600 Subject: [PATCH 2/2] add ensemble_num_chunks to render_dictionary --- src/swell/deployment/create_experiment.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/swell/deployment/create_experiment.py b/src/swell/deployment/create_experiment.py index 46596ce78..2cd3a2924 100644 --- a/src/swell/deployment/create_experiment.py +++ b/src/swell/deployment/create_experiment.py @@ -537,7 +537,8 @@ def prepare_cylc_suite_jinja2( 'dictionary.') # Check if 'ensemble_hofx_strategy' appears anywhere in suite_file - ensemble_list = ['ensemble_'+s for s in ['num_members', 'hofx_strategy', 'hofx_packets']] + ensemble_list = ['ensemble_'+s for s in + ['num_members', 'num_chunks', 'hofx_strategy', 'hofx_packets']] ensemble_list = ensemble_list + ['skip_ensemble_hofx'] for ensemble_aspect in ensemble_list: if ensemble_aspect in suite_file: