Commit ea2b01e8 authored by Trung Nguyen's avatar Trung Nguyen
Browse files

Refactored 3-body gpu styles to remove code duplication

parent 34fe2273
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -180,6 +180,8 @@ int * BaseThreeT::reset_nbors(const int nall, const int inum, const int nlist,
  if (!success)
    return NULL;

  _nall = nall;

  // originally the requirement that nall == nlist was enforced
  // to allow direct indexing neighbors of neighbors after re-arrangement
//  nbor->get_host3(nall,nlist,ilist,numj,firstneigh,block_size());
@@ -214,6 +216,8 @@ inline int BaseThreeT::build_nbor_list(const int inum, const int host_inum,
    return 0;
  atom->cast_copy_x(host_x,host_type);

  _nall = nall;

  int mn;
  nbor->build_nbor_list(host_x, nall, host_inum, nall, *atom, sublo, subhi, tag,
                        nspecial, special, success, mn);
+3 −3
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ class BaseThree {
  }

  /// Check if there is enough storage for neighbors and realloc if not
  /** \param nlocal number of particles whose nbors must be stored on device
  /** \param inum number of particles whose nbors must be stored on device
    * \param max_nbors maximum number of neighbors
    * \param success set to false if insufficient memory
    * \note olist_size=total number of local particles **/
@@ -83,7 +83,7 @@ class BaseThree {
  }

  /// Check if there is enough storage for neighbors and realloc if not
  /** \param nlocal number of particles whose nbors must be stored on device
  /** \param inum number of particles whose nbors must be stored on device
    * \param host_inum number of particles whose nbors need to copied to host
    * \param max_nbors current maximum number of neighbors
    * \note host_inum is 0 if the host is performing neighboring
@@ -203,7 +203,7 @@ class BaseThree {
  int _block_pair, _block_size, _threads_per_atom, _end_command_queue;
  int _gpu_nbor;
  double _max_bytes, _max_an_bytes;
  int _max_nbors, _ainum;
  int _max_nbors, _ainum, _nall;
  double _gpu_overhead, _driver_overhead;
  UCL_D_Vec<int> *_nbor_data;

+7 −145
Original line number Diff line number Diff line
@@ -225,151 +225,6 @@ double TersoffT::host_memory_usage() const {

#define KTHREADS this->_threads_per_atom
#define JTHREADS this->_threads_per_atom
// ---------------------------------------------------------------------------
// Copy nbor list from host if necessary and then calculate forces, virials,..
// ---------------------------------------------------------------------------
template <class numtyp, class acctyp>
void TersoffT::compute(const int f_ago, const int inum_full, const int nall,
                       const int nlist, double **host_x, int *host_type,
                       int *ilist, int *numj, int **firstneigh,
                       const bool eflag, const bool vflag, const bool eatom,
                       const bool vatom, int &host_start,
                       const double cpu_time, bool &success) {
  this->acc_timers();
  if (inum_full==0) {
    host_start=0;
    // Make sure textures are correct if realloc by a different hybrid style
    this->resize_atom(0,nall,success);
    this->zero_timers();
    return;
  }

  int ago=this->hd_balancer.ago_first(f_ago);
  int inum=this->hd_balancer.balance(ago,inum_full,cpu_time);
  this->ans->inum(inum);
  #ifdef THREE_CONCURRENT
  this->ans2->inum(inum);
  #endif
  host_start=inum;

  if (ago==0) {
    this->reset_nbors(nall, inum, nlist, ilist, numj, firstneigh, success);
    if (!success)
      return;
    this->_max_nbors = this->nbor->max_nbor_loop(nlist,numj,ilist);
  }

  this->atom->cast_x_data(host_x,host_type);
  this->hd_balancer.start_timer();
  this->atom->add_x_data(host_x,host_type);

  // re-allocate zetaij if necessary
  if (nall*this->_max_nbors > _zetaij.cols()) {
    int _nmax=static_cast<int>(static_cast<double>(nall)*1.10);
    _zetaij.resize(this->_max_nbors*_nmax);
  }

  this->_ainum=nlist;

  int _eflag;
  if (eflag)
    _eflag=1;
  else
    _eflag=0;

  int evatom=0;
  if (eatom || vatom)
    evatom=1;
  #ifdef THREE_CONCURRENT
  this->ucl_device->sync();
  #endif
  loop(eflag,vflag,evatom);
  this->ans->copy_answers(eflag,vflag,eatom,vatom,ilist);
  this->device->add_ans_object(this->ans);
  #ifdef THREE_CONCURRENT
  this->ans2->copy_answers(eflag,vflag,eatom,vatom,ilist);
  this->device->add_ans_object(this->ans2);
  #endif
  this->hd_balancer.stop_timer();
}

// ---------------------------------------------------------------------------
// Reneighbor on GPU if necessary and then compute forces, virials, energies
// ---------------------------------------------------------------------------
template <class numtyp, class acctyp>
int ** TersoffT::compute(const int ago, const int inum_full,
                         const int nall, double **host_x, int *host_type,
                         double *sublo, double *subhi, tagint *tag,
                         int **nspecial, tagint **special, const bool eflag,
                         const bool vflag, const bool eatom,
                         const bool vatom, int &host_start,
                         int **ilist, int **jnum,
                         const double cpu_time, bool &success) {
  this->acc_timers();

  if (inum_full==0) {
    host_start=0;
    // Make sure textures are correct if realloc by a different hybrid style
    this->resize_atom(0,nall,success);
    this->zero_timers();
    return NULL;
  }

  this->hd_balancer.balance(cpu_time);
  int inum=this->hd_balancer.get_gpu_count(ago,inum_full);
  this->ans->inum(inum);
  #ifdef THREE_CONCURRENT
  this->ans2->inum(inum);
  #endif
  host_start=inum;

  // Build neighbor list on GPU if necessary
  if (ago==0) {
    this->_max_nbors = this->build_nbor_list(inum, inum_full-inum, nall, host_x, host_type,
                    sublo, subhi, tag, nspecial, special, success);
    if (!success)
      return NULL;
    this->hd_balancer.start_timer();
  } else {
    this->atom->cast_x_data(host_x,host_type);
    this->hd_balancer.start_timer();
    this->atom->add_x_data(host_x,host_type);
  }
  *ilist=this->nbor->host_ilist.begin();
  *jnum=this->nbor->host_acc.begin();

  // re-allocate zetaij if necessary
  if (nall*this->_max_nbors > _zetaij.cols()) {
    int _nmax=static_cast<int>(static_cast<double>(nall)*1.10);
    _zetaij.resize(this->_max_nbors*_nmax);
  }

  this->_ainum=nall;

  int _eflag;
  if (eflag)
    _eflag=1;
  else
    _eflag=0;

  int evatom=0;
  if (eatom || vatom)
    evatom=1;
  #ifdef THREE_CONCURRENT
  this->ucl_device->sync();
  #endif
  loop(eflag,vflag,evatom);
  this->ans->copy_answers(eflag,vflag,eatom,vatom);
  this->device->add_ans_object(this->ans);
  #ifdef THREE_CONCURRENT
  this->ans2->copy_answers(eflag,vflag,eatom,vatom);
  this->device->add_ans_object(this->ans2);
  #endif
  this->hd_balancer.stop_timer();

  return this->nbor->host_jlist.begin()-host_start;
}

// ---------------------------------------------------------------------------
// Calculate energies, forces, and torques
// ---------------------------------------------------------------------------
@@ -400,6 +255,13 @@ void TersoffT::loop(const bool _eflag, const bool _vflag, const int evatom) {
                 &this->dev_short_nbor, &ainum,
                 &nbor_pitch, &this->_threads_per_atom);

  // re-allocate zetaij if necessary
  int nall = this->_nall;
  if (nall*this->_max_nbors > _zetaij.cols()) {
    int _nmax=static_cast<int>(static_cast<double>(nall)*1.10);
    _zetaij.resize(this->_max_nbors*_nmax);
  }

  nbor_pitch=this->nbor->nbor_pitch();
  GX=static_cast<int>(ceil(static_cast<double>(this->_ainum)/
                               (BX/(JTHREADS*KTHREADS))));
+0 −15
Original line number Diff line number Diff line
@@ -47,21 +47,6 @@ class Tersoff : public BaseThree<numtyp, acctyp> {
           const double* h, const double* gamma, const double* beta,
           const double* powern, const double* cutsq);

  /// Pair loop with host neighboring
  void compute(const int f_ago, const int inum_full, const int nall,
               const int nlist, double **host_x, int *host_type,
               int *ilist, int *numj, int **firstneigh, const bool eflag,
               const bool vflag, const bool eatom, const bool vatom,
               int &host_start, const double cpu_time, bool &success);

  /// Pair loop with device neighboring
  int ** compute(const int ago, const int inum_full,
                 const int nall, double **host_x, int *host_type, double *sublo,
                 double *subhi, tagint *tag, int **nspecial,
                 tagint **special, const bool eflag, const bool vflag,
                 const bool eatom, const bool vatom, int &host_start,
                 int **ilist, int **numj, const double cpu_time, bool &success);

  /// Clear all host and device data
  /** \note This is called at the beginning of the init() routine **/
  void clear();
+7 −169
Original line number Diff line number Diff line
@@ -225,175 +225,6 @@ double TersoffMT::host_memory_usage() const {

#define KTHREADS this->_threads_per_atom
#define JTHREADS this->_threads_per_atom
// ---------------------------------------------------------------------------
// Copy nbor list from host if necessary and then calculate forces, virials,..
// ---------------------------------------------------------------------------
template <class numtyp, class acctyp>
void TersoffMT::compute(const int f_ago, const int inum_full, const int nall,
                       const int nlist, double **host_x, int *host_type,
                       int *ilist, int *numj, int **firstneigh,
                       const bool eflag, const bool vflag, const bool eatom,
                       const bool vatom, int &host_start,
                       const double cpu_time, bool &success) {
  this->acc_timers();
  if (inum_full==0) {
    host_start=0;
    // Make sure textures are correct if realloc by a different hybrid style
    this->resize_atom(0,nall,success);
    this->zero_timers();
    return;
  }

  int ago=this->hd_balancer.ago_first(f_ago);
  int inum=this->hd_balancer.balance(ago,inum_full,cpu_time);
  this->ans->inum(inum);
  #ifdef THREE_CONCURRENT
  this->ans2->inum(inum);
  #endif
  host_start=inum;

  if (ago==0) {
    this->reset_nbors(nall, inum, nlist, ilist, numj, firstneigh, success);
    if (!success)
      return;
    this->_max_nbors = this->nbor->max_nbor_loop(nlist,numj,ilist);
  }

  this->atom->cast_x_data(host_x,host_type);
  this->hd_balancer.start_timer();
  this->atom->add_x_data(host_x,host_type);

  // re-allocate zetaij if necessary
  if (nall*this->_max_nbors > _zetaij.cols()) {
    int _nmax=static_cast<int>(static_cast<double>(nall)*1.10);
    _zetaij.resize(this->_max_nbors*_nmax);
  }

  this->_ainum=nlist;

  int _eflag;
  if (eflag)
    _eflag=1;
  else
    _eflag=0;

  int ainum=nlist;
  int nbor_pitch=this->nbor->nbor_pitch();
  int BX=this->block_pair();
  int GX=static_cast<int>(ceil(static_cast<double>(ainum)/
                               (BX/(JTHREADS*KTHREADS))));

  this->k_zeta.set_size(GX,BX);
  this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &cutsq,
                   &map, &elem2param, &_nelements, &_nparams, &_zetaij,
                   &this->nbor->dev_nbor, &this->_nbor_data->begin(),
                   &_eflag, &ainum, &nbor_pitch, &this->_threads_per_atom);

  int evatom=0;
  if (eatom || vatom)
    evatom=1;
  #ifdef THREE_CONCURRENT
  this->ucl_device->sync();
  #endif
  loop(eflag,vflag,evatom);
  this->ans->copy_answers(eflag,vflag,eatom,vatom,ilist);
  this->device->add_ans_object(this->ans);
  #ifdef THREE_CONCURRENT
  this->ans2->copy_answers(eflag,vflag,eatom,vatom,ilist);
  this->device->add_ans_object(this->ans2);
  #endif
  this->hd_balancer.stop_timer();
}

// ---------------------------------------------------------------------------
// Reneighbor on GPU if necessary and then compute forces, virials, energies
// ---------------------------------------------------------------------------
template <class numtyp, class acctyp>
int ** TersoffMT::compute(const int ago, const int inum_full,
                         const int nall, double **host_x, int *host_type,
                         double *sublo, double *subhi, tagint *tag,
                         int **nspecial, tagint **special, const bool eflag,
                         const bool vflag, const bool eatom,
                         const bool vatom, int &host_start,
                         int **ilist, int **jnum,
                         const double cpu_time, bool &success) {
  this->acc_timers();

  if (inum_full==0) {
    host_start=0;
    // Make sure textures are correct if realloc by a different hybrid style
    this->resize_atom(0,nall,success);
    this->zero_timers();
    return NULL;
  }

  this->hd_balancer.balance(cpu_time);
  int inum=this->hd_balancer.get_gpu_count(ago,inum_full);
  this->ans->inum(inum);
  #ifdef THREE_CONCURRENT
  this->ans2->inum(inum);
  #endif
  host_start=inum;

  // Build neighbor list on GPU if necessary
  if (ago==0) {
    this->_max_nbors = this->build_nbor_list(inum, inum_full-inum, nall, host_x, host_type,
                    sublo, subhi, tag, nspecial, special, success);
    if (!success)
      return NULL;
    this->hd_balancer.start_timer();
  } else {
    this->atom->cast_x_data(host_x,host_type);
    this->hd_balancer.start_timer();
    this->atom->add_x_data(host_x,host_type);
  }
  *ilist=this->nbor->host_ilist.begin();
  *jnum=this->nbor->host_acc.begin();

  // re-allocate zetaij if necessary
  if (nall*this->_max_nbors > _zetaij.cols()) {
    int _nmax=static_cast<int>(static_cast<double>(nall)*1.10);
    _zetaij.resize(this->_max_nbors*_nmax);
  }

  this->_ainum=nall;

  int _eflag;
  if (eflag)
    _eflag=1;
  else
    _eflag=0;

  int ainum=nall;
  int nbor_pitch=this->nbor->nbor_pitch();
  int BX=this->block_pair();
  int GX=static_cast<int>(ceil(static_cast<double>(ainum)/
                               (BX/(JTHREADS*KTHREADS))));

  this->k_zeta.set_size(GX,BX);
  this->k_zeta.run(&this->atom->x, &ts1, &ts2, &ts3, &ts4, &ts5, &cutsq,
                   &map, &elem2param, &_nelements, &_nparams, &_zetaij,
                   &this->nbor->dev_nbor, &this->_nbor_data->begin(),
                   &_eflag, &ainum, &nbor_pitch, &this->_threads_per_atom);

  int evatom=0;
  if (eatom || vatom)
    evatom=1;
  #ifdef THREE_CONCURRENT
  this->ucl_device->sync();
  #endif
  loop(eflag,vflag,evatom);
  this->ans->copy_answers(eflag,vflag,eatom,vatom);
  this->device->add_ans_object(this->ans);
  #ifdef THREE_CONCURRENT
  this->ans2->copy_answers(eflag,vflag,eatom,vatom);
  this->device->add_ans_object(this->ans2);
  #endif
  this->hd_balancer.stop_timer();

  return this->nbor->host_jlist.begin()-host_start;
}

// ---------------------------------------------------------------------------
// Calculate energies, forces, and torques
// ---------------------------------------------------------------------------
@@ -424,6 +255,13 @@ void TersoffMT::loop(const bool _eflag, const bool _vflag, const int evatom) {
                 &this->dev_short_nbor, &ainum,
                 &nbor_pitch, &this->_threads_per_atom);

  // re-allocate zetaij if necessary
  int nall = this->_nall;
  if (nall*this->_max_nbors > _zetaij.cols()) {
    int _nmax=static_cast<int>(static_cast<double>(nall)*1.10);
    _zetaij.resize(this->_max_nbors*_nmax);
  }

  nbor_pitch=this->nbor->nbor_pitch();
  GX=static_cast<int>(ceil(static_cast<double>(this->_ainum)/
                               (BX/(JTHREADS*KTHREADS))));
Loading