in lib/ramble/ramble/experiment_set.py [0:0]
def _ingest_experiments(self, die_on_validate_error=True):
"""Ingest experiments based on the current context.
Merge all contexts, and render individual experiments. Track these
experiments within this experiment set.
Args:
None
Returns:
None
"""
no_var_contexts = [
self._contexts.global_conf,
self._contexts.base,
self._contexts.required,
]
final_context = ramble.context.Context()
for context in self._contexts:
final_context.merge_context(self._context[context])
for context in self._contexts:
if context not in no_var_contexts:
var_name = f"{context.name}_name"
if var_name not in final_context.variables:
final_context.variables[var_name] = self._context[context].context_name
# Set namespaces
final_context.variables[self.keywords.application_namespace] = self.application_namespace
final_context.variables[self.keywords.workload_namespace] = self.workload_namespace
final_context.variables[self.keywords.experiment_namespace] = self.experiment_namespace
# Set required variables for directories.
final_context.variables[self.keywords.application_run_dir] = os.path.join(
self._workspace.experiment_dir, Expander.expansion_str(self.keywords.application_name)
)
final_context.variables[self.keywords.application_input_dir] = os.path.join(
self._workspace.input_dir, Expander.expansion_str(self.keywords.application_name)
)
final_context.variables[self.keywords.workload_run_dir] = os.path.join(
Expander.expansion_str(self.keywords.application_run_dir),
Expander.expansion_str(self.keywords.workload_name),
)
final_context.variables[self.keywords.workload_input_dir] = os.path.join(
Expander.expansion_str(self.keywords.application_input_dir),
Expander.expansion_str(self.keywords.workload_name),
)
final_context.variables[self.keywords.license_input_dir] = os.path.join(
self._workspace.shared_license_dir,
Expander.expansion_str(self.keywords.application_name),
)
final_context.variables[self.keywords.experiment_run_dir] = os.path.join(
Expander.expansion_str(self.keywords.workload_run_dir),
Expander.expansion_str(self.keywords.experiment_name),
)
experiment_template_name = final_context.variables[self.keywords.experiment_name]
renderer = ramble.renderer.Renderer()
render_group = ramble.renderer.RenderGroup("experiment", "create")
render_group.variables = final_context.variables
render_group.zips = final_context.zips
render_group.matrices = final_context.matrices
render_group.n_repeats = final_context.n_repeats
render_group.used_variables = set()
excluded_experiments = set()
if final_context.exclude:
exclude_group = ramble.renderer.RenderGroup("experiment", "exclude")
exclude_group.copy_contents(render_group)
perform_explicit_exclude = exclude_group.from_dict(
experiment_template_name, final_context.exclude
)
if perform_explicit_exclude:
for exclude_exp_vars, _ in renderer.render_objects(
exclude_group, ignore_used=False
):
expander = ramble.expander.Expander(exclude_exp_vars, self)
self._compute_mpi_vars(expander, exclude_exp_vars)
exclude_exp_name = expander.expand_var(
experiment_template_name, allow_passthrough=False
)
excluded_experiments.add(exclude_exp_name)
exclude_where = []
if final_context.exclude:
if namespace.where in final_context.exclude:
exclude_where = final_context.exclude[namespace.where]
tracking_group = ramble.renderer.RenderGroup("experiment", "create")
tracking_group.variables = final_context.variables
tracking_group.zips = final_context.zips
tracking_group.matrices = final_context.matrices
tracking_group.n_repeats = final_context.n_repeats
tracking_group.used_variables = set()
used_variables = set()
for tracking_vars, repeats in renderer.render_objects(
tracking_group, exclude_where=exclude_where, ignore_used=False, fatal=False
):
app_inst = self._prepare_experiment(
experiment_template_name,
tracking_vars,
final_context,
repeats,
)
exp_used_variables = app_inst.build_used_variables(self._workspace)
used_variables = used_variables.union(exp_used_variables)
render_group.used_variables = used_variables.copy()
rendered_experiments = set()
for experiment_vars, repeats in renderer.render_objects(
render_group, exclude_where=exclude_where
):
app_inst = self._prepare_experiment(
experiment_template_name,
experiment_vars,
final_context,
repeats,
)
final_exp_name = app_inst.expander.expand_var_name(self.keywords.experiment_name)
final_exp_namespace = app_inst.expander.expand_var_name(
self.keywords.experiment_namespace
)
# Skip explicitly excluded experiments
if final_exp_name not in excluded_experiments:
logger.debug(f" Final name: {final_exp_namespace}")
if final_exp_namespace in rendered_experiments:
left_vars = self.experiments[final_exp_namespace].variables
right_vars = experiment_vars
lkeys = set(left_vars.keys())
rkeys = set(right_vars.keys())
# Determine variables that are only in one of the two experiments
left_unique_vars = lkeys - rkeys
right_unique_vars = rkeys - lkeys
common_vars = lkeys & rkeys
logger.warn(f"Two experiments are defined with the name {final_exp_namespace}")
# Print warnings about experiment differences
if left_unique_vars:
logger.warn("Variables unique to previously defined experiment:")
for var in left_unique_vars:
logger.warn(f" - {var}")
if right_unique_vars:
logger.warn("Variables unique to newly defined experiment:")
for var in right_unique_vars:
logger.warn(f" - {var}")
print_header = True
for var in common_vars:
if left_vars[var] != right_vars[var]:
if print_header:
logger.warn("Variable differences between experiment definitions:")
print_header = False
diff = {"previous": left_vars[var], "new": right_vars[var]}
logger.warn(f" - {var}: {diff}")
logger.die(f"Experiment {final_exp_namespace} is not unique.")
try:
app_inst.validate_experiment(
warn_validation=True, die_on_validate_error=die_on_validate_error
)
except ramble.keywords.RambleKeywordError as e:
if die_on_validate_error:
raise RambleVariableDefinitionError(
f"In experiment {final_exp_namespace}: {e}"
)
pass
rendered_experiments.add(final_exp_namespace)
self.experiments[final_exp_namespace] = app_inst
self.experiment_order.append(final_exp_namespace)