Skip to content

Commit 8e0fbf4

Browse files
committed
Resolve simulation output file paths via opp_run -e
Fix issue #10: get_scalars() fails when result files are written to non-default locations because the hardcoded fallback pattern doesn't match the actual configured path. - Add SimulationTask._resolve_output_file_path() that checks the explicit path first, then falls back to opp_run -s -e to query the resolved path from OMNeT++ (supports both direct and opp_env) - Convert SimulationTaskResult file path attributes to lazy properties so opp_run -e is only called when a path is actually accessed - Update optimize.py to set file paths on the task directly instead of passing them via append_args
1 parent 1623993 commit 8e0fbf4

2 files changed

Lines changed: 72 additions & 10 deletions

File tree

opp_repl/simulation/optimize.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,14 @@ def cost_function(parameter_values, simulation_task, expected_result_names, expe
4444
all_parameter_units = [*fixed_parameter_units, *parameter_units]
4545
all_parameter_assignment_args = list(map(lambda name, value, unit: "--" + name + "=" + (unit.format(value) if "{" in unit else str(value) + unit), all_parameter_assignments, all_parameter_values, all_parameter_units))
4646
suffix = "-".join(map(str, all_parameter_values))
47-
output_scalar_file = "results/" + simulation_task.simulation_config.config + "-" + suffix + ".sca"
48-
output_vector_file = "results/" + simulation_task.simulation_config.config + "-" + suffix + ".vec"
49-
append_args = ["--output-scalar-file=" + output_scalar_file, "--output-vector-file=" + output_vector_file, *all_parameter_assignment_args]
50-
simulation_result = simulation_task.run(append_args=append_args, **kwargs)
47+
simulation_task.scalar_file_path = "results/" + simulation_task.simulation_config.config + "-" + suffix + ".sca"
48+
simulation_task.vector_file_path = "results/" + simulation_task.simulation_config.config + "-" + suffix + ".vec"
49+
simulation_result = simulation_task.run(append_args=all_parameter_assignment_args, **kwargs)
5150
if simulation_result.result == "DONE":
5251
working_dir = simulation_task.simulation_config.working_directory
5352
project = simulation_task.simulation_config.simulation_project
54-
scalar_file = project.get_full_path(os.path.join(working_dir, output_scalar_file))
55-
vector_file = project.get_full_path(os.path.join(working_dir, output_vector_file))
53+
scalar_file = project.get_full_path(os.path.join(working_dir, simulation_result.scalar_file_path))
54+
vector_file = project.get_full_path(os.path.join(working_dir, simulation_result.vector_file_path))
5655
result_files = [f for f in [scalar_file, vector_file] if os.path.exists(f)]
5756
result_values = []
5857
for result_name in expected_result_names:

opp_repl/simulation/task.py

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,56 @@ def __init__(self, subprocess_result=None, cancel=False, **kwargs):
122122
self.elapsed_cpu_time = float(match.group(1)) if match else None
123123
self.num_cpu_cycles = int(match.group(2)) if match else None
124124
self.num_cpu_instructions = int(match.group(3)) if match else None
125-
self.stdout_file_path = self.task.stdout_file_path or f"results/{self.task.simulation_config.config}-#{str(self.task.run_number)}.out"
126-
self.eventlog_file_path = self.task.eventlog_file_path or f"results/{self.task.simulation_config.config}-#{str(self.task.run_number)}.elog"
127-
self.scalar_file_path = self.task.scalar_file_path or f"results/{self.task.simulation_config.config}-#{str(self.task.run_number)}.sca"
128-
self.vector_file_path = self.task.vector_file_path or f"results/{self.task.simulation_config.config}-#{str(self.task.run_number)}.vec"
125+
self.stdout_file_path = None
126+
self.eventlog_file_path = None
127+
self.scalar_file_path = None
128+
self.vector_file_path = None
129129
else:
130130
self.last_event_number = None
131131
self.last_simulation_time = None
132132
self.error_message = None
133133
self.error_module = None
134134

135+
@property
136+
def stdout_file_path(self):
137+
if self._stdout_file_path is None:
138+
self._stdout_file_path = self.task._resolve_output_file_path("cmdenv-output-file")
139+
return self._stdout_file_path
140+
141+
@stdout_file_path.setter
142+
def stdout_file_path(self, value):
143+
self._stdout_file_path = value
144+
145+
@property
146+
def eventlog_file_path(self):
147+
if self._eventlog_file_path is None:
148+
self._eventlog_file_path = self.task._resolve_output_file_path("eventlog-file")
149+
return self._eventlog_file_path
150+
151+
@eventlog_file_path.setter
152+
def eventlog_file_path(self, value):
153+
self._eventlog_file_path = value
154+
155+
@property
156+
def scalar_file_path(self):
157+
if self._scalar_file_path is None:
158+
self._scalar_file_path = self.task._resolve_output_file_path("output-scalar-file")
159+
return self._scalar_file_path
160+
161+
@scalar_file_path.setter
162+
def scalar_file_path(self, value):
163+
self._scalar_file_path = value
164+
165+
@property
166+
def vector_file_path(self):
167+
if self._vector_file_path is None:
168+
self._vector_file_path = self.task._resolve_output_file_path("output-vector-file")
169+
return self._vector_file_path
170+
171+
@vector_file_path.setter
172+
def vector_file_path(self, value):
173+
self._vector_file_path = value
174+
135175
def get_error_message(self, complete_error_message=True, **kwargs):
136176
if complete_error_message and self.error_module and self.error_message:
137177
return self.error_message + " -- in module " + self.error_module
@@ -384,6 +424,29 @@ def is_interactive(self):
384424
self.interactive = match is not None
385425
return self.interactive
386426

427+
def _resolve_output_file_path(self, option_name):
428+
file_path_attr = {
429+
"cmdenv-output-file": "stdout_file_path",
430+
"eventlog-file": "eventlog_file_path",
431+
"output-scalar-file": "scalar_file_path",
432+
"output-vector-file": "vector_file_path",
433+
}[option_name]
434+
explicit_path = getattr(self, file_path_attr)
435+
if explicit_path:
436+
return explicit_path
437+
simulation_config = self.simulation_config
438+
simulation_project = simulation_config.simulation_project
439+
executable = simulation_project.get_executable()
440+
default_args = simulation_project.get_default_args()
441+
inifile_entries_args = list(map(lambda inifile_entry: "--" + inifile_entry, self.inifile_entries))
442+
result_folder_args = ["--result-dir", self.result_folder] if self.result_folder != "results" else []
443+
args = [executable, *default_args, "-s", "-f", simulation_config.ini_file, "-c", simulation_config.config, "-r", str(self.run_number), *inifile_entries_args, *result_folder_args, "-e", option_name]
444+
if simulation_project.opp_env_workspace:
445+
subprocess_result = OppEnvSimulationRunner().run_args(simulation_project, args, cwd=simulation_project.get_full_path(simulation_config.working_directory))
446+
else:
447+
subprocess_result = run_command_with_logging(args, cwd=simulation_project.get_full_path(simulation_config.working_directory), env=simulation_project.get_env())
448+
return subprocess_result.stdout.strip().strip('"')
449+
387450
def get_expected_result(self):
388451
return self.simulation_config.expected_result
389452

0 commit comments

Comments
 (0)