diff --git a/src/imbalance.cpp b/src/imbalance.cpp new file mode 100644 index 0000000000..181775e337 --- /dev/null +++ b/src/imbalance.cpp @@ -0,0 +1,20 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "imbalance.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +Imbalance::Imbalance(LAMMPS *lmp) : Pointers(lmp) {} diff --git a/src/imbalance.h b/src/imbalance.h new file mode 100644 index 0000000000..14fd1b59b2 --- /dev/null +++ b/src/imbalance.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef LMP_IMBALANCE_H +#define LMP_IMBALANCE_H + +#include +#include "pointers.h" + +namespace LAMMPS_NS { + +class Imbalance : protected Pointers { + public: + Imbalance(class LAMMPS *); + virtual ~Imbalance() {}; + + // parse options. return number of arguments consumed (required) + virtual int options(int narg, char **arg) = 0; + // reinitialize internal data (needed for fix balance) (optional) + virtual void init() {}; + // compute and apply weight factors to local atom array (required) + virtual void compute(double *weights) = 0; + // print information about the state of this imbalance compute (required) + virtual void info(FILE *fp) = 0; + + // disallow default and copy constructor, assignment operator + // private: + //Imbalance() {}; + //Imbalance(const Imbalance &) {}; + //Imbalance &operator=(const Imbalance &) {return *this;}; +}; + +} + +#endif diff --git a/src/imbalance_group.cpp b/src/imbalance_group.cpp new file mode 100644 index 0000000000..54eac47c83 --- /dev/null +++ b/src/imbalance_group.cpp @@ -0,0 +1,89 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "imbalance_group.h" +#include "atom.h" +#include "force.h" +#include "group.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* -------------------------------------------------------------------- */ + +ImbalanceGroup::ImbalanceGroup(LAMMPS *lmp) : Imbalance(lmp), id(0), factor(0) +{} + +/* -------------------------------------------------------------------- */ + +ImbalanceGroup::~ImbalanceGroup() +{ + delete [] id; + delete [] factor; +} + +/* -------------------------------------------------------------------- */ + +int ImbalanceGroup::options(int narg, char **arg) +{ + if (narg < 3) error->all(FLERR,"Illegal balance weight command"); + + num = force->inumeric(FLERR,arg[0]); + if (num < 1) error->all(FLERR,"Illegal balance weight command"); + if (2*num+1 > narg) error->all(FLERR,"Illegal balance weight command"); + + id = new int[num]; + factor = new double[num]; + for (int i = 0; i < num; ++i) { + id[i] = group->find(arg[2*i+1]); + if (id[i] < 0) + error->all(FLERR,"Unknown group in balance weight command"); + factor[i] = force->numeric(FLERR,arg[2*i+2]); + } + return 2*num+1; +} + +/* -------------------------------------------------------------------- */ + +void ImbalanceGroup::compute(double *weight) +{ + const int * const mask = atom->mask; + const int * const bitmask = group->bitmask; + const int nlocal = atom->nlocal; + + if (num == 0) return; + + for (int i = 0; i < nlocal; ++i) { + const int imask = mask[i]; + double iweight = weight[i]; + for (int j = 0; j < num; ++j) { + if (imask & bitmask[id[j]]) + iweight *= factor[j]; + } + weight[i] = iweight; + } +} + +/* -------------------------------------------------------------------- */ + +void ImbalanceGroup::info(FILE *fp) +{ + if (num > 0) { + const char * const * const names = group->names; + + fprintf(fp," group weights:"); + for (int i = 0; i < num; ++i) + fprintf(fp," %s=%g",names[id[i]],factor[i]); + fputs("\n",fp); + } +} diff --git a/src/imbalance_group.h b/src/imbalance_group.h new file mode 100644 index 0000000000..b3961ea389 --- /dev/null +++ b/src/imbalance_group.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef LMP_IMBALANCE_GROUP_H +#define LMP_IMBALANCE_GROUP_H + +#include "imbalance.h" + +namespace LAMMPS_NS { + +class ImbalanceGroup : public Imbalance { + public: + ImbalanceGroup(class LAMMPS *); + virtual ~ImbalanceGroup(); + + // parse options, return number of arguments consumed + virtual int options(int, char **); + // compute and apply weight factors to local atom array + virtual void compute(double *); + // print information about the state of this imbalance compute + virtual void info(FILE *); + + private: + int num; // number of groups with weights + int *id; // numerical IDs of groups + double *factor; // group weight factors +}; + +} + +#endif diff --git a/src/imbalance_neigh.cpp b/src/imbalance_neigh.cpp new file mode 100644 index 0000000000..d4de27fed4 --- /dev/null +++ b/src/imbalance_neigh.cpp @@ -0,0 +1,102 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "imbalance_neigh.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "neighbor.h" +#include "neigh_request.h" +#include "neigh_list.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* -------------------------------------------------------------------- */ + +ImbalanceNeigh::ImbalanceNeigh(LAMMPS *lmp) : Imbalance(lmp) +{ + did_warn = 0; +} + +/* -------------------------------------------------------------------- */ + +int ImbalanceNeigh::options(int narg, char **arg) +{ + if (narg < 1) error->all(FLERR,"Illegal balance weight command"); + factor = force->numeric(FLERR,arg[0]); + if (factor < 0.0) error->all(FLERR,"Illegal balance weight command"); + return 1; +} + +/* -------------------------------------------------------------------- */ + +void ImbalanceNeigh::compute(double *weight) +{ + int req; + + if (factor == 0.0) return; + + // find suitable neighbor list + // we can only make use of certain (conventional) neighbor lists + + for (req = 0; req < neighbor->old_nrequest; ++req) { + if ((neighbor->old_requests[req]->half || + neighbor->old_requests[req]->gran || + neighbor->old_requests[req]->respaouter || + neighbor->old_requests[req]->half_from_full) && + neighbor->old_requests[req]->skip == 0 && + neighbor->lists[req] && neighbor->lists[req]->numneigh) break; + } + + if (req >= neighbor->old_nrequest || neighbor->ago < 0) { + if (comm->me == 0 && !did_warn) + error->warning(FLERR,"No suitable neighbor list found. " + "Neighbor weighted balancing skipped"); + did_warn = 1; + return; + } + + NeighList *list = neighbor->lists[req]; + bigint neighsum = 0; + + const int inum = list->inum; + const int * const ilist = list->ilist; + const int * const numneigh = list->numneigh; + + // first pass: get local number of neighbors + + for (int i = 0; i < inum; ++i) neighsum += numneigh[ilist[i]]; + + double allatoms = static_cast (atom->natoms); + if (allatoms == 0.0) allatoms = 1.0; + double allavg; + double myavg = static_cast(neighsum)/allatoms; + MPI_Allreduce(&myavg,&allavg,1,MPI_DOUBLE,MPI_SUM,world); + + // second pass: compute and apply weights + + double scale = 1.0/allavg; + for (int ii = 0; ii < inum; ++ii) { + const int i = ilist[ii]; + weight[i] *= (1.0-factor) + factor*scale*numneigh[i]; + } +} + +/* -------------------------------------------------------------------- */ + +void ImbalanceNeigh::info(FILE *fp) +{ + fprintf(fp," neigh weight factor: %g\n",factor); +} diff --git a/src/imbalance_neigh.h b/src/imbalance_neigh.h new file mode 100644 index 0000000000..e905d3e1c0 --- /dev/null +++ b/src/imbalance_neigh.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef LMP_IMBALANCE_NEIGH_H +#define LMP_IMBALANCE_NEIGH_H + +#include "imbalance.h" + +namespace LAMMPS_NS { + +class ImbalanceNeigh : public Imbalance { + public: + ImbalanceNeigh(class LAMMPS *); + virtual ~ImbalanceNeigh() {} + + public: + // parse options, return number of arguments consumed + virtual int options(int, char **); + // compute and apply weight factors to local atom array + virtual void compute(double *); + // print information about the state of this imbalance compute + virtual void info(FILE *); + + private: + double factor; // weight factor for neighbor imbalance + int did_warn; // 1 if warned about no suitable neighbor list +}; + +} + +#endif diff --git a/src/imbalance_store.cpp b/src/imbalance_store.cpp new file mode 100644 index 0000000000..26dd47fb1b --- /dev/null +++ b/src/imbalance_store.cpp @@ -0,0 +1,69 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "imbalance_store.h" +#include "atom.h" +#include "input.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* -------------------------------------------------------------------- */ + +ImbalanceStore::ImbalanceStore(LAMMPS *lmp) : Imbalance(lmp), name(0) {} + +/* -------------------------------------------------------------------- */ + +ImbalanceStore::~ImbalanceStore() +{ + delete [] name; +} + +/* -------------------------------------------------------------------- */ + +int ImbalanceStore::options(int narg, char **arg) +{ + if (narg < 1) error->all(FLERR,"Illegal balance weight command"); + + int len = strlen(arg[0]) + 1; + name = new char[len]; + memcpy(name,arg[0],len); + + return 1; +} + +/* -------------------------------------------------------------------- */ + +void ImbalanceStore::compute(double *weight) +{ + int dflag = 0; + int idx = atom->find_custom(name,dflag); + + // property does not exist + + if (idx < 0 || dflag != 1) return; + + double *prop = atom->dvector[idx]; + const int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; ++i) + prop[i] = weight[i]; +} + +/* -------------------------------------------------------------------- */ + +void ImbalanceStore::info(FILE *fp) +{ + fprintf(fp," storing weight in atom property d_%s\n",name); +} diff --git a/src/imbalance_store.h b/src/imbalance_store.h new file mode 100644 index 0000000000..74f200ecbf --- /dev/null +++ b/src/imbalance_store.h @@ -0,0 +1,40 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef LMP_IMBALANCE_STORE_H +#define LMP_IMBALANCE_STORE_H + +#include "imbalance.h" + +namespace LAMMPS_NS { + +class ImbalanceStore : public Imbalance { + public: + ImbalanceStore(class LAMMPS *); + virtual ~ImbalanceStore(); + + public: + // parse options, return number of arguments consumed + virtual int options(int, char **); + // compute per-atom imbalance and apply to weight array + virtual void compute(double *); + // print information about the state of this imbalance compute (required) + virtual void info(FILE *); + + private: + char *name; // property name +}; + +} + +#endif diff --git a/src/imbalance_time.cpp b/src/imbalance_time.cpp new file mode 100644 index 0000000000..f8ec4343e2 --- /dev/null +++ b/src/imbalance_time.cpp @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "imbalance_time.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "timer.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* -------------------------------------------------------------------- */ + +ImbalanceTime::ImbalanceTime(LAMMPS *lmp) : Imbalance(lmp) {} + +/* -------------------------------------------------------------------- */ + +int ImbalanceTime::options(int narg, char **arg) +{ + if (narg < 1) error->all(FLERR,"Illegal balance weight command"); + factor = force->numeric(FLERR,arg[0]); + if (factor < 0.0) error->all(FLERR,"Illegal balance weight command"); + return 1; +} + +/* ---------------------------------------------------------------------- + reset last, needed for fix balance caller +------------------------------------------------------------------------- */ + +void ImbalanceTime::init() +{ + last = 0.0; +} + +/* -------------------------------------------------------------------- */ + +void ImbalanceTime::compute(double *weight) +{ + const int nlocal = atom->nlocal; + const bigint natoms = atom->natoms; + + if (factor == 0.0) return; + + // compute the cost function of based on relevant timers + + if (timer->has_normal()) { + double cost = -last; + cost += timer->get_wall(Timer::PAIR); + cost += timer->get_wall(Timer::NEIGH); + cost += timer->get_wall(Timer::BOND); + cost += timer->get_wall(Timer::KSPACE); + + double allcost; + MPI_Allreduce(&cost,&allcost,1,MPI_DOUBLE,MPI_SUM,world); + + if ((allcost > 0.0) && (nlocal > 0)) { + const double avgcost = allcost/natoms; + const double localcost = cost/nlocal; + const double scale = (1.0-factor) + factor*localcost/avgcost; + for (int i = 0; i < nlocal; ++i) weight[i] *= scale; + } + + // record time up to this point + + last += cost; + } +} + +/* -------------------------------------------------------------------- */ + +void ImbalanceTime::info(FILE *fp) +{ + fprintf(fp," time weight factor: %g\n",factor); +} diff --git a/src/imbalance_time.h b/src/imbalance_time.h new file mode 100644 index 0000000000..76ba9aa985 --- /dev/null +++ b/src/imbalance_time.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef LMP_IMBALANCE_TIME_H +#define LMP_IMBALANCE_TIME_H + +#include "imbalance.h" + +namespace LAMMPS_NS { + +class ImbalanceTime : public Imbalance { + public: + ImbalanceTime(class LAMMPS *); + virtual ~ImbalanceTime() {} + + public: + // parse options, return number of arguments consumed + virtual int options(int, char **); + // reinitialize internal data + virtual void init(); + // compute and apply weight factors to local atom array + virtual void compute(double *); + // print information about the state of this imbalance compute + virtual void info(FILE *); + + private: + double factor; // weight factor for time imbalance + double last; // combined wall time from last call +}; + +} + +#endif diff --git a/src/imbalance_var.cpp b/src/imbalance_var.cpp new file mode 100644 index 0000000000..81c7c4b354 --- /dev/null +++ b/src/imbalance_var.cpp @@ -0,0 +1,88 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "imbalance_var.h" +#include "atom.h" +#include "group.h" +#include "input.h" +#include "variable.h" +#include "memory.h" +#include "error.h" + +// DEBUG +#include "update.h" + +using namespace LAMMPS_NS; + +/* -------------------------------------------------------------------- */ + +ImbalanceVar::ImbalanceVar(LAMMPS *lmp) : Imbalance(lmp), name(0) {} + +/* -------------------------------------------------------------------- */ + +ImbalanceVar::~ImbalanceVar() +{ + delete [] name; +} + +/* -------------------------------------------------------------------- */ + +int ImbalanceVar::options(int narg, char **arg) +{ + if (narg < 1) error->all(FLERR,"Illegal balance weight command"); + + int len = strlen(arg[0]) + 1; + name = new char[len]; + memcpy(name,arg[0],len); + init(); + + return 1; +} + +/* -------------------------------------------------------------------- */ + +void ImbalanceVar::init() +{ + id = input->variable->find(name); + if (id < 0) { + error->all(FLERR,"Variable name for balance weight does not exist"); + } else { + if (input->variable->atomstyle(id) == 0) + error->all(FLERR,"Variable for balance weight has invalid style"); + } +} + +/* -------------------------------------------------------------------- */ + +void ImbalanceVar::compute(double *weight) +{ + const int all = group->find("all"); + if (all < 0) return; + + double *values; + const int nlocal = atom->nlocal; + memory->create(values,nlocal,"imbalance:values"); + + input->variable->compute_atom(id,all,values,1,0); + for (int i = 0; i < nlocal; ++i) weight[i] *= values[i]; + + memory->destroy(values); +} + +/* -------------------------------------------------------------------- */ + +void ImbalanceVar::info(FILE *fp) +{ + fprintf(fp," weight variable: %s\n",name); +} diff --git a/src/imbalance_var.h b/src/imbalance_var.h new file mode 100644 index 0000000000..16c59eb0de --- /dev/null +++ b/src/imbalance_var.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef LMP_IMBALANCE_VAR_H +#define LMP_IMBALANCE_VAR_H + +#include "imbalance.h" + +namespace LAMMPS_NS { + +class ImbalanceVar : public Imbalance { + public: + ImbalanceVar(class LAMMPS *); + virtual ~ImbalanceVar(); + + public: + // parse options. return number of arguments consumed. + virtual int options(int, char **); + // re-initialize internal data, e.g. variable ID + virtual void init(); + // compute per-atom imbalance and apply to weight array + virtual void compute(double *); + // print information about the state of this imbalance compute (required) + virtual void info(FILE *); + + private: + char *name; // variable name + int id; // variable index +}; + +} + +#endif