System Black Box

The BlackBox modules provides utilities to run external scripts and programs in a constrained environment and parse the result.

class optilog.blackbox.ExecutionConstraints(wall_time=None, cpu_time=None, memory=None)

Describes the execution constraints of a process

Parameters
  • wall_time (Optional[int]) – Wall time limit in seconds

  • cpu_time (Optional[int]) – CPU time limit in seconds

  • memory (Optional[str]) – Memory limit represented with a string. The memory limit should have a postfix with the unit (accepts “M”, “G” or “T”). Examples: "5M", "123G", "2T".

class optilog.blackbox.SystemBlackBox(arguments, runsolver=None, unbuffer=False, constraints=None, parsing_info=None)

Blackbox that runs an external subprocess (usually a binary).

Parameters
  • arguments (List[Union[str, BlackBoxArgument]]) – List of arguments for the command to be executed. Placeholders might be used, such as SystemBlackBox.Instance and SystemBlackBox.Seed, that will be replaced during execution.

  • runsolver (Union[str, bool]) – Path to the runsolver binary, which is needed to enforce memory and times limits. If it is True it will search runsolver in the PATH. If it is None, it will search it in PATH only if necessary (if there is a time or memory constraint). See the runsolver documentation for more information.

  • unbuffer (Union[str, bool]) – Path to the unbuffer binary, which may be desirable to unbuffer the pipe of the call. If it is a boolean, it will search unbuffer in the PATH. See the unbuffer documentation for more information.

  • constraints (ExecutionConstraints) – Defines the execution constraints for the Configuration Process

  • parsing_info (ParsingInfo) – Optional ParsingInfo object used for parsing the output of the blackbox

Instance = 1

Automatically substitutable instance argument

Seed = 2

Automatically substitutable seed argument

WallTime = 4

Automatically substitutable WallTime argument

CPUTime = 5

Automatically substitutable CPUTime argument

Memory = 3

Automatically substitutable Memory argument

property returncode: int

Return code of the execution Accessible after the execution has finished.

Return type

int

property stdout: str

Stdout output of the execution. Accessible after the execution has finished.

Return type

str

property stderr: str

Stderr output of the execution. Accessible after the execution has finished.

Return type

str

property config: Dict

Dictionary used to store all the possible configurable parameters of this class

Return type

Dict

format_config(args)

Formats the configurable parameters of the blackbox, and concats them with args. By default, all parameters are formatted as --param-name=value. This method is expected to be overwritten for commands that expect the parameters in a different format.

Parameters

args (list) – List of current arguments

Returns

Final list of strings with the parameters to be called

run(instance, seed=None, constraints=None, stdout=BlackBoxRedirection.Default, stderr=BlackBoxRedirection.Stdout, text=True)

Executes the blackbox and stores its standard output

Parameters
  • instance (str) – Instance to execute

  • seed (Optional[int]) – Seed of the execution

  • constraints (Optional[ExecutionConstraints]) – Defines the execution constraints for the Configuration Process. If it is None, the default constraints of the constructor will be used. Otherwise, these new constraints will be used.

  • stdout (Union[str, BlackBoxRedirection]) – Where to redirect stdout. If it is a string, the output will be redirected to the specified path.

  • stderr (Union[str, BlackBoxRedirection]) – Where to redirect stderr. If it is a string, the output will be redirected to the specified path.

  • text (bool) – Whether the output is text based or binary

get(key)

Returns the value assigned to a given parameter name.

Parameters

key (str) – Parameter name.

Return type

Union[int, float, bool, str]

Returns

Parameter value.

classmethod get_config()
Return type

Dict[str, Dict[str, str]]

Returns

A dictionary with all the configurable parameters of the solver. Each parameter has defined its type (int, float, bool or categorical), its domain, and its default value.

property parsed

Dictionary with all the parsed elements from the execution. Accessible after the execution has finished.

set(key, value, check_domain=True)

Sets the value for a given parameter.

Parameters
  • key (str) – Parameter name.

  • value – Parameter value.

  • value – int or float or bool or str

Raises

KeyError: if param is not found inside the solver.

class optilog.blackbox.BlackBoxRedirection(value)

Blackbox redirection options

Default = 1

Default redirection

Stdout = 2

Redirect output to stdout.

Null = 3

Redirect output to null (ignore output).

Process = 4

Redirect output to parent process file descriptors. n Example: Redirecting stdout to Process will “automatically print” the stdout output of the subprocess.

Here we have a basic example of a blackbox execution with parsing and memory limitations. Notice the usage of the placeholder SystemBlackBox.Instance. This will be replaced by the instance specified passed to run.

>>> from optilog.blackbox import SystemBlackBox
>>> from optilog.running import ParsingInfo
>>>
>>> parsing_info = ParsingInfo()
>>> parsing_info.add_filter('conflicts', 'Num conflicts: (\d+)', cast_to=int)
>>>
>>> executor = SystemBlackBox(
>>>     ['./solver.sh', SystemBlackBox.Instance],
>>>     constraints=ExecutionConstraints( # will inject call with runsolver found in PATH
>>>         wall_time=100,
>>>         memory='100M'
>>>     ),
>>>     parsing_info=parsing_info
>>> )
>>>
>>> executor.run('path/to/instance')  # wraps: ./solver.sh path/to/instance
>>>
>>> print(executor.conflicts) # 34
>>> print(executor.parsed) # {'conflicts': 34}

Here we have a more complex example with configuration. To have a higher flexibility, we extend the BlackBox class. As ./solver.sh expects the boolean parameters as flags, we override the format_config method to add the flag only when needed, instead of having –flag=True to the command call. Notice that we still have to add the args reveived by format_config.

>>> from optilog.blackbox import SystemBlackBox
>>> from optilog.running import ParsingInfo
>>> from optilog.tuning.basis import Int, Real, Bool
>>>
>>>
>>> parsing_info = ParsingInfo()
>>> parsing_info.add_filter('conflicts', 'Num conflicts: (\d+)', cast_to=int)
>>> parsing_info.add_filter('instance', 'Instance Path: (.+)')
>>>
>>> class ExampleSolverBB(SystemBlackBox):
>>>
>>>     config = {
>>>         'incReduceDB': Int(0, 2147483647, default=300),
>>>         'R': Real(1.001, 4.999, default=1.4),
>>>         'C': Bool(default=False)
>>>     }
>>>
>>>     def __init__(self, *args, **kwargs):
>>>         super().__init__(arguments=['./solver.sh', SystemBlackBox.Instance], *args, **kwargs)
>>>
>>>     def format_config(self, args):
>>>         config = self.configured.copy()
>>>         c = config.pop('C', False)
>>>         extra_args = []
>>>         if c:
>>>             extra_args += ['--C']
>>>         return args + extra_args + [
>>>             f'--{k}={v}'
>>>             for k, v in config.items()
>>>         ]
>>>
>>>
>>> executor = ExampleSolverBB(parsing_info=parsing_info)
>>>
>>> executor.set('incReduceDB', 20)  # Set the parameter --incReduceDB=20
>>> executor.set('C', True)  # Set the flag --C
>>>
>>> executor.run('path/to/instance') # wraps: ./solver.sh path/to/instance --C --incReduceDB=20
>>>
>>> print(executor.conflicts)
...
>>> print(executor.parsed)
...
>>> print(executor.stdout)
...