Filter Expression Grammar
The filter expression grammar creates a filter, which is a set of function
(
funcfilter
), message
(p2pfilter
), and collective
operation (collfilter
) filters,
each defining a filter for its respective kind of data. These sub-filter
specifications are separated by the #
sign and come in any order. Each filter class is specified
either once, or more than once (in this case a Boolean AND is created from all
subfilters for a given class), or not specified at all. An example where three
classes of filters are specified is the expression generated in the graphical
interface.Each filter class specifier (
funcfilter
, p2pfilter
, or collfilter
) is followed by an expression put in parentheses. That
expression can consist of any number of predicates that are different for each
filter class and correspond to the entries described in the section Building
Filter Expressions Using the Graphical Interface. These predicates are
joined by using Boolean AND (&&) and OR (||) operators. Boolean expressions
are parenthesized as needed. Also, a Boolean NOT (!) operator in front of any
predicate or parenthesized expression negates the predicate/expression.A filter class enables you to define a special expression to pass all or no data
through the filter. For example,
p2pfilter(NONE)
filters out all messages, while collfilter(ALL)
passes all collective
operation. When the keywords ALL or NONE are used, ensure that it is the only
argument to funcfilter
,
p2pfilter
, or collfilter
.Keyword specification in the filter expression grammar is case-insensitive.
Specifying names (for functions, processes and communicators, among others),
however, is case-sensitive. Use double quotes for names that consist of several
words or do not start with a letter or an underscore character (for example, "Major
Function Groups"). Use double quotes for single word names (for example, "MPI") if
necessary. White space (space and tab characters, as well as newlines) is ignored,
unless it is part of a quoted name. If a process/group or function/group name is
ambiguous, it is evaluated as if all matching groups were given.
Formal Description of Grammar
Here is a formal description of the filter expression grammar:
# The filter itself FILTER ::= AFILTER | FILTER # AFILTER AFILTER ::= funcfilter ( FUNCFILTARG ) | collfilter ( COLLFILTARG ) | p2pfilter ( P2PFILTARG ) # Specifying functions FUNCFILTARG ::= FUNCEXPR | all | none FUNCEXPR ::= FUNCATOM | FUNCEXPR && FUNCATOM | FUNCEXPR || FUNCATOM FUNCATOM ::= TG | FG | STARTTIME | ( FUNCEXPR ) | ! FUNCATOM # Specifying messages P2PFILTARG ::= P2PEXPR | all | none P2PEXPR ::= P2PATOM | P2PEXPR && P2PATOM | P2PEXPR || P2PATOM P2PATOM ::= DURATION | COMM | TAG | P2PVOLUME | TGSENDER | TGRECEIVER | COMMSENDER | COMMRECEIVER | TGSRPAIR | COMMSRPAIR | TG | COMMSR | STARTTIME | ENDTIME | SENDER_FG | RECEIVER_FG | ( P2PEXPR ) | ! P2PATOM # Specifying collective operations COLLFILTARG ::= COLLEXPR | all | none COLLEXPR ::= COLLATOM | COLLEXPR && COLLATOM | COLLEXPR || COLLATOM COLLATOM ::= DURATION | COMM | COLLOPTYPE | COLLVOLUME | TGROOT | COMMROOT | TG | STARTTIME | ENDTIME | ( COLLEXPR ) | ! COLLATOM # Specifying times STARTTIME ::= start ( TRIPLETS ; INTEGER ) | start ( TRIPLETS ) ENDTIME ::= end ( TRIPLETS ; INTEGER ) | end ( TRIPLETS ) DURATION ::= duration ( TRIPLETS ) # Specifying TGroups and FGroups TG ::= tg ( NAMES ) FG ::= fg ( NAMES ) SENDER_FG ::= send_fg ( NAMES ) RECEIVER_FG ::= recv_fg ( NAMES ) # Specifying collective operation and message properties COMM ::= comm ( TRIPLETS ) TAG ::= tag ( TRIPLETS ) COLLOPTYPE ::= type ( COLLNAMES ) COLLVOLUME ::= volume ( TRIPLETS ) P2PVOLUME ::= volume ( TRIPLETS ) # Specifying root, sender, or receiver, either by a TGroup name # or by position in the communicator. If the operation has no # root, then root() is always false. TGROOT ::= root ( NAMES ) TGSENDER ::= sender ( NAMES ) TGRECEIVER ::= receiver ( NAMES ) # The predicate sr specifies both sender and receiver, separated # by a semicolon. TGSRPAIR ::= sr ( NAMES ; NAMES ) COMMROOT ::= root@ ( TRIPLETS ) COMMSENDER ::= sender@ ( TRIPLETS ) COMMRECEIVER ::= receiver@ ( TRIPLETS ) # The predicate sr@ specifies both sender and receiver ranks, # separated by a semicolon. COMMSRPAIR ::= sr@ ( TRIPLETS ; TRIPLETS ) COMMSR ::= tg@ ( TRIPLETS ) # Names containing fancy characters have to be double-quoted. # Names map to TGroup and thread names, FGroup and function # names, or collective operation types, depending on the context. NAMES ::= NAME | TRIPLET | NAMES , NAME | NAMES , TRIPLET COLLNAMES ::= COLLNAMELIST | TRIPLETS COLLNAMELIST ::= NAME | COLLNAMELIST , NAME NAME ::= [_a-zA-Z][_a-zA-Z0-9.]* | \"[^\"]*\" # Specifying triplets and numbers TRIPLETS ::= TRIPLET | TRIPLETS , TRIPLET TRIPLET ::= INTEGER | INTEGER : | INTEGER : INTEGER | INTEGER : INTEGER : INTEGER INTEGER ::= [0-9]+
Examples of Advanced Usage of Grammar
This section includes several examples of the manual usage of the filter
expression grammar and how the manual usage of the grammar provides advanced
capabilities in filtering trace data and speeding up the process of selecting
exactly what you want to analyze.
For the first example, consider a parenthesized structure that cannot be built in
the graphical interface easily (messages sent by process 0 and starting or ending
between 70000 and 80000 ticks):
p2pfilter( sender( 0 ) && ( start( 70000:80000 ) || end( 70000:80000 ) ) )
The following example uses the
sr
predicate, which is not available in the graphical interface.
This predicate helps to efficiently filter out all messages between processes 0
and 1:p2pfilter( ! sr( 0:1; 0:1 ) )
Finally, consider the following scenario. With the graphical interface, a
complicated filter is specified for a certain filter class with a large number of
predicates and Boolean operators (both AND and OR, the latter added by using the
Add New Clause
button). To negate everything that has been specified so
far (that is, to get exactly the trace data that was previously being filtered
out), use !
in front of the
whole expression when in the manual mode. For example, the filter below specifies
MPI_Barrier
collective
operations that last no longer than 2000 ticks, plus all collective operations
with process 0 as the root:collfilter( type( MPI_Barrier ) && duration( 0:2000 ) || root( 0 ) )
while the following filter specifies all the collective operations that do not
match the description above:
collfilter( ! ( type( MPI_Barrier ) && duration( 0:2000 ) || root( 0 ) ) )