From 445251d5695aa80c78fcb2c226e6abfc1805c5a8 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Mon, 22 Jul 2024 14:11:04 -0600 Subject: [PATCH] simplify logic for checking whether occasional neight list needs to be rebuilt --- src/EXTRA-COMPUTE/compute_hexorder_atom.cpp | 4 +- src/MC/fix_bond_create.cpp | 8 +-- src/MC/fix_bond_swap.cpp | 2 +- src/REACTION/fix_bond_react.cpp | 2 +- src/RHEO/fix_rheo_thermal.cpp | 2 +- src/compute_aggregate_atom.cpp | 6 +-- src/compute_cluster_atom.cpp | 6 +-- src/create_bonds.cpp | 2 +- src/neighbor.cpp | 57 ++++++++++++++------- src/neighbor.h | 21 +++++--- 10 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_hexorder_atom.cpp b/src/EXTRA-COMPUTE/compute_hexorder_atom.cpp index 11e65ea9c5..86e816b2e5 100644 --- a/src/EXTRA-COMPUTE/compute_hexorder_atom.cpp +++ b/src/EXTRA-COMPUTE/compute_hexorder_atom.cpp @@ -148,10 +148,8 @@ void ComputeHexOrderAtom::compute_peratom() } // invoke full neighbor list (will copy or build if necessary) - // on the first step of a run, set preflag to one in neighbor->build_one(...) - if (update->firststep == update->ntimestep) neighbor->build_one(list,1); - else neighbor->build_one(list); + neighbor->build_one(list); inum = list->inum; ilist = list->ilist; diff --git a/src/MC/fix_bond_create.cpp b/src/MC/fix_bond_create.cpp index 589625cc16..b2d92805d3 100644 --- a/src/MC/fix_bond_create.cpp +++ b/src/MC/fix_bond_create.cpp @@ -408,15 +408,15 @@ void FixBondCreate::post_integrate() int *mask = atom->mask; int *type = atom->type; - if (constrainflag) { - // communicate partner and 1-2 special neighbors - // to correctly handle angle constraints + // communicate partner and 1-2 special neighbors + // to correctly handle angle constraints + if (constrainflag) { commflag = 3; comm->forward_comm(this); } - neighbor->build_one(list,1); + neighbor->build_one(list); inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; diff --git a/src/MC/fix_bond_swap.cpp b/src/MC/fix_bond_swap.cpp index 29d81684dd..cc67a07ed2 100644 --- a/src/MC/fix_bond_swap.cpp +++ b/src/MC/fix_bond_swap.cpp @@ -229,7 +229,7 @@ void FixBondSwap::post_integrate() type = atom->type; x = atom->x; - neighbor->build_one(list,1); + neighbor->build_one(list); inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index d8561b3959..8c241355fd 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -920,7 +920,7 @@ void FixBondReact::post_integrate() tagint *tag = atom->tag; int *type = atom->type; - neighbor->build_one(list,1); + neighbor->build_one(list); // here we define a full special list // may need correction for unusual special bond settings diff --git a/src/RHEO/fix_rheo_thermal.cpp b/src/RHEO/fix_rheo_thermal.cpp index daa5b347a7..c8c1877e32 100644 --- a/src/RHEO/fix_rheo_thermal.cpp +++ b/src/RHEO/fix_rheo_thermal.cpp @@ -654,7 +654,7 @@ void FixRHEOThermal::create_bonds() int *num_bond = atom->num_bond; double **x = atom->x; - neighbor->build_one(list, 1); + neighbor->build_one(list); inum = list->inum; ilist = list->ilist; diff --git a/src/compute_aggregate_atom.cpp b/src/compute_aggregate_atom.cpp index 8c6f7165a2..9720cb86cf 100644 --- a/src/compute_aggregate_atom.cpp +++ b/src/compute_aggregate_atom.cpp @@ -116,12 +116,8 @@ void ComputeAggregateAtom::compute_peratom() comm->forward_comm(); // invoke full neighbor list (will copy or build if necessary) - // on the first step of a run, set preflag to one in neighbor->build_one(...) - if (update->firststep == update->ntimestep) - neighbor->build_one(list, 1); - else - neighbor->build_one(list); + neighbor->build_one(list); // if group is dynamic, ensure ghost atom masks are current diff --git a/src/compute_cluster_atom.cpp b/src/compute_cluster_atom.cpp index 0021d32e2c..ca521f11e8 100644 --- a/src/compute_cluster_atom.cpp +++ b/src/compute_cluster_atom.cpp @@ -105,12 +105,8 @@ void ComputeClusterAtom::compute_peratom() comm->forward_comm(); // invoke full neighbor list (will copy or build if necessary) - // on the first step of a run, set preflag to one in neighbor->build_one(...) - if (update->firststep == update->ntimestep) - neighbor->build_one(list, 1); - else - neighbor->build_one(list); + neighbor->build_one(list); inum = list->inum; ilist = list->ilist; diff --git a/src/create_bonds.cpp b/src/create_bonds.cpp index 13a99a182f..416884138b 100644 --- a/src/create_bonds.cpp +++ b/src/create_bonds.cpp @@ -228,7 +228,7 @@ void CreateBonds::many() // build neighbor list this command needs based on earlier request auto list = neighbor->find_list(this); - neighbor->build_one(list, 1); + neighbor->build_one(list); // loop over all neighs of each atom // compute distance between two atoms consistently on both procs diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 59ddf87698..110814c1c4 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -163,6 +163,9 @@ pairclass(nullptr), pairnames(nullptr), pairmasks(nullptr) npair_perpetual = 0; plist = nullptr; + npair_occasional = 0; + olist = nullptr; + nrequest = maxrequest = 0; requests = nullptr; j_sorted = nullptr; @@ -253,6 +256,7 @@ Neighbor::~Neighbor() delete[] slist; delete[] plist; + delete[] olist; for (int i = 0; i < nrequest; i++) if (requests[i]) delete requests[i]; @@ -1008,6 +1012,9 @@ int Neighbor::init_pair() for (i = 0; i < nrequest; i++) { requests[i]->index_pair = -1; flag = lists[i]->pair_method; + + // 22 Jul 2024 NOTE, don't think flag = 0 occurs in current code + if (flag == 0) { neigh_pair[i] = nullptr; continue; @@ -1054,19 +1061,25 @@ int Neighbor::init_pair() // plist = indices of perpetual NPair classes // perpetual = non-occasional, re-built at every reneighboring + // olist = indices of occasional NPair classes + // occasional = built only when requested // slist = indices of perpetual NStencil classes // perpetual = used by any perpetual NPair class - delete[] slist; delete[] plist; - nstencil_perpetual = npair_perpetual = 0; - slist = new int[nstencil]; + delete[] olist; + delete[] slist; + npair_perpetual = npair_occasional = nstencil_perpetual = 0; plist = new int[nlist]; + olist = new int[nlist]; + slist = new int[nstencil]; for (i = 0; i < nlist; i++) { if (lists[i]->occasional == 0 && lists[i]->pair_method) plist[npair_perpetual++] = i; - } + if (lists[i]->occasional) + olist[npair_occasional++] = i; + } for (i = 0; i < nstencil; i++) { flag = 0; @@ -1173,7 +1186,7 @@ void Neighbor::morph_unique() irq = requests[i]; // if cut flag set by requestor and cutoff is different than default, - // set unique flag, otherwise unset cut flag + // set unique flag, otherwise unset cut flag // this forces Pair,Stencil,Bin styles to be instantiated separately // also add skin to cutoff of perpetual lists @@ -2416,7 +2429,9 @@ void Neighbor::build(int topoflag) int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; + // rebuild collection array from scratch + if (style == Neighbor::MULTI) build_collection(0); // check that using special bond flags will not overflow neigh lists @@ -2488,6 +2503,16 @@ void Neighbor::build(int topoflag) // skip if GPU package styles will call it explicitly to overlap with GPU computation. if ((atom->molecular != Atom::ATOMIC) && topoflag && !overlap_topo) build_topology(); + + // reset last_build in all occasional lists + // this will force them rebuild on next request + // all occasional lists are now out-of-date b/c + // comm->exchange() occurred before neighbor->build() + + for (i = 0; i < npair_occasional; i++) { + m = olist[i]; + neigh_pair[m]->last_build = -1; + } } /* ---------------------------------------------------------------------- @@ -2524,7 +2549,7 @@ void Neighbor::build_topology() called by other classes ------------------------------------------------------------------------- */ -void Neighbor::build_one(class NeighList *mylist, int preflag) +void Neighbor::build_one(class NeighList *mylist) { // check if list structure is initialized @@ -2535,18 +2560,12 @@ void Neighbor::build_one(class NeighList *mylist, int preflag) if (!mylist->occasional) error->all(FLERR,"Neighbor::build_one() invoked on perpetual list"); - // no need to build if already built since last re-neighbor - // preflag is set by fix bond/create and fix bond/swap - // b/c they invoke build_one() on same step neigh list is re-built, - // but before re-build, so need to use ">" instead of ">=" + // no need to build this occasional list if already built + // since last comm->exchange() and re-neighbor which invoked build() + // build() method resets last_build for all occasional lists to -1 NPair *np = neigh_pair[mylist->index]; - - if (preflag) { - if (np->last_build > lastcall) return; - } else { - if (np->last_build >= lastcall) return; - } + if (np->last_build >= lastcall) return; // if this is copy list and parent is occasional list, // or this is halffull and parent is occasional list, @@ -2554,11 +2573,11 @@ void Neighbor::build_one(class NeighList *mylist, int preflag) // ensure parent is current if (mylist->listcopy && mylist->listcopy->occasional) - build_one(mylist->listcopy,preflag); + build_one(mylist->listcopy); if (mylist->listfull && mylist->listfull->occasional) - build_one(mylist->listfull,preflag); + build_one(mylist->listfull); if (mylist->listskip && mylist->listskip->occasional) - build_one(mylist->listskip,preflag); + build_one(mylist->listskip); // create stencil if hasn't been created since last setup_bins() call diff --git a/src/neighbor.h b/src/neighbor.h index 8533fe5efa..88dfe991f2 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -126,18 +126,22 @@ class Neighbor : protected Pointers { virtual void init(); // old API for creating neighbor list requests + int request(void *, int instance = 0); // new API for creating neighbor list requests + NeighRequest *add_request(class Pair *, int flags = 0); NeighRequest *add_request(class Fix *, int flags = 0); NeighRequest *add_request(class Compute *, int flags = 0); NeighRequest *add_request(class Command *, const char *, int flags = 0); // set neighbor list request OpenMP flag + void set_omp_neighbor(int); // report if we have INTEL package neighbor lists + bool has_intel_request() const; int decide(); // decide whether to build or not @@ -145,8 +149,8 @@ class Neighbor : protected Pointers { void setup_bins(); // setup bins based on box and cutoff virtual void build(int); // build all perpetual neighbor lists virtual void build_topology(); // pairwise topology neighbor lists - // create a one-time pairwise neigh list - void build_one(class NeighList *list, int preflag = 0); + + void build_one(class NeighList *list); // create an occasional pairwise neigh list void set(int, char **); // set neighbor style and skin distance void reset_timestep(bigint); // reset of timestep counter void modify_params(int, char **); // modify params that control builds @@ -155,18 +159,18 @@ class Neighbor : protected Pointers { void exclusion_group_group_delete(int, int); // rm a group-group exclusion int exclude_setting(); // return exclude value to accelerator pkg - // Option to call build_topology (e.g. from gpu styles instead for overlapped computation) + // option to call build_topology (e.g. from gpu styles instead for overlapped computation) int overlap_topo; // 0 for default/old non-overlap mode void set_overlap_topo(int); - // find a neighbor list based on requestor + // find a neighbor list or request based on requestor + NeighList *find_list(void *, const int id = 0) const; - // find a neighbor request based on requestor NeighRequest *find_request(void *, const int id = 0) const; const std::vector get_pair_requests() const; - int any_full(); // Check if any old requests had full neighbor lists + int any_full(); // check if any old requests had full neighbor lists void build_collection(int); // build peratom collection array starting at the given index bigint get_nneigh_full(); // return number of neighbors in a regular full neighbor list @@ -205,10 +209,13 @@ class Neighbor : protected Pointers { int old_pgsize, old_oneatom; // used to avoid re-creating neigh lists int nstencil_perpetual; // # of perpetual NeighStencil classes - int npair_perpetual; // #x of perpetual NeighPair classes + int npair_perpetual; // # of perpetual NeighPair classes int *slist; // indices of them in neigh_stencil int *plist; // indices of them in neigh_pair + int npair_occasional; // # of occasional NeighPair classes + int *olist; // indices of them in neigh_pair + int maxex_type; // max # in exclusion type list int maxex_group; // max # in exclusion group list int maxex_mol; // max # in exclusion molecule list