Overview

brahms_execution is a Matlab object that corresponds to a BRAHMS Execution File. It is constructed using the syntax exe = brahms_execution, and then the object can be modified. It is passed to brahms for writing to file automatically, or can be written to file explicitly using the serialize() call.

Interface

Properties

Like the fields of a structure in Matlab (see the Example below).

name
This parameter, along with workingDirectory is used to name the Execution File, System File, and Report File (if these filenames are not specified explicitly). If absent, "unnamed" is assumed.
systemFileIn, executionFile, reportFile
These fields allow to specify explicitly the names of all files written on calling brahms, overriding the automatic setting. The first two are also written into the Execution File.
systemFileOut
This field, if set, causes an output system file to be written (this may not yet be supported by BRAHMS).
title, workingDirectory, executionStop, seed
These fields give direct one-to-one access to the corresponding fields (note case may vary) in the Execution File. executionStop can also be reached through the synonym stop.
precision, window, encapsulated, all
Gives access to the attributes of the <Logs> tag of the Execution File.
voices READONLY
Returns the number of Voices in the Execution (set addresses to write this value).
addresses
Gives access to the <Voices> tag of the Execution File. Syntaxes accepted are: exe.addresses = {comms N}, with comms the communications protocol ('sockets' or 'mpi') and N the number of Voices (for 'sockets', this sets up a babble, with all IPs set to localhost); exe.addresses = {ip1, ip2, ...} with each ip<n> a string holding an IP address (this sets up a Concerto Execution on remote machines). See example below.
affinity
Gives access to the <Affinity> tag of the Execution File. Set this to a single cell array, with each cell representing a <Group>. Each <Group> cell should itself be a cell array containing a list of strings, representing the <Identifier> tags within the <Group> tag. Exactly one number can be included in a group cell, in which case it will be interpreted as an explicit assignment of that Group to a specific Voice (this is useful if your hardware is not symmetric). See example below.
execPars
Any Execution Parameter can be set as a sub-field of this field, for example exe.execPars.MaxThreadCount = 1. Any parameter that has been set can be read back in a similar way.
launch
The Launch Line is used to launch the BRAHMS executable when the time comes. See below for details.

Methods

Note that the old usage of this function of the form exe = exe.log(..., key, value, ...) is now replaced by exe = exe.log(..., {key, value}, ...).

exe = exe.log(name, ...)
Request logging of one or more output Ports or Processes by using this function. The first argument "name" should be the SystemML Absolute Identifier of the output Port, Process or Subsystem you want logged. Additional arguments should be flags or key-value pairs in a two-element cell. Key-value pairs may include {'precision', <number>} and {'window', '<window string>'}. Flags may include 'encapsulated' ('encap'), 'unencapsulated' ('unencap'), and 'norecurse'. By default, "Recurse" is set on the Log, so any descendants of the specified object are also logged; to turn this off, pass the flag 'norecurse'.

Launch Line

To allow total flexibility in launching BRAHMS through the Matlab Bindings on any hardware or software configuration, no attempt is made to cover all bases, and we use instead a "Launch Line" which is invoked through the system() call, and which can be chosen by the user. The Launch Line system is intended to allow customisation of a launch to your local context, and need not be modified in many cases. It becomes useful when you have hardware to interact with, or esoteric deployment situations. The more esoteric, the more of this section you'll want to read.

For instance, a common requirement is to launch different voices on different machines. If running in Sockets mode, their IP address is already stored, so you can use a Launch Line that uses ssh and the IP to start the BRAHMS voice on a remote machine. Whatever form the launch line takes, certain tokens are replaced by something appropriate before it is used, as follows.

((VOICES))
The Voice count.
((VOICE))
The index of the launched Voice.
((ADDR))
The address of the Voice (usually, IP address).
((EXECFILE))
The full path to the Execution File.
((LOGFILE))
The full path to the Log File.
((EXITFILE))
The full path to the Exit File.
((ARGS))
Any additional command-line arguments.
((REDIRECT))
Whatever is required to redirect the output of the preceding command at a stdout/stderr log file.
Notes
  • The launch line may be variously modified and augmented as the launcher proceeds (including, but not limited to, replacement of the above tokens). You can retrieve the final form of the launch line from the invocation object returned by the brahms script (or pass "--show-cmd" to brahms).
  • Having established the Launch Line that works for your local configuration, you can set LaunchLineSolo, LaunchLineSockets or LaunchLineMPI to have it used as the default for future executions.
  • If you need even more flexibility, you can use the first form of the Launch Line to launch a shell script of your own design, and use this shell script to invoke BRAHMS. Alternatively, you can use a Matlab Launch Function (below).

Shell Launch Line (Single)

The simplest launch line will be called once, launching BRAHMS to execute the correct Execution File (see notes on tokens, below), and will not return until BRAHMS has finished executing. The launcher will then collect results, collate and return them. This is known as synchronous launch mode. For example, the default Solo launch line is given below. Note that it does not end in ((REDIRECT)), since the stdout/stderr of this line will be captured as part of the launch process.

brahms ((EXECFILE)) --logfmt-xml --voice-1 --logfile-((LOGFILE)) --exitfile-((EXITFILE)) ((ARGS))

If the launch line starts with the five-character token each<space>, the remainder of the line is called once for each voice in the execution, and (naturally) these calls are assumed to return instantly, without waiting for BRAHMS to finish executing. The launcher will then wait until exit files from each voice have been seen, before collecting and returning results (to facilitate this, an --exitfile argument is added to invocation.args). This is known as asynchronous launch mode. For example, the default Concerto (Sockets) launch line is below. This line does end in the ((REDIRECT)) token, because we expect stdout/stderr to continue generating content after the launch process has completed, and we'd like to see it.

each brahms ((EXECFILE)) --logfmt-xml --voice-((VOICE)) --logfile-((LOGFILE)) --exitfile-((EXITFILE)) ((ARGS)) ((REDIRECT))

Where possible, running in synchronous mode is preferable, because segmentation faults can be detected (this is not possible in asynchronous mode, where seg faults will lead to the bindings hanging indefinitely waiting for an exit file that will never appear). Sometimes, even when running multiple voices (Concerto), it is possible to run in synchronous mode. An example of this is when multiple voices are launched using MPI. The default Concerto (MPI) launch line is given below. No ((REDIRECT)), again, because mpiexec collates the stdout/stderr of the launched processes, and pipes them to its own output.

mpiexec -n ((VOICES)) brahms ((EXECFILE)) --logfmt-xml --voice-mpi --logfile-((LOGFILE)) --exitfile-((EXITFILE)) ((ARGS))

Notes
  • In the case that synchronous mode is used but multiple voices are being launched (e.g. when using MPI), the tokens ((VOICE)) and ((ADDR)) cannot be replaced by the bindings, and remain unchanged. The executable will replace ((VOICE)) as soon as that information is available (but not ((ADDR))), but errors occurring before this point are piped to a file with the token in its name. This file is detected by the bindings and an error message is still generated.

Shell Launch Line (Multiple)

To use different launch lines for different voices (beyond the variability allowed by replacement of tokens), set exe.launch equal to a cell array of strings. The first will be used to launch Voice 1, the second to launch Voice 2, etc. If insufficient lines are supplied, the last is used to launch all further Voices. Note that this form implies asynchronous mode (it is treated as if "each" were used), so the launcher will ask for exit files from the executable and wait for them to appear before collecting results. This form might be useful, for instance, if you want to launch the first Voice locally with the GUI displayed, and the remainder on remote machines with the GUI hidden. You could achieve this by setting exe.launch to a two-element cell array.

Launch Function

If you prefer to write a Matlab script rather than a shell command line or script to launch your voices, set exe.launch to a function handle. The function should have the form out = launch('launch', invocation), will be called just once for all voices, and should launch the voices specified in the invocation data object. The function can operate in synchronous or asynchronous mode, and should provide a second calling form info = launch('info', invocation), returning a structure info with one string field mode set to either "synchronous" or "asynchronous".

The function should launch all BRAHMS voices, and return a 1xL structure, where L is the number of launch lines called (usually, L is either 1 or V, with V the number of voices). The structure should have fields cmd, result and log. If the function operates in synchronous mode, result and log should contain the return code and stdout/stderr log from the BRAHMS executable; if it operates in asynchronous mode, they should contain the return code and log from the launch line. In either case, cmd should contain the system command called to invoke the executable. The function should not raise an error on failure to launch; the bindings will do this when non-zero return codes are returned.

In case it is of use, the default launch line for the execution is provided in invocation.launch, with some tokens (((VOICES)), ((EXECFILE)), ((LOGFILE)) and ((EXITFILE))) already replaced with appropriate tokens. The token ((VOICE)) can be replaced with the voice index as appropriate, and the token ((ARGS)) with the string in invocation.args. The token ((ADDR)), or other tokens, may also be present, depending on the default launch line for the condition in the Execution Parameters that apply. However, the function is free to construct this command entirely from scratch, if appropriate.

Example

M Source Code (against 995)
% construct execution object exe = brahms_execution; % the name is used to generate filenames for XML files exe.name = test; % set the a priori stop time to t = 1.0 seconds exe.stop = 1; % turn off multi-threading exe.execPars.MaxThreadCount = 1; % ask for everything to be logged exe.all = true; % set precision of all logs exe.precision = 4; % override settings for one individual log exe = exe.log('process>output', 'precision', 6, 'encapsulated', true); % run a three voice Babble exe.addresses = {'sockets' 3}; % have all processes of Subsystem "SubSys" computed together % have "ProcA" and "ProcB" computed together, too exe.affinity = {{'SubSys'}, {'ProcA' 'ProcB'}}; % as above, but also make sure "SubSys" is computed on Voice 2, % which may be running on particular hardware with which "SubSys" % needs to interact exe.affinity = {{2, 'SubSys'}, {'ProcA' 'ProcB'}}; ... % run BRAHMS out = brahms(sys, exe);

Example

This is an example Launch Line used to invoke BRAHMS on different machines through ssh.

each ssh user@((ADDR)) brahms ((EXECFILE)) --voice-((VOICE)) ((ARGS))

Example

This is an example of a Launch Function.

M Source Code (against 995)
% this custom launch script does pretty much exactly what % the default LaunchLineSockets does... function out = launch(op, invocation) out = []; switch op case 'info' % just return information on how this function operates, % which currently is just the mode field out.mode = 'asynchronous'; case 'launch' % default launch.cmd = ''; launch.result = []; launch.log = ''; out = launch(1:0); % the default launch line is provided, here cmd = invocation.launch; % we'll hack it for windows - this prefix causes the OS to % return without waiting for the executable to finish, and % is equivalent to the unix idiom of suffixing an "&" cmd = strrep(cmd, 'each', 'start /B'); % replace $(ARGS) token cmd = strrep(cmd, '((ARGS))', invocation.args); % launch all (behave as "each") for v = 1:invocation.exe.voices launch.cmd = strrep(cmd, '((VOICE))', num2str(v)); [launch.result, launch.log] = system(out.cmds{v}); out(v) = launch; end end