Sort all includes in src/gromacs
[alexxy/gromacs.git] / src / gromacs / selection / compiler.cpp
index 60a87a179579ab6568dd1ee9490d4d3c8a8f2b24..4b696a29ae1095f31e6cd5ac41f0f3a0649e9639 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013, by the GROMACS development team, led by
- * David van der Spoel, Berk Hess, Erik Lindahl, and including many
- * others, as listed in the AUTHORS file in the top-level source
- * directory and at http://www.gromacs.org.
+ * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
  *
  * GROMACS is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
  * calculated.
  * Currently, no other processing is done.
  */
-#include "compiler.h"
+#include "gmxpre.h"
 
-#include <algorithm>
+#include "compiler.h"
 
 #include <math.h>
 #include <stdarg.h>
 
-#include "gromacs/legacyheaders/smalloc.h"
-#include "gromacs/legacyheaders/string2.h"
-#include "gromacs/legacyheaders/vec.h"
+#include <algorithm>
 
+#include "gromacs/math/vec.h"
 #include "gromacs/selection/indexutil.h"
-#include "gromacs/selection/poscalc.h"
 #include "gromacs/selection/selection.h"
-#include "gromacs/selection/selmethod.h"
 #include "gromacs/utility/exceptions.h"
+#include "gromacs/utility/smalloc.h"
 #include "gromacs/utility/stringutil.h"
 
 #include "evaluate.h"
 #include "keywords.h"
 #include "mempool.h"
+#include "poscalc.h"
 #include "selectioncollection-impl.h"
 #include "selelem.h"
+#include "selmethod.h"
 
 using std::min;
 using gmx::SelectionTreeElement;
@@ -565,7 +565,7 @@ alloc_selection_pos_data(const SelectionTreeElementPointer &sel)
         GMX_RELEASE_ASSERT(child,
                            "Subexpression elements should always have a child element");
     }
-    nalloc = child->v.u.p->nr;
+    nalloc = child->v.u.p->count();
     isize  = child->v.u.p->m.b.nra;
 
     /* For positions, we want to allocate just a single structure
@@ -1603,7 +1603,7 @@ init_item_minmax_groups(const SelectionTreeElementPointer &sel)
  * \param[in,out] sc   Selection collection data.
  *
  * The evaluation group of each \ref SEL_ROOT element corresponding to a
- * selection in \p sc is set to NULL.  The evaluation grop for \ref SEL_ROOT
+ * selection in \p sc is set to NULL.  The evaluation group for \ref SEL_ROOT
  * elements corresponding to subexpressions that need full evaluation is set
  * to \c sc->gall.
  */
@@ -1809,8 +1809,6 @@ store_param_val(const SelectionTreeElementPointer &sel)
     if (sel->v.type == INT_VALUE || sel->v.type == REAL_VALUE
         || sel->v.type == STR_VALUE)
     {
-        GMX_RELEASE_ASSERT(sel->v.u.ptr != NULL,
-                           "Selection method parameter not properly initialized");
         _gmx_selvalue_setstore(&sel->u.param->val, sel->v.u.ptr);
     }
 }
@@ -1980,8 +1978,7 @@ evaluate_boolean_static_part(gmx_sel_evaluate_t                *data,
     {
         child->cdata->evaluate = &_gmx_sel_evaluate_static;
         /* The cgrp has only been allocated if it originated from an
-         * external index group. In that case, we need special handling
-         * to preserve the name of the group and to not leak memory.
+         * external index group.
          * If cgrp has been set in make_static(), it is not allocated,
          * and hence we can overwrite it safely. */
         if (child->u.cgrp.nalloc_index > 0)
@@ -2407,7 +2404,7 @@ init_root_item(const SelectionTreeElementPointer &root,
         /* For selections, store the maximum group for
          * gmx_ana_selcollection_evaluate_fin() as the value of the root
          * element (unused otherwise). */
-        if (expr->type != SEL_SUBEXPR && expr->v.u.p->g)
+        if (expr->type != SEL_SUBEXPR && expr->v.u.p->m.mapb.a != NULL)
         {
             SelectionTreeElementPointer child = expr;
 
@@ -2427,10 +2424,12 @@ init_root_item(const SelectionTreeElementPointer &root,
             }
             if (child->child->flags & SEL_DYNAMIC)
             {
+                gmx_ana_index_t g;
+                gmx_ana_index_set(&g, expr->v.u.p->m.mapb.nra, expr->v.u.p->m.mapb.a, 0);
                 _gmx_selelem_set_vtype(root, GROUP_VALUE);
                 root->flags  |= (SEL_ALLOCVAL | SEL_ALLOCDATA);
                 _gmx_selvalue_reserve(&root->v, 1);
-                gmx_ana_index_copy(root->v.u.g, expr->v.u.p->g, true);
+                gmx_ana_index_copy(root->v.u.g, &g, true);
             }
         }
     }
@@ -2441,6 +2440,54 @@ init_root_item(const SelectionTreeElementPointer &root,
 }
 
 
+/********************************************************************
+ * REQUIRED ATOMS ANALYSIS
+ ********************************************************************/
+
+/*! \brief
+ * Finds the highest atom index required to evaluate a selection subtree.
+ *
+ * \param[in]     sel           Root of the selection subtree to process.
+ * \param[in,out] maxAtomIndex  The highest atom index required to evaluate the
+ *      subtree.  The existing value is never decreased, so multiple calls with
+ *      the same parameter will compute the maximum over several subtrees.
+ *
+ * For evaluation that starts from a \ref SEL_ROOT element with a fixed group,
+ * children will never extend the evaluation group except for method parameter
+ * evaluation (which have their own root element), so it is sufficient to check
+ * the root.  However, children of \ref SEL_EXPRESSION elements (i.e., the
+ * method parameters) may have been independently evaluated to a static group
+ * that no longer has a separate root, so those need to be checked as well.
+ *
+ * Position calculations are not considered here, but are analyzed through the
+ * position calculation collection in the main compilation method.
+ */
+static void
+init_required_atoms(const SelectionTreeElementPointer &sel, int *maxAtomIndex)
+{
+    // Process children.
+    if (sel->type != SEL_SUBEXPRREF)
+    {
+        SelectionTreeElementPointer child = sel->child;
+        while (child)
+        {
+            init_required_atoms(child, maxAtomIndex);
+            child = child->next;
+        }
+    }
+
+    if (sel->type == SEL_ROOT
+        || (sel->type == SEL_CONST && sel->v.type == GROUP_VALUE))
+    {
+        if (sel->u.cgrp.isize > 0)
+        {
+            *maxAtomIndex =
+                std::max(*maxAtomIndex, gmx_ana_index_get_max_index(&sel->u.cgrp));
+        }
+    }
+}
+
+
 /********************************************************************
  * FINAL SUBEXPRESSION OPTIMIZATION
  ********************************************************************/
@@ -2580,7 +2627,7 @@ init_item_comg(const SelectionTreeElementPointer &sel,
                 gmx_ana_poscalc_set_flags(sel->u.expr.pc, cflags);
             }
             gmx_ana_poscalc_set_maxindex(sel->u.expr.pc, sel->cdata->gmax);
-            snew(sel->u.expr.pos, 1);
+            sel->u.expr.pos = new gmx_ana_pos_t();
             gmx_ana_poscalc_init_pos(sel->u.expr.pc, sel->u.expr.pos);
         }
     }
@@ -2834,9 +2881,10 @@ SelectionCompiler::compile(SelectionCollection *coll)
         coll->printTree(stderr, false);
     }
 
-    /* Initialize evaluation groups, position calculations for methods, perform
-     * some final optimization, and free the memory allocated for the
-     * compilation. */
+    // Initialize evaluation groups, maximum atom index needed for evaluation,
+    // position calculations for methods, perform some final optimization, and
+    // free the memory allocated for the compilation.
+    coll->impl_->maxAtomIndex_ = 0;
     /* By default, use whole residues/molecules. */
     flags = POS_COMPLWHOLE;
     PositionCalculationCollection::typeFromEnum(coll->impl_->rpost_.c_str(),
@@ -2846,10 +2894,14 @@ SelectionCompiler::compile(SelectionCollection *coll)
     {
         init_root_item(item, &sc->gall);
         postprocess_item_subexpressions(item);
+        init_required_atoms(item, &coll->impl_->maxAtomIndex_);
         init_item_comg(item, &sc->pcc, post, flags);
         free_item_compilerdata(item);
         item = item->next;
     }
+    coll->impl_->maxAtomIndex_ =
+        std::max(coll->impl_->maxAtomIndex_,
+                 sc->pcc.getHighestRequiredAtomIndex());
 
     /* Allocate memory for the evaluation memory pool. */
     _gmx_sel_mempool_reserve(sc->mempool, 0);