Gromacs
2024.3
|
The compiler takes the selection element tree from the selection parser (see Selection parsing) as input. The selection parser is quite independent of selection evaluation details, and the compiler processes the tree to conform to what the evaluation functions expect. For better control and optimization possibilities, the compilation is done on all selections simultaneously. Hence, all the selections should be parsed before the compiler can be called.
The compiler initializes all fields in gmx::SelectionTreeElement not initialized by the parser: gmx::SelectionTreeElement::v (some fields have already been initialized by the parser), gmx::SelectionTreeElement::evaluate, and gmx::SelectionTreeElement::u (again, some elements have been initialized in the parser). The gmx::SelectionTreeElement::cdata field is used during the compilation to store internal data, but the data is freed when the compiler returns.
In addition to initializing the elements, the compiler reorganizes the tree to simplify and optimize evaluation. The compiler also evaluates the static parts of the selection: in the end of the compilation, static parts have been replaced by the result of the evaluation.
The compiler is invoked using gmx::SelectionCompiler. The gmx::SelectionCompiler::compile() method does the compilation in several passes over the gmx::SelectionTreeElement tree.
gmax
and gmin
fields. This is the part that needs multiple passes, because some flags are set recursively based on which elements refer to an element, and these flags need to be set to initialize other fields.SEL_CDATA_EVALMAX
flag, which makes dynamic child expressions of BOOL_OR
expressions evaluate to empty groups, while subexpressions of BOOL_AND
are evaluated to largest possible groups. Memory is also allocated to store the results of the evaluation. For each element, analyze_static() calls the actual evaluation function after the element has been properly initialized.gmx_ana_selection_t
data structures.The actual evaluation of the selection is described in the documentation of the functions in evaluate.h.
After the compilation, the selection element tree is suitable for gmx_ana_selcollection_evaluate(). Enough memory has been allocated for gmx::SelectionTreeElement::v (and gmx::SelectionTreeElement::cgrp for SEL_SUBEXPR elements) to allow the selection to be evaluated without allocating any memory.
The top level of the tree consists of a chain of SEL_ROOT elements. These are used for two purposes:
The children of the SEL_ROOT elements can be used to distinguish the two types of root elements from each other; the rules are the same as for the parsed tree (see Root elements). Subexpressions are treated as if they had been provided through variables.
Selection names are stored as after parsing (see Root elements).
All (sub)selections that do not require particle positions have been replaced with SEL_CONST elements. Constant elements from the parser are also retained if present in dynamic parts of the selections. Several constant elements with a NULL gmx::SelectionTreeElement::evaluate are left for debugging purposes; of these, only the ones for BOOL_OR expressions are used during evaluation.
The value is stored in gmx::SelectionTreeElement::v, and for group values with an evaluation function set, also in gmx::SelectionTreeElement::cgrp. For GROUP_VALUE elements, unnecessary atoms (i.e., atoms that could never be selected) have been removed from the value.
SEL_CONST elements have no children.
All selection methods that need to be evaluated dynamically are described by a SEL_EXPRESSION element. The gmx::SelectionTreeElement::method and gmx::SelectionTreeElement::mdata fields have already been initialized by the parser, and the compiler only calls the initialization functions in the method data structure to do some additional initialization of these fields at appropriate points. If the gmx::SelectionTreeElement::pc data field has been created by the parser, the compiler initializes the data structure properly once the required positions are known. If the gmx::SelectionTreeElement::pc field is NULL after the parser, but the method provides only sel_updatefunc_pos(), an appropriate position calculation data structure is created. If gmx::SelectionTreeElement::pc is not NULL, gmx::SelectionTreeElement::pos is also initialized to hold the positions calculated.
Children of these elements are of type SEL_SUBEXPRREF, and describe parameter values that need to be evaluated for each frame. See the next section for more details. SEL_CONST children can also appear, and stand for parameters that get their value from a static expression. These elements are present only for debugging purposes: they always have a NULL evaluation function.
As described in Root elements, subexpressions are created for each variable and each expression that gives a value to a selection method parameter. As the only child of the SEL_ROOT element, these elements have a SEL_SUBEXPR element. The SEL_SUBEXPR element has a single child, which evaluates the actual expression. After compilation, only subexpressions that require particle positions for evaluation are left. For non-variable subexpression, automatic names have been generated to help in debugging.
For SEL_SUBEXPR elements, memory has been allocated for gmx::SelectionTreeElement::cgrp to store the group for which the expression has been evaluated during the current frame. This is only done if full subexpression evaluation by _gmx_sel_evaluate_subexpr() is needed; the other evaluation functions do not require this memory.
SEL_SUBEXPRREF elements are used to describe references to subexpressions. They have always a single child, which is the SEL_SUBEXPR element being referenced.
If a subexpression is used only once, the evaluation has been optimized by setting the child of the SEL_SUBEXPR element to evaluate the value of SEL_SUBEXPRREF directly (in the case of memory pooling, this is managed by the evaluation functions). In such cases, the evaluation routines for the SEL_SUBEXPRREF and SEL_SUBEXPR elements only propagate some status information, but do not unnecessarily copy the values.
SEL_BOOLEAN elements have been merged such that one element may carry out evaluation of more than one operation of the same type. The static parts of the expressions have been evaluated, and are placed in the first child. These are followed by the dynamic expressions, in the order provided by the user.
Constant and static expressions in SEL_ARITHMETIC elements have been calculated. Currently, no other processing is done.