git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@9002 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
@ -32,7 +32,7 @@ lammps_spparks grain-growth Monte Carlo with strain via MD,
|
|||||||
coupling to SPPARKS kinetic MC code
|
coupling to SPPARKS kinetic MC code
|
||||||
library collection of useful inter-code communication routines
|
library collection of useful inter-code communication routines
|
||||||
simple simple example of driver code calling LAMMPS as library
|
simple simple example of driver code calling LAMMPS as library
|
||||||
fortran a wrapper on the LAMMPS library API that
|
fortran a simple wrapper on the LAMMPS library API that
|
||||||
can be called from Fortran
|
can be called from Fortran
|
||||||
fortran2 a more sophisticated wrapper on the LAMMPS library API that
|
fortran2 a more sophisticated wrapper on the LAMMPS library API that
|
||||||
can be called from Fortran
|
can be called from Fortran
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
/* -------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
http://lammps.sandia.gov, Sandia National Laboratories
|
http://lammps.sandia.gov, Sandia National Laboratories
|
||||||
Steve Plimpton, sjplimp@sandia.gov
|
Steve Plimpton, sjplimp@sandia.gov
|
||||||
@ -32,6 +32,7 @@
|
|||||||
#include "kspace.h"
|
#include "kspace.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
|
#include "fix.h"
|
||||||
#include "modify.h"
|
#include "modify.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
@ -260,7 +261,8 @@ void VerletSplit::setup_minimal(int flag)
|
|||||||
|
|
||||||
void VerletSplit::run(int n)
|
void VerletSplit::run(int n)
|
||||||
{
|
{
|
||||||
int nflag,ntimestep,sortflag;
|
bigint ntimestep;
|
||||||
|
int nflag,sortflag;
|
||||||
|
|
||||||
// sync both partitions before start timer
|
// sync both partitions before start timer
|
||||||
|
|
||||||
@ -272,6 +274,13 @@ void VerletSplit::run(int n)
|
|||||||
|
|
||||||
rk_setup();
|
rk_setup();
|
||||||
|
|
||||||
|
// check if OpenMP support fix defined
|
||||||
|
|
||||||
|
Fix *fix_omp;
|
||||||
|
int ifix = modify->find_fix("package_omp");
|
||||||
|
if (ifix < 0) fix_omp = NULL;
|
||||||
|
else fix_omp = modify->fix[ifix];
|
||||||
|
|
||||||
// flags for timestepping iterations
|
// flags for timestepping iterations
|
||||||
|
|
||||||
int n_post_integrate = modify->n_post_integrate;
|
int n_post_integrate = modify->n_post_integrate;
|
||||||
@ -360,6 +369,11 @@ void VerletSplit::run(int n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// run FixOMP as sole pre_force fix, if defined
|
||||||
|
|
||||||
|
if (fix_omp) fix_omp->pre_force(vflag);
|
||||||
|
|
||||||
if (force->kspace) {
|
if (force->kspace) {
|
||||||
timer->stamp();
|
timer->stamp();
|
||||||
force->kspace->compute(eflag,vflag);
|
force->kspace->compute(eflag,vflag);
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
# Install/unInstall package files in LAMMPS
|
# Install/unInstall package files in LAMMPS
|
||||||
# do not install child files if parent does not exist
|
# do not install child files if parent does not exist
|
||||||
|
|
||||||
for file in *_omp.cpp *_omp.h pppm*proxy.h pppm*proxy.cpp; do
|
for file in *_omp.cpp *_omp.h ; do
|
||||||
# let us see if the "rain man" can count the toothpicks...
|
# let us see if the "rain man" can count the toothpicks...
|
||||||
ofile=`echo $file | sed -e s,_pppm_tip4p_omp,_long_tip4p_omp, \
|
ofile=`echo $file | sed \
|
||||||
-e s,pppm.\\*_proxy,pppm_omp, -e s,_pppm_omp,_long_omp, \
|
|
||||||
-e s,\\\\\\(.\\*\\\\\\)_omp\\\\.h,\\\\1.h, \
|
-e s,\\\\\\(.\\*\\\\\\)_omp\\\\.h,\\\\1.h, \
|
||||||
-e s,\\\\\\(.\\*\\\\\\)_omp\\\\.cpp,\\\\1.cpp,`
|
-e s,\\\\\\(.\\*\\\\\\)_omp\\\\.cpp,\\\\1.cpp,`
|
||||||
if (test $1 = 1) then
|
if (test $1 = 1) then
|
||||||
|
|||||||
@ -4,10 +4,9 @@
|
|||||||
# not exist. Do remove OpenMP style files that have no matching
|
# not exist. Do remove OpenMP style files that have no matching
|
||||||
# non-OpenMP version installed, e.g. after a package has been
|
# non-OpenMP version installed, e.g. after a package has been
|
||||||
# removed
|
# removed
|
||||||
for file in *_omp.cpp *_omp.h pppm*proxy.h pppm*proxy.cpp thr_data.h thr_data.cpp; do
|
for file in *_omp.cpp *_omp.h thr_data.h thr_data.cpp; do
|
||||||
# let us see if the "rain man" can count the toothpicks...
|
# let us see if the "rain man" can count the toothpicks...
|
||||||
ofile=`echo $file | sed -e s,_pppm_tip4p_omp,_long_tip4p_omp, \
|
ofile=`echo $file | sed \
|
||||||
-e s,pppm.\\*_proxy,pppm_omp, -e s,_pppm_omp,_long_omp, \
|
|
||||||
-e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,`
|
-e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,`
|
||||||
if (test $file = "thr_omp.h") || (test $file = "thr_omp.cpp") \
|
if (test $file = "thr_omp.h") || (test $file = "thr_omp.cpp") \
|
||||||
|| (test $file = "thr_data.h") || (test $file = "thr_data.cpp") then
|
|| (test $file = "thr_data.h") || (test $file = "thr_data.cpp") then
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "force.h"
|
#include "force.h"
|
||||||
#include "neighbor.h"
|
#include "neighbor.h"
|
||||||
#include "neigh_request.h"
|
#include "neigh_request.h"
|
||||||
|
#include "universe.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "integrate.h"
|
#include "integrate.h"
|
||||||
#include "min.h"
|
#include "min.h"
|
||||||
@ -194,61 +195,76 @@ void FixOMP::init()
|
|||||||
if (strstr(update->integrate_style,"respa") != NULL)
|
if (strstr(update->integrate_style,"respa") != NULL)
|
||||||
error->all(FLERR,"Cannot use r-RESPA with /omp styles");
|
error->all(FLERR,"Cannot use r-RESPA with /omp styles");
|
||||||
|
|
||||||
int check_hybrid;
|
int check_hybrid, kspace_split;
|
||||||
last_pair_hybrid = NULL;
|
last_pair_hybrid = NULL;
|
||||||
last_omp_style = NULL;
|
last_omp_style = NULL;
|
||||||
const char *last_omp_name = NULL;
|
const char *last_omp_name = NULL;
|
||||||
const char *last_hybrid_name = NULL;
|
const char *last_hybrid_name = NULL;
|
||||||
const char *last_force_name = NULL;
|
const char *last_force_name = NULL;
|
||||||
|
|
||||||
|
// support for verlet/split operation.
|
||||||
|
// kspace_split == 0 : regular processing
|
||||||
|
// kspace_split < 0 : master partition, does not do kspace
|
||||||
|
// kspace_split > 0 : slave partition, only does kspace
|
||||||
|
if (strstr(update->integrate_style,"verlet/split") != NULL) {
|
||||||
|
if (universe->iworld == 0) kspace_split = -1;
|
||||||
|
else kspace_split = 1;
|
||||||
|
} else {
|
||||||
|
kspace_split = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// determine which is the last force style with OpenMP
|
// determine which is the last force style with OpenMP
|
||||||
// support as this is the one that has to reduce the forces
|
// support as this is the one that has to reduce the forces
|
||||||
|
|
||||||
#define CheckStyleForOMP(name) \
|
#define CheckStyleForOMP(name) \
|
||||||
check_hybrid = 0; \
|
check_hybrid = 0; \
|
||||||
if (force->name) { \
|
if (force->name) { \
|
||||||
if ( (strcmp(force->name ## _style,"hybrid") == 0) || \
|
if ( (strcmp(force->name ## _style,"hybrid") == 0) || \
|
||||||
(strcmp(force->name ## _style,"hybrid/overlay") == 0) ) \
|
(strcmp(force->name ## _style,"hybrid/overlay") == 0) ) \
|
||||||
check_hybrid=1; \
|
check_hybrid=1; \
|
||||||
if (force->name->suffix_flag & Suffix::OMP) { \
|
if (force->name->suffix_flag & Suffix::OMP) { \
|
||||||
last_force_name = (const char *) #name; \
|
last_force_name = (const char *) #name; \
|
||||||
last_omp_name = force->name ## _style; \
|
last_omp_name = force->name ## _style; \
|
||||||
last_omp_style = (void *) force->name; \
|
last_omp_style = (void *) force->name; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CheckHybridForOMP(name,Class) \
|
#define CheckHybridForOMP(name,Class) \
|
||||||
if (check_hybrid) { \
|
if (check_hybrid) { \
|
||||||
Class ## Hybrid *style = (Class ## Hybrid *) force->name; \
|
Class ## Hybrid *style = (Class ## Hybrid *) force->name; \
|
||||||
for (int i=0; i < style->nstyles; i++) { \
|
for (int i=0; i < style->nstyles; i++) { \
|
||||||
if (style->styles[i]->suffix_flag & Suffix::OMP) { \
|
if (style->styles[i]->suffix_flag & Suffix::OMP) { \
|
||||||
last_force_name = (const char *) #name; \
|
last_force_name = (const char *) #name; \
|
||||||
last_omp_name = style->keywords[i]; \
|
last_omp_name = style->keywords[i]; \
|
||||||
last_omp_style = style->styles[i]; \
|
last_omp_style = style->styles[i]; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckStyleForOMP(pair);
|
if (kspace_split <= 0) {
|
||||||
CheckHybridForOMP(pair,Pair);
|
CheckStyleForOMP(pair);
|
||||||
if (check_hybrid) {
|
CheckHybridForOMP(pair,Pair);
|
||||||
last_pair_hybrid = last_omp_style;
|
if (check_hybrid) {
|
||||||
last_hybrid_name = last_omp_name;
|
last_pair_hybrid = last_omp_style;
|
||||||
|
last_hybrid_name = last_omp_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckStyleForOMP(bond);
|
||||||
|
CheckHybridForOMP(bond,Bond);
|
||||||
|
|
||||||
|
CheckStyleForOMP(angle);
|
||||||
|
CheckHybridForOMP(angle,Angle);
|
||||||
|
|
||||||
|
CheckStyleForOMP(dihedral);
|
||||||
|
CheckHybridForOMP(dihedral,Dihedral);
|
||||||
|
|
||||||
|
CheckStyleForOMP(improper);
|
||||||
|
CheckHybridForOMP(improper,Improper);
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckStyleForOMP(bond);
|
if (kspace_split >= 0) {
|
||||||
CheckHybridForOMP(bond,Bond);
|
CheckStyleForOMP(kspace);
|
||||||
|
}
|
||||||
CheckStyleForOMP(angle);
|
|
||||||
CheckHybridForOMP(angle,Angle);
|
|
||||||
|
|
||||||
CheckStyleForOMP(dihedral);
|
|
||||||
CheckHybridForOMP(dihedral,Dihedral);
|
|
||||||
|
|
||||||
CheckStyleForOMP(improper);
|
|
||||||
CheckHybridForOMP(improper,Improper);
|
|
||||||
|
|
||||||
CheckStyleForOMP(kspace);
|
|
||||||
|
|
||||||
#undef CheckStyleForOMP
|
#undef CheckStyleForOMP
|
||||||
#undef CheckHybridForOMP
|
#undef CheckHybridForOMP
|
||||||
|
|||||||
@ -147,7 +147,7 @@ void ThrOMP::ev_setup_thr(int eflag, int vflag, int nall, double *eatom,
|
|||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
|
|
||||||
void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag,
|
void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag,
|
||||||
ThrData *const thr, const int nproxy)
|
ThrData *const thr)
|
||||||
{
|
{
|
||||||
const int nlocal = lmp->atom->nlocal;
|
const int nlocal = lmp->atom->nlocal;
|
||||||
const int nghost = lmp->atom->nghost;
|
const int nghost = lmp->atom->nghost;
|
||||||
@ -172,12 +172,7 @@ void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag,
|
|||||||
|
|
||||||
if (pair->vflag_fdotr) {
|
if (pair->vflag_fdotr) {
|
||||||
|
|
||||||
if (style == fix->last_pair_hybrid) {
|
if (fix->last_pair_hybrid) return;
|
||||||
// pair_style hybrid will compute fdotr for us
|
|
||||||
// but we first need to reduce the forces
|
|
||||||
data_reduce_thr(&(f[0][0]), nall, nthreads, 3, tid);
|
|
||||||
need_force_reduce = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is a non-hybrid pair style. compute per thread fdotr
|
// this is a non-hybrid pair style. compute per thread fdotr
|
||||||
if (fix->last_pair_hybrid == NULL) {
|
if (fix->last_pair_hybrid == NULL) {
|
||||||
@ -205,67 +200,7 @@ void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag,
|
|||||||
thr->virial_pair[i] = 0.0;
|
thr->virial_pair[i] = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (eflag & 2) {
|
|
||||||
data_reduce_thr(&(pair->eatom[0]), nall, nthreads, 1, tid);
|
|
||||||
}
|
|
||||||
if (vflag & 4) {
|
|
||||||
data_reduce_thr(&(pair->vatom[0][0]), nall, nthreads, 6, tid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case THR_PAIR|THR_PROXY: {
|
|
||||||
Pair * const pair = lmp->force->pair;
|
|
||||||
|
|
||||||
if (tid >= nproxy && pair->vflag_fdotr) {
|
|
||||||
|
|
||||||
if (fix->last_pair_hybrid) {
|
|
||||||
if (tid == nproxy)
|
|
||||||
lmp->error->all(FLERR,
|
|
||||||
"Cannot use hybrid pair style with kspace proxy");
|
|
||||||
else return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is a non-hybrid pair style. compute per thread fdotr
|
|
||||||
if (fix->last_pair_hybrid == NULL) {
|
|
||||||
if (lmp->neighbor->includegroup == 0)
|
|
||||||
thr->virial_fdotr_compute(x, nlocal, nghost, -1);
|
|
||||||
else
|
|
||||||
thr->virial_fdotr_compute(x, nlocal, nghost, nfirst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evflag) {
|
|
||||||
#if defined(_OPENMP)
|
|
||||||
#pragma omp critical
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (tid < nproxy) {
|
|
||||||
// nothing to collect for kspace proxy threads
|
|
||||||
// just reset pair accumulators to 0.0.
|
|
||||||
if (eflag & 1) {
|
|
||||||
thr->eng_vdwl = 0.0;
|
|
||||||
thr->eng_coul = 0.0;
|
|
||||||
}
|
|
||||||
if (vflag & 3)
|
|
||||||
for (int i=0; i < 6; ++i) {
|
|
||||||
thr->virial_pair[i] = 0.0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (eflag & 1) {
|
|
||||||
pair->eng_vdwl += thr->eng_vdwl;
|
|
||||||
pair->eng_coul += thr->eng_coul;
|
|
||||||
thr->eng_vdwl = 0.0;
|
|
||||||
thr->eng_coul = 0.0;
|
|
||||||
}
|
|
||||||
if (vflag & 3)
|
|
||||||
for (int i=0; i < 6; ++i) {
|
|
||||||
pair->virial[i] += thr->virial_pair[i];
|
|
||||||
thr->virial_pair[i] = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (eflag & 2) {
|
if (eflag & 2) {
|
||||||
data_reduce_thr(&(pair->eatom[0]), nall, nthreads, 1, tid);
|
data_reduce_thr(&(pair->eatom[0]), nall, nthreads, 1, tid);
|
||||||
}
|
}
|
||||||
@ -439,9 +374,8 @@ void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case THR_KSPACE|THR_PROXY: // fallthrough
|
|
||||||
case THR_KSPACE:
|
case THR_KSPACE:
|
||||||
// nothing to do
|
// nothing to do. XXX need to add support for per-atom info
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -58,7 +58,8 @@ class ThrOMP {
|
|||||||
|
|
||||||
enum {THR_NONE=0,THR_PAIR=1,THR_BOND=1<<1,THR_ANGLE=1<<2,
|
enum {THR_NONE=0,THR_PAIR=1,THR_BOND=1<<1,THR_ANGLE=1<<2,
|
||||||
THR_DIHEDRAL=1<<3,THR_IMPROPER=1<<4,THR_KSPACE=1<<5,
|
THR_DIHEDRAL=1<<3,THR_IMPROPER=1<<4,THR_KSPACE=1<<5,
|
||||||
THR_CHARMM=1<<6,THR_PROXY=1<<7,THR_HYBRID=1<<8,THR_FIX=1<<9};
|
THR_CHARMM=1<<6, /*THR_PROXY=1<<7,*/ THR_HYBRID=1<<8,
|
||||||
|
THR_FIX=1<<9};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// extra ev_tally setup work for threaded styles
|
// extra ev_tally setup work for threaded styles
|
||||||
@ -71,7 +72,7 @@ class ThrOMP {
|
|||||||
|
|
||||||
// reduce per thread data as needed
|
// reduce per thread data as needed
|
||||||
void reduce_thr(void * const style, const int eflag, const int vflag,
|
void reduce_thr(void * const style, const int eflag, const int vflag,
|
||||||
ThrData * const thr, const int nproxy=0);
|
ThrData * const thr);
|
||||||
|
|
||||||
// thread safe variant error abort support.
|
// thread safe variant error abort support.
|
||||||
// signals an error condition in any thread by making
|
// signals an error condition in any thread by making
|
||||||
@ -167,14 +168,14 @@ class ThrOMP {
|
|||||||
|
|
||||||
// set loop range thread id, and force array offset for threaded runs.
|
// set loop range thread id, and force array offset for threaded runs.
|
||||||
static inline void loop_setup_thr(int &ifrom, int &ito, int &tid,
|
static inline void loop_setup_thr(int &ifrom, int &ito, int &tid,
|
||||||
int inum, int nthreads, int nproxy=0)
|
int inum, int nthreads)
|
||||||
{
|
{
|
||||||
#if defined(_OPENMP)
|
#if defined(_OPENMP)
|
||||||
tid = omp_get_thread_num();
|
tid = omp_get_thread_num();
|
||||||
|
|
||||||
// each thread works on a fixed chunk of atoms.
|
// each thread works on a fixed chunk of atoms.
|
||||||
const int idelta = 1 + inum/(nthreads-nproxy);
|
const int idelta = 1 + inum/nthreads;
|
||||||
ifrom = (tid-nproxy)*idelta;
|
ifrom = tid*idelta;
|
||||||
ito = ((ifrom + idelta) > inum) ? inum : ifrom + idelta;
|
ito = ((ifrom + idelta) > inum) ? inum : ifrom + idelta;
|
||||||
#else
|
#else
|
||||||
tid = 0;
|
tid = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user