The Transfomer program accepts event built data as input. For each fragment in each physics event ring item, user written code is invoked to supply an extension data block that's put on the back end of each fragment. The sizes are adjusted accordingly so that the resulting ring items are fully consistent.
The application spins up several parallel workers that process blocks of events in parallel. Resulting ring items are re-sorted by timestamp before they are emitted to the output sink.
Most program options are mandatory. The optional ones will be pointed out in the discussion below.
--help
(optional)Help text is output to stdout and the program exits.
--version
(optional)The program name and version are output to stdout and the program exits.
--source
=URISpecifies the source of the data to be processed. This can be either a file or a tcp URI. If this is a tcp URI in general the program will likely not exit but continue processing until forced to exit.
--sink
=URISpecifies where the processed data will go. This can be a file or tcp URI. If a tcp URI is specified, the host must resolve to the local host.
--workers
=int (optional)
Specifies the number of workers to spin up for the
computation. Note that this can be overidden by the
-np
option specified in
mpirun if
--paralele-strategy
is
mpi.
IF not specified, this defaults to 1 which for anything but trivial computations is probably not sufficient.
--clump-size
=int (optional)The clump size, specified by this option, is the number of ring items that make up a work unit passed to each worker. Clumping ring items together makes communication and sorting more efficient (sorting can be done by blocks rather than individual ring items).
If not specified, this defaults to 1 which likely does not optimize performance. Unfortunately ther are no good hard and fast rules for recommending the value of this option. In general large is good, but too large and you either won't have enough workers to parallelize the processing or physical memroy can be oversubscribed. Furthermore if the source and destinations are tcp URI's, overly large clump-sizes can mean that the output will lag significantly behind the input.
--extendlib
=filepathProvides the path to the shared library that will be used to provide user code. See SHARED LIBRARY below for more information about the expectations for the code that lives in that library.
--parallel-strategy
= mpi | threadedSpecifies how parallelism will be performedn and how communications between the parallel processes will be handled. threaded limits the application to the cores available on a single system. Each processing element is a thread and ZMQ inproc is used to communicate between the threads.
mpi uses MPI as the parallel model and the communications mechanism MPI provides mechanisms to recruit several systems into the computation and allows this software to run scalably across Linux MPI clusters.
If mpi parallelism is chosen,
the mpirun command must be run and
specifies the total number of processes in the application
using its -np
option.
The total number of processes is nworkers+3.
If -np
is inconsistent with
--workers
, the number of workers is
determined by -np
(nworkers = npvalue-3). If this
is not the same value as --workers
a
warning message is output and, if there are sufficient
processes for at least one worker, processing continues.
If this the value of -np
in
mpirun is not at least 4,
an error message is output indicating there are
not sufficient processes and the program exits.
The Transformer application requires
that you supply a shared library and specify it with the
--extendlib
option. This shared library
must:
Define and implement a concrete subclass of the
class CBuiltRingItemExtender::CRingItemExtender
defined in CBuiltRingItemExtender.h.
Provide a factory function that can create instances of your class.
The CBuiltRingitemExtender::CRingItemExtender
abstract base class provide an interface definition for the user
code that computes the extensions that will be added to
event fragments in a physics event. Concrete subclasses must
implmenet two interface methods:
virtual iovec operator()(pRingItem item);
item
is a pointer to a ring
item as defined in DataFormat.h.
This item is an event fragment in the event currently
being operated on by the worker.
The method is expected to create an extension that will
be appended to the event fragment. The return value
is an iovec
as described in
the manpage for writev
(2). It has
the fields iov_len
which is the
size of the extension you create and
iov_base
which points to the
extension.
The storage containing the extension must be valid for the entirety of event processing as events are output using the gather capabilities of the communications framework. Typically, this requirement means that extensions should be dynamically allocated.
Note that if your code does not want to provide
an extension for the fragment it can set the
iov_len
field to
0.
virtual void free(iovec& extension);
When the extension storage is no longer needed, the framework calls this method once for each extension that was created for this event. This method is not called for fragments for which no extension was provided.
This method is suppoed to free all storage
associated with the extension provided by this
extension
parameter.