Runtime Configuration

About

palaestrAI has a separate, often optional, configuration that takes care of all options not releated to experiment setup. This includes the results storage (the most commonly changed parameter), verbosity and form of palaestrAI’s output, and several options to tweak performance.

Quickstart

Most commonly, only the connection to the results storage backend wants to be changed. Per default, sets the store URI to sqlite:///palaestrai.db, i.e., if you run palaestrai database-create, an SQLite database with the filename palaestrai.db is created in the local directory (and subsequently used by all operations).

However, there is usually a central storage server that groups have set up. To use it, create a file named palaestrai.conf in your local directory from which you will run palaestrAI. Put the following contents in it:

store_uri: postgresql://user:password@host/database

Of course, replace user, password, host and database with actual values.

Setting and Loading the Configuration

palaestrAI searches its configuration at several places:

  1. $XDG_CONFIG_DIRS/palaestrai/runtime-conf.yaml

  2. $HOME/.config/palaestrai/runtime-conf.yaml

  3. $PWD/palaestrai.conf

  4. $PWD/palaestrai-runtime.conf.yaml

  5. $PWD/runtime.conf.yaml

  6. (Built-in defaults)

To determine an option, palaestrAI tries to read all sources, from 6 to 1 in the list, every time updating the current state with the new version. For this reason, palaestrAI has always a working runtime config and you can selectively overwrite whatever options you see fit.

As mentioned in the introduction the configuration runs through seperate phases in configuring the RuntimeConfig, each updating the config and taking preference to the former. After loading the built-in default values the RuntimeConfig searches through its standard search paths.

These search paths are generated at runtime. To check which paths your RuntimeConfig instance is looking up run the following command:

palaestrai runtime-config-show-default

To modify the beavior of the runtime search-path lookup, refer to the CONFIG_FILE_PATHS list in the RunetimeConfig class.

The configuration of the RuntimeConfig goes through several phases. First it loads default values which are built into the framework. Then it looks up the standard search paths and then, subsequently, loads any stream, file path or dictionary that is supplied by the user. Note that the RuntimeConfig always runs through these phases and each subsequent load updates the config accordingly. That means that the user provided values have preference over the previous configurations.

The seperate runtime configuration file is written in the YAML format. For an easy example please refer to an existing runtime configuration, for example: palaestrai/tests/fixtures/palaestrai-runtime-debug-conf.yaml

Lets take a look at all available config file options. All examples were taking from the default configuration. (Note: you can display the default configuration at any time by running: palaestrai runtime-config-show-default To display the currently effective runtime configuration run: palaestrai runtime-config-show-effective)

Configuration Options

Results Storage

property _RuntimeConfig.store_uri: str

URI to the store database for results

This must be any standards-compliant string in the form of transport://user:password@host-or-path:port/db. For example, postgresql://myuser:mypass@localhost/arl.

Returns:

The connection string; default: sqlite:///palaestrai.db

Return type:

str

Example

store_uri: postgresql://palaestrai:Password@localhost:5432/arl

property _RuntimeConfig.store_buffer_size: int

Number of messages buffered before writing to the store

palaestrAI buffers data before flushing it in bulk to the store. This number defines a factor; the number of messages being buffered is a multiple of the number of agents and number of environments, for technical reasons.

Writing data in bulk to the database makes the results storage more efficient. However, caching too many messages before writing will also increase the local memory consumption. To find a balance, the number is user-configurable. The number of messages cached is equal to number_of_workers * number_of_environments * store_buffer_size

Returns:

Multiplied for the storage buffer, default: 20

Return type:

int

Example

store_buffer_size: 10

property _RuntimeConfig.data_path: Path

File system path for data storage

Although the results storage database is the main system for storing any result the comes out of a palaestrAI run, some data is also dumped to the local disk, either for convenience or as backup. A common example are brain dumps (i.e., trained agent models).

Returns:

The data path, default: ./_outputs

Return type:

pathlib.Path

Example

data_path: /home/myself/palaestrai/results

In-palaestrAI Communication

palaestrAI is a heavily decentralized piece of software. Modules communicate with each other through a ZeroMQ broker.

property _RuntimeConfig.broker_uri: str

Full URI to the Major Domo Protocol broker

palaestrAI is based on message passing. All subsystems communicate with each other through a architecture that is based on the ZeroMQ Major Domo Protocol. This architecture uses a central broker to route messagees between subsystems.

This property retrives the full connect URI of the broker. It can be explicitly set in the runtime configuration; if not, it is derived from executor_bus_port and public_bind properties. The following values are recognized by palaestrAI:

broker_uri: ~ (i.e., None)

Derives from executor_bus_port and public_bind. If public_bind: False (the default), then the broker URI will be tcp://127.0.0.1:4242.

broker_uri: tcp://

Instructs the major domo broker to pick a random free port. Uses public_bind to determine whether the broker binds to localhost or to all available interfaces. Equivalent to tcp://*:*.

broker_uri: tcp://*:4242

Explicitly instructs the major domo broker to bind to the given port 4242 on all available interfaces.

broker_uri: ipc://

Lets the major domo broker pick a random file in a temporary directory to use the inter-process communication protocol instead of TCP. Ignores the settings in executor_bus_port and public_bind. Equivalent to ipc://*.

broker_uri: ipc:///some/file

Explicitly sets a file for IPC transport.

If the broker_uri property is set, it overwrites the effects of setting executor_bus_port and public_bind.

Examples

The default sets public_bind: False and executor_bus_port: 4242 in the runtime config, which creates the broker URI tcp://127.0.0.1:4242. This is equivalent to creating the following runtime config file entry:

broker_uri: tcp://127.0.0.1:4242
property _RuntimeConfig.executor_bus_port: int

Port of the executor’s messaging bus

palaestrai needs one bus to start it all, which is managed by the executor. All other buses and topics can be communicated over this initial bus.

Returns:

The bus port; default: 4242

Return type:

int

Example

executor_bus_port: 4242

property _RuntimeConfig.public_bind: bool

Indicates whether to bind to all public adresses or to localhost

This configuration setting allows the Executor and all other message buses to bind to all public IP addresses if set to True. If not, the buses will bind to 127.0.0.1 only`.

Finer-grained control can be excerted by the broker_uri option, which overwrites whatever setting is made here.

Returns:

If True, the major domo broker binds to all available IP addresses. The default is False.

Return type:

bool

Example

public_bind: False

property _RuntimeConfig.logger_port: int

Destination port the internal log server should use

All spawned submodules of palaestrAI communicate their log messages back to the main process. This log message receiver binds to the given port.

Returns:

The port of the internal log server, default: 4243

Return type:

int

Example

logger_port: 4243

Logging, Printing, and Profiling

property _RuntimeConfig.logging: Dict

Configuration of all subsystem loggers

The logging configuration determines how palaestrAI outputs its state information. The built-in configuration doesn’t give much output except for warnings and errors (which is akin to the Unix philosophy). However, the log level of individual modules can be increased to, e.g., INFO.

The configuration is based on the Python logging module. Thus, generation information can be obtained from Python’s official documentation on logging.

Returns:

The logging configuration

Return type:

dict

Examples

palaestrai runtime-config-show-default gives a complete, sane default logging config. To get a more colorful output, change it to:

logging:
  version: 1
  root:
    handlers: [console]
    level: ERROR
  filters:
    debug_filter: {(): palaestrai.core.runtime_config.DebugLogFilter}
  formatters:
    debug: {format: '%(asctime)s %(name)s[%(process)d]: %(levelname)s - %(message)s
        (%(module)s.%(funcName)s in %(filename)s:%(lineno)d)'}
    simple: {format: '%(asctime)s %(name)s[%(process)d]: %(levelname)s - %(message)s'}
    terminal: {class: palaestrai.cli.terminal_formatter.TerminalFormatter}
  handlers:
    console:
      class: logging.StreamHandler
      formatter: terminal
      level: DEBUG
      stream: 'ext://sys.stdout'
    console_debug:
      class: logging.StreamHandler
      filters: [debug_filter]
      formatter: debug
      level: DEBUG
      stream: ext://sys.stdout
  loggers:
    palaestrai.agent: {level: ERROR}
    palaestrai.agent.agent_conductor: {level: INFO}
    palaestrai.agent.brain: {level: INFO}
    palaestrai.agent.muscle: {level: INFO}
    palaestrai.core: {level: INFO}
    palaestrai.environment: {level: INFO}
    palaestrai.experiment: {level: INFO}
    palaestrai.simulation: {level: INFO}
    palaestrai.store: {level: ERROR}
    palaestrai.types: {level: ERROR}
    palaestrai.util: {level: ERROR}
    palaestrai.visualization: {level: ERROR}
    sqlalchemy.engine: {level: ERROR}

Performance Tuning

property _RuntimeConfig.fork_method: str

The method for forking child processes palaestrAI should use

palaestrAI creates a number of subprocesses when it runs. Python offers several ways to create new processes. The safest is to use the spawn method, which is the default. However, other methods like fork and forkserver offer higher speed, but are not available on every platform.

The recommended way is to leave it at spawn unless you are running on a Linux system, e.g., in a docker container. Then, forkserver can offer you a performance boost. For more details, see the offical Python documentation on start methods.

Returns:

Either spawn, fork, or forkserver. If the value set in the loadable runtime config is not any of these strings, the default method of spawn is returned. Default: spawn.

Return type:

str

property _RuntimeConfig.profile: bool

Whether to enable profiling or not.

If enabled, executions of palaestrAI create profiling information in .prof files. This can be important for hunting performance bugs and is usually enabled by developers, but not by end users. Profiling is based on Python’s cProfile module and the resulting files can be inspected with tools like Snakeviz.

Returns:

If True, profiling is enabled and .prof files are generated; if False, nothing is additionally done.

Return type:

bool

RuntimeConfig as an API

When running palaestrAI from the command line interface, the configuration file is usually all that is needed. However, the runtime configuration can also be accessed and changed programmatically throught the palaestrai.core.RuntimeConfig() singleton method. This comes in handy in Jupyter Notebooks.

Note

palaestrAI loads its runtime configuration automatically. I.e., it is usually not necessary to use the API, not even from Jupyter notebooks. The only difference exists when, e.g., a notebook should be self-contained. The tutorials make a case in this regard.

palaestrai.core.RuntimeConfig()[source]

RuntimeConfig singleton instance

Provides API access to palaestrAI’s runtime configuration. At any time, the configuration is fed from one singleton instance.

_RuntimeConfig.load(stream_or_dict: dict | TextIO | str | Path | None = None)[source]

Loads the configuration from an external source.

The runtime configuration is initialized from the default configuration in ::_RuntimeConfig.DEFAULT_CONFIG. This method then iterates through the list in ::_RuntimeConfig.CONFIG_FILE_PATHS, subsequently updating the existing configuration with new values found. Finally, the given ::stream_or_dict parameter is used if present, ultimately taking preference over all other values.

That means that each config file can contain only a portion of the overall configuration; it gets updated subsequently.

Parameters:

stream_or_dict (Union[dict, TextIO, str, Path, None]) – Loads the runtime configuration directly from a dictionary or as YAML-encoded stream. If no stream is given, the default files in _RuntimeConfig.CONFIG_FILE_PATHS will be tried as described.

Examples

RuntimeConfig().load()

Will initialize the runtime configuration from the default configuration, and then try all available configuration files. The configuration is updated in a cascading manner.

RuntimeConfig.load({"store_uri": "sqlite:///test.db"})

Loads the complete configuration is above, but additionally overwrites the store_uri parameter, setting it to sqlite:///test.db.

_RuntimeConfig.reset()[source]

Resets the runtime configuration to empty state