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 ) ) )