Skip to content

Commit 113c211

Browse files
committed
Add option to redirect logs to file in a FunctionEvaluator
1 parent 1dd3e5d commit 113c211

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

optimas/evaluators/function_evaluator.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,23 @@ class FunctionEvaluator(Evaluator):
2020
using this option, the current working directory inside the ``function``
2121
will be changed to the corresponding evaluation directory.
2222
By default, ``False``.
23+
redirect_logs_to_file : bool
24+
Whether to redirect the logs (stdout and stderr) of the evaluation
25+
function to a file (log.out and log.err). This can be useful to keep the
26+
logs of the exploration clean, preventing many processes from writing to the
27+
terminal at once. If enabled, `create_evaluation_dirs` will be set to `True`.
2328
2429
"""
2530

2631
def __init__(
27-
self, function: Callable, create_evaluation_dirs: bool = False
32+
self, function: Callable, create_evaluation_dirs: bool = False, redirect_logs_to_file: bool = False
2833
) -> None:
2934
super().__init__(sim_function=run_function)
3035
self.function = function
3136
self._create_evaluation_dirs = create_evaluation_dirs
37+
self._redirect_logs_to_file = redirect_logs_to_file
38+
if self._redirect_logs_to_file:
39+
self._create_evaluation_dirs = True
3240

3341
def get_sim_specs(
3442
self,
@@ -43,6 +51,7 @@ def get_sim_specs(
4351
)
4452
# Add evaluation function to sim_specs.
4553
sim_specs["user"]["evaluation_func"] = self.function
54+
sim_specs["user"]["redirect_logs_to_file"] = self._redirect_logs_to_file
4655
return sim_specs
4756

4857
def get_libe_specs(self) -> Dict:

optimas/sim_functions.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Contains the definition of the simulation functions given to libEnsemble."""
2+
from contextlib import redirect_stderr, redirect_stdout
23

34
import jinja2
45
import numpy as np
@@ -122,6 +123,7 @@ def run_function(H, persis_info, sim_specs, libE_info):
122123
else:
123124
user_specs = sim_specs["user"]
124125
evaluation_func = user_specs["evaluation_func"]
126+
redirect_logs_to_file = user_specs["redirect_logs_to_file"]
125127

126128
# Prepare the array that is returned to libE
127129
libE_output = np.zeros(1, dtype=sim_specs["out"])
@@ -130,7 +132,16 @@ def run_function(H, persis_info, sim_specs, libE_info):
130132
libE_output[name].fill(np.nan)
131133

132134
# Run evaluation.
133-
evaluation_func(input_values, libE_output[0])
135+
if redirect_logs_to_file:
136+
with (
137+
open("log.out", "w") as stdout_file,
138+
open("log.err", "w") as stderr_file,
139+
redirect_stdout(stdout_file),
140+
redirect_stderr(stderr_file),
141+
):
142+
evaluation_func(input_values, libE_output[0])
143+
else:
144+
evaluation_func(input_values, libE_output[0])
134145
calc_status = WORKER_DONE
135146

136147
# If required, fail when the objectives are NaN.

0 commit comments

Comments
 (0)