add OpenMP support for multi-neigbor lists

This commit is contained in:
Axel Kohlmeyer
2011-10-02 23:44:11 -04:00
parent 07a30ba4aa
commit 7594a2c491

View File

@ -14,8 +14,13 @@
#include "neighbor.h"
#include "neigh_list.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#if defined(_OPENMP)
#include <omp.h>
#endif
using namespace LAMMPS_NS;
/* ----------------------------------------------------------------------
@ -28,15 +33,24 @@ using namespace LAMMPS_NS;
void Neighbor::half_multi_no_newton(NeighList *list)
{
// bin local & ghost atoms
bin_atoms();
const int nthreads = comm->nthreads;
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
NEIGH_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(list)
#endif
NEIGH_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,which,ns;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*s;
double *cutsq,*distsq;
// bin local & ghost atoms
bin_atoms();
// loop over each atom, storing neighbors
int **special = atom->special;
@ -47,31 +61,33 @@ void Neighbor::half_multi_no_newton(NeighList *list)
int *type = atom->type;
int *mask = atom->mask;
int *molecule = atom->molecule;
int nlocal = atom->nlocal;
int molecular = atom->molecular;
if (includegroup) nlocal = atom->nfirst;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
int **pages = list->pages;
int *nstencil_multi = list->nstencil_multi;
int **stencil_multi = list->stencil_multi;
double **distsq_multi = list->distsq_multi;
int inum = 0;
int npage = 0;
// each thread works on its own page
int npage = tid;
int npnt = 0;
for (i = 0; i < nlocal; i++) {
for (i = ifrom; i < ito; i++) {
if (pgsize - npnt < oneatom) {
npnt = 0;
npage++;
if (npage == list->maxpage) pages = list->add_pages();
npage += nthreads;
// only one thread at a time may check whether we
// need new neighbor list pages and then add to them.
#if defined(_OPENMP)
#pragma omp critical
#endif
if (npage >= list->maxpage) list->add_pages(nthreads);
}
neighptr = &pages[npage][npnt];
neighptr = &(list->pages[npage][npnt]);
n = 0;
itype = type[i];
@ -112,15 +128,15 @@ void Neighbor::half_multi_no_newton(NeighList *list)
}
}
ilist[inum++] = i;
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
npnt += n;
if (n > oneatom || npnt >= pgsize)
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
}
list->inum = inum;
NEIGH_OMP_CLOSE;
list->inum = nlocal;
}
/* ----------------------------------------------------------------------
@ -132,15 +148,24 @@ void Neighbor::half_multi_no_newton(NeighList *list)
void Neighbor::half_multi_newton(NeighList *list)
{
// bin local & ghost atoms
bin_atoms();
const int nthreads = comm->nthreads;
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
NEIGH_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(list)
#endif
NEIGH_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,which,ns;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*s;
double *cutsq,*distsq;
// bin local & ghost atoms
bin_atoms();
// loop over each atom, storing neighbors
int **special = atom->special;
@ -151,31 +176,33 @@ void Neighbor::half_multi_newton(NeighList *list)
int *type = atom->type;
int *mask = atom->mask;
int *molecule = atom->molecule;
int nlocal = atom->nlocal;
int molecular = atom->molecular;
if (includegroup) nlocal = atom->nfirst;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
int **pages = list->pages;
int *nstencil_multi = list->nstencil_multi;
int **stencil_multi = list->stencil_multi;
double **distsq_multi = list->distsq_multi;
int inum = 0;
int npage = 0;
// each thread works on its own page
int npage = tid;
int npnt = 0;
for (i = 0; i < nlocal; i++) {
for (i = ifrom; i < ito; i++) {
if (pgsize - npnt < oneatom) {
npnt = 0;
npage++;
if (npage == list->maxpage) pages = list->add_pages();
npage += nthreads;
// only one thread at a time may check whether we
// need new neighbor list pages and then add to them.
#if defined(_OPENMP)
#pragma omp critical
#endif
if (npage >= list->maxpage) list->add_pages(nthreads);
}
neighptr = &pages[npage][npnt];
neighptr = &(list->pages[npage][npnt]);
n = 0;
itype = type[i];
@ -241,15 +268,15 @@ void Neighbor::half_multi_newton(NeighList *list)
}
}
ilist[inum++] = i;
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
npnt += n;
if (n > oneatom || npnt >= pgsize)
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
}
list->inum = inum;
NEIGH_OMP_CLOSE;
list->inum = nlocal;
}
/* ----------------------------------------------------------------------
@ -261,15 +288,24 @@ void Neighbor::half_multi_newton(NeighList *list)
void Neighbor::half_multi_newton_tri(NeighList *list)
{
// bin local & ghost atoms
bin_atoms();
const int nthreads = comm->nthreads;
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
NEIGH_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(list)
#endif
NEIGH_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,which,ns;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*s;
double *cutsq,*distsq;
// bin local & ghost atoms
bin_atoms();
// loop over each atom, storing neighbors
int **special = atom->special;
@ -280,31 +316,33 @@ void Neighbor::half_multi_newton_tri(NeighList *list)
int *type = atom->type;
int *mask = atom->mask;
int *molecule = atom->molecule;
int nlocal = atom->nlocal;
int molecular = atom->molecular;
if (includegroup) nlocal = atom->nfirst;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
int **pages = list->pages;
int *nstencil_multi = list->nstencil_multi;
int **stencil_multi = list->stencil_multi;
double **distsq_multi = list->distsq_multi;
int inum = 0;
int npage = 0;
// each thread works on its own page
int npage = tid;
int npnt = 0;
for (i = 0; i < nlocal; i++) {
for (i = ifrom; i < ito; i++) {
if (pgsize - npnt < oneatom) {
npnt = 0;
npage++;
if (npage == list->maxpage) pages = list->add_pages();
npage += nthreads;
// only one thread at a time may check whether we
// need new neighbor list pages and then add to them.
#if defined(_OPENMP)
#pragma omp critical
#endif
if (npage >= list->maxpage) list->add_pages(nthreads);
}
neighptr = &pages[npage][npnt];
neighptr = &(list->pages[npage][npnt]);
n = 0;
itype = type[i];
@ -354,13 +392,13 @@ void Neighbor::half_multi_newton_tri(NeighList *list)
}
}
ilist[inum++] = i;
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
npnt += n;
if (n > oneatom || npnt >= pgsize)
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
}
list->inum = inum;
NEIGH_OMP_CLOSE;
list->inum = nlocal;
}