Bug fix and simplification for CUDA X Buffer Ops
[gromacs.git] / src / gromacs / nbnxm / gridset.cpp
blobfeeb005594d4fa277fd20f29bb5ed457bd1ea2b5
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2019, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
36 /*! \internal \file
38 * \brief
39 * Implements the GridSet class.
41 * \author Berk Hess <hess@kth.se>
42 * \ingroup module_nbnxm
45 #include "gmxpre.h"
47 #include "gridset.h"
49 #include "gromacs/mdlib/gmx_omp_nthreads.h"
50 #include "gromacs/mdlib/updategroupscog.h"
51 #include "gromacs/nbnxm/atomdata.h"
52 #include "gromacs/utility/fatalerror.h"
54 namespace Nbnxm
57 //! Returns the number of DD zones
58 static int numDDZones(const std::array<bool, DIM> &haveMultipleDomainsPerDim)
60 int numDDZones = 1;
61 for (auto haveDD : haveMultipleDomainsPerDim)
63 if (haveDD)
65 numDDZones *= 2;
69 return numDDZones;
72 GridSet::DomainSetup::DomainSetup(const int ePBC,
73 const ivec *numDDCells,
74 const gmx_domdec_zones_t *ddZones) :
75 ePBC(ePBC),
76 haveMultipleDomains(numDDCells != nullptr),
77 zones(ddZones)
79 for (int d = 0; d < DIM; d++)
81 haveMultipleDomainsPerDim[d] = (numDDCells != nullptr && (*numDDCells)[d] > 1);
85 GridSet::GridSet(const int ePBC,
86 const ivec *numDDCells,
87 const gmx_domdec_zones_t *ddZones,
88 const PairlistType pairlistType,
89 const bool haveFep,
90 const int numThreads) :
91 domainSetup_(ePBC, numDDCells, ddZones),
92 grids_(numDDZones(domainSetup_.haveMultipleDomainsPerDim), pairlistType),
93 haveFep_(haveFep),
94 numRealAtomsLocal_(0),
95 numRealAtomsTotal_(0),
96 gridWork_(numThreads)
98 clear_mat(box_);
101 void GridSet::setLocalAtomOrder()
103 /* Set the atom order for the home cell (index 0) */
104 const Nbnxm::Grid &grid = grids_[0];
106 int atomIndex = 0;
107 for (int cxy = 0; cxy < grid.numColumns(); cxy++)
109 const int numAtoms = grid.numAtomsInColumn(cxy);
110 int cellIndex = grid.firstCellInColumn(cxy)*grid.geometry().numAtomsPerCell;
111 for (int i = 0; i < numAtoms; i++)
113 atomIndices_[cellIndex] = atomIndex;
114 cells_[atomIndex] = cellIndex;
115 atomIndex++;
116 cellIndex++;
121 // TODO: Move to gridset.cpp
122 void GridSet::putOnGrid(const matrix box,
123 const int ddZone,
124 const rvec lowerCorner,
125 const rvec upperCorner,
126 const gmx::UpdateGroupsCog *updateGroupsCog,
127 const int atomStart,
128 const int atomEnd,
129 real atomDensity,
130 gmx::ArrayRef<const int> atomInfo,
131 gmx::ArrayRef<const gmx::RVec> x,
132 const int numAtomsMoved,
133 const int *move,
134 nbnxn_atomdata_t *nbat)
136 Nbnxm::Grid &grid = grids_[ddZone];
138 int cellOffset;
139 if (ddZone == 0)
141 cellOffset = 0;
143 else
145 const Nbnxm::Grid &previousGrid = grids_[ddZone - 1];
146 cellOffset = previousGrid.atomIndexEnd()/previousGrid.geometry().numAtomsPerCell;
149 const int n = atomEnd - atomStart;
151 real maxAtomGroupRadius;
152 if (ddZone == 0)
154 copy_mat(box, box_);
156 numRealAtomsLocal_ = atomEnd - numAtomsMoved;
157 /* We assume that nbnxn_put_on_grid is called first
158 * for the local atoms (ddZone=0).
160 numRealAtomsTotal_ = atomEnd - numAtomsMoved;
162 maxAtomGroupRadius = (updateGroupsCog ? updateGroupsCog->maxUpdateGroupRadius() : 0);
164 if (debug)
166 fprintf(debug, "natoms_local = %5d atom_density = %5.1f\n",
167 numRealAtomsLocal_, atomDensity);
170 else
172 const Nbnxm::Grid::Dimensions &dimsGrid0 = grids_[0].dimensions();
173 atomDensity = dimsGrid0.atomDensity;
174 maxAtomGroupRadius = dimsGrid0.maxAtomGroupRadius;
176 numRealAtomsTotal_ = std::max(numRealAtomsTotal_, atomEnd);
179 /* We always use the home zone (grid[0]) for setting the cell size,
180 * since determining densities for non-local zones is difficult.
182 grid.setDimensions(ddZone, n - numAtomsMoved,
183 lowerCorner, upperCorner,
184 atomDensity,
185 maxAtomGroupRadius,
186 haveFep_);
188 for (GridWork &work : gridWork_)
190 work.numAtomsPerColumn.resize(grid.numColumns() + 1);
193 /* Make space for the new cell indices */
194 cells_.resize(atomEnd);
196 const int nthread = gmx_omp_nthreads_get(emntPairsearch);
198 #pragma omp parallel for num_threads(nthread) schedule(static)
199 for (int thread = 0; thread < nthread; thread++)
203 Grid::calcColumnIndices(grid.dimensions(),
204 updateGroupsCog,
205 atomStart, atomEnd, x,
206 ddZone, move, thread, nthread,
207 cells_, gridWork_[thread].numAtomsPerColumn);
209 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
212 GridSetData gridSetData = getGridSetData();
214 /* Copy the already computed cell indices to the grid and sort, when needed */
215 grid.setCellIndices(ddZone, cellOffset, &gridSetData, gridWork_,
216 atomStart, atomEnd, atomInfo.data(), x, numAtomsMoved, nbat);
218 if (ddZone == 0)
220 nbat->natoms_local = nbat->numAtoms();
222 if (ddZone == gmx::ssize(grids_) - 1)
224 /* We are done setting up all grids, we can resize the force buffers */
225 nbat->resizeForceBuffers();
228 int maxNumColumns = 0;
229 for (const auto &grid : grids())
231 maxNumColumns = std::max(maxNumColumns, grid.numColumns());
233 setNumColumnsMax(maxNumColumns);
237 } // namespace Nbnxm