Commit eeff0b86 authored by Anders Hafreager's avatar Anders Hafreager
Browse files

Added vashishta GPU package for NVidia

parent 286d4f27
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ OBJS = $(OBJ_DIR)/lal_atom.o $(OBJ_DIR)/lal_ans.o \
       $(OBJ_DIR)/lal_lj_coul_debye.o $(OBJ_DIR)/lal_lj_coul_debye_ext.o \
       $(OBJ_DIR)/lal_coul_dsf.o $(OBJ_DIR)/lal_coul_dsf_ext.o \
       $(OBJ_DIR)/lal_sw.o $(OBJ_DIR)/lal_sw_ext.o \
       $(OBJ_DIR)/lal_vashishta.o $(OBJ_DIR)/lal_vashishta_ext.o \
       $(OBJ_DIR)/lal_beck.o $(OBJ_DIR)/lal_beck_ext.o \
       $(OBJ_DIR)/lal_mie.o $(OBJ_DIR)/lal_mie_ext.o \
       $(OBJ_DIR)/lal_soft.o $(OBJ_DIR)/lal_soft_ext.o \
@@ -117,6 +118,7 @@ CBNS = $(OBJ_DIR)/device.cubin $(OBJ_DIR)/device_cubin.h \
       $(OBJ_DIR)/lj_coul_debye.cubin $(OBJ_DIR)/lj_coul_debye_cubin.h \
       $(OBJ_DIR)/coul_dsf.cubin $(OBJ_DIR)/coul_dsf_cubin.h \
       $(OBJ_DIR)/sw.cubin $(OBJ_DIR)/sw_cubin.h \
       $(OBJ_DIR)/vashishta.cubin $(OBJ_DIR)/vashishta_cubin.h \
       $(OBJ_DIR)/beck.cubin $(OBJ_DIR)/beck_cubin.h \
       $(OBJ_DIR)/mie.cubin $(OBJ_DIR)/mie_cubin.h \
       $(OBJ_DIR)/soft.cubin $(OBJ_DIR)/soft_cubin.h \
@@ -613,6 +615,18 @@ $(OBJ_DIR)/lal_coul_dsf.o: $(ALL_H) lal_coul_dsf.h lal_coul_dsf.cpp $(OBJ_DIR)/c
$(OBJ_DIR)/lal_coul_dsf_ext.o: $(ALL_H) lal_coul_dsf.h lal_coul_dsf_ext.cpp lal_base_charge.h
	$(CUDR) -o $@ -c lal_coul_dsf_ext.cpp -I$(OBJ_DIR)

$(OBJ_DIR)/vashishta.cubin: lal_vashishta.cu lal_precision.h lal_preprocessor.h
	$(CUDA) --cubin -DNV_KERNEL -o $@ lal_vashishta.cu

$(OBJ_DIR)/vashishta_cubin.h: $(OBJ_DIR)/vashishta.cubin $(OBJ_DIR)/vashishta.cubin
	$(BIN2C) -c -n vashishta $(OBJ_DIR)/vashishta.cubin > $(OBJ_DIR)/vashishta_cubin.h

$(OBJ_DIR)/lal_vashishta.o: $(ALL_H) lal_vashishta.h lal_vashishta.cpp $(OBJ_DIR)/vashishta_cubin.h $(OBJ_DIR)/lal_base_three.o
	$(CUDR) -o $@ -c lal_vashishta.cpp -I$(OBJ_DIR)

$(OBJ_DIR)/lal_vashishta_ext.o: $(ALL_H) lal_vashishta.h lal_vashishta_ext.cpp lal_base_three.h
	$(CUDR) -o $@ -c lal_vashishta_ext.cpp -I$(OBJ_DIR)

$(OBJ_DIR)/sw.cubin: lal_sw.cu lal_precision.h lal_preprocessor.h
	$(CUDA) --cubin -DNV_KERNEL -o $@ lal_sw.cu

+283 −0
Original line number Diff line number Diff line
/***************************************************************************
                                vashishta.cpp
                             -------------------
                            Anders Hafreager (UiO)

  Class for acceleration of the vashishta pair style.

 __________________________________________________________________________
    This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
 __________________________________________________________________________

    begin                : Mon June 12, 2017
    email                : andershaf@gmail.com
 ***************************************************************************/

#if defined(USE_OPENCL)
#include "vashishta_cl.h"
#elif defined(USE_CUDART)
const char *vashishta=0;
#else
#include "vashishta_cubin.h"
#endif

#include "lal_vashishta.h"
#include <cassert>
using namespace LAMMPS_AL;
#define VashishtaT Vashishta<numtyp, acctyp>

extern Device<PRECISION,ACC_PRECISION> device;

template <class numtyp, class acctyp>
VashishtaT::Vashishta() : BaseThree<numtyp,acctyp>(), _allocated(false) {
}

template <class numtyp, class acctyp>
VashishtaT::~Vashishta() {
  clear();
}

template <class numtyp, class acctyp>
int VashishtaT::bytes_per_atom(const int max_nbors) const {
  return this->bytes_per_atom_atomic(max_nbors);
}

template <class numtyp, class acctyp>
int VashishtaT::init(const int ntypes, const int nlocal, const int nall, const int max_nbors,
           const double cell_size, const double gpu_split, FILE *_screen,
           int* host_map, const int nelements, int*** host_elem2param, const int nparams,
           const double* cutsq, const double* r0,
           const double* gamma, const double* eta,
           const double* lam1inv, const double* lam4inv,
           const double* zizj, const double* mbigd,
           const double* dvrc, const double* big6w, 
           const double* heta, const double* bigh,
           const double* bigw, const double* c0,
           const double* costheta, const double* bigb,
           const double* big2b, const double* bigc)
{
  int success;
  success=this->init_three(nlocal,nall,max_nbors,0,cell_size,gpu_split,
                           _screen,vashishta,"k_vashishta","k_vashishta_three_center",
                           "k_vashishta_three_end");
  if (success!=0)
    return success;

  // If atom type constants fit in shared memory use fast kernel
  int lj_types=ntypes;
  shared_types=false;
  int max_shared_types=this->device->max_shared_types();
  if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) {
    lj_types=max_shared_types;
    shared_types=true;
  }
  _lj_types=lj_types;

  _nparams = nparams;
  _nelements = nelements;

  UCL_H_Vec<numtyp4> dview(nparams,*(this->ucl_device),
                             UCL_WRITE_ONLY);

  for (int i=0; i<nparams; i++) {
    dview[i].x=(numtyp)0;
    dview[i].y=(numtyp)0;
    dview[i].z=(numtyp)0;
    dview[i].w=(numtyp)0;
  }

  // pack coefficients into arrays
  param1.alloc(nparams,*(this->ucl_device),UCL_READ_ONLY);

  for (int i=0; i<nparams; i++) {
    dview[i].x=static_cast<numtyp>(eta[i]);
    dview[i].y=static_cast<numtyp>(lam1inv[i]);
    dview[i].z=static_cast<numtyp>(lam4inv[i]);
    dview[i].w=static_cast<numtyp>(zizj[i]);
  }

  ucl_copy(param1,dview,false);
  param1_tex.get_texture(*(this->pair_program),"param1_tex");
  param1_tex.bind_float(param1,4);

  param2.alloc(nparams,*(this->ucl_device),UCL_READ_ONLY);

  for (int i=0; i<nparams; i++) {
    dview[i].x=static_cast<numtyp>(mbigd[i]);
    dview[i].y=static_cast<numtyp>(dvrc[i]);
    dview[i].z=static_cast<numtyp>(big6w[i]);
    dview[i].w=static_cast<numtyp>(heta[i]);
  }

  ucl_copy(param2,dview,false);
  param2_tex.get_texture(*(this->pair_program),"param2_tex");
  param2_tex.bind_float(param2,4);

  param3.alloc(nparams,*(this->ucl_device),UCL_READ_ONLY);

  for (int i=0; i<nparams; i++) {
    dview[i].x=static_cast<numtyp>(bigh[i]);
    dview[i].y=static_cast<numtyp>(bigw[i]);
    dview[i].z=static_cast<numtyp>(dvrc[i]);
    dview[i].w=static_cast<numtyp>(c0[i]);
  }

  ucl_copy(param3,dview,false);
  param3_tex.get_texture(*(this->pair_program),"param3_tex");
  param3_tex.bind_float(param3,4);

  param4.alloc(nparams,*(this->ucl_device),UCL_READ_ONLY);

  for (int i=0; i<nparams; i++) {
    double r0sq = r0[i]*r0[i]-1e-4; // TODO: should we have the 1e-4?

    dview[i].x=static_cast<numtyp>(r0sq);
    dview[i].y=static_cast<numtyp>(gamma[i]);
    dview[i].z=static_cast<numtyp>(cutsq[i]);
    dview[i].w=static_cast<numtyp>(r0[i]);
  }

  ucl_copy(param4,dview,false);
  param4_tex.get_texture(*(this->pair_program),"param4_tex");
  param4_tex.bind_float(param4,4);

  param5.alloc(nparams,*(this->ucl_device),UCL_READ_ONLY);

  for (int i=0; i<nparams; i++) {
    dview[i].x=static_cast<numtyp>(bigc[i]);
    dview[i].y=static_cast<numtyp>(costheta[i]);
    dview[i].z=static_cast<numtyp>(bigb[i]);
    dview[i].w=static_cast<numtyp>(big2b[i]);
  }

  ucl_copy(param5,dview,false);
  param5_tex.get_texture(*(this->pair_program),"param5_tex");
  param5_tex.bind_float(param5,4);

  UCL_H_Vec<int> dview_elem2param(nelements*nelements*nelements,
                           *(this->ucl_device), UCL_WRITE_ONLY);

  elem2param.alloc(nelements*nelements*nelements,*(this->ucl_device),
                   UCL_READ_ONLY);

  for (int i = 0; i < nelements; i++)
    for (int j = 0; j < nelements; j++)
      for (int k = 0; k < nelements; k++) {
         int idx = i*nelements*nelements+j*nelements+k;
         dview_elem2param[idx] = host_elem2param[i][j][k];
      }

  ucl_copy(elem2param,dview_elem2param,false);

  UCL_H_Vec<int> dview_map(lj_types, *(this->ucl_device), UCL_WRITE_ONLY);
  for (int i = 0; i < ntypes; i++)
    dview_map[i] = host_map[i];

  map.alloc(lj_types,*(this->ucl_device), UCL_READ_ONLY);
  ucl_copy(map,dview_map,false);

  _allocated=true;
  this->_max_bytes=param1.row_bytes()+param2.row_bytes()+param3.row_bytes()+param4.row_bytes()+param5.row_bytes()+
    map.row_bytes()+elem2param.row_bytes();
  return 0;
}

template <class numtyp, class acctyp>
void VashishtaT::clear() {
  if (!_allocated)
    return;
  _allocated=false;

  param1.clear();
  param2.clear();
  param3.clear();
  param4.clear();
  param5.clear();
  map.clear();
  elem2param.clear();
  this->clear_atomic();
}

template <class numtyp, class acctyp>
double VashishtaT::host_memory_usage() const {
  return this->host_memory_usage_atomic()+sizeof(Vashishta<numtyp,acctyp>);
}

#define KTHREADS this->_threads_per_atom
#define JTHREADS this->_threads_per_atom
// ---------------------------------------------------------------------------
// Calculate energies, forces, and torques
// ---------------------------------------------------------------------------
template <class numtyp, class acctyp>
void VashishtaT::loop(const bool _eflag, const bool _vflag, const int evatom) {
  // Compute the block size and grid size to keep all cores busy
  int BX=this->block_pair();
  int eflag, vflag;
  if (_eflag)
    eflag=1;
  else
    eflag=0;

  if (_vflag)
    vflag=1;
  else
    vflag=0;

  int GX=static_cast<int>(ceil(static_cast<double>(this->ans->inum())/
                               (BX/this->_threads_per_atom)));

  // this->_nbor_data == nbor->dev_packed for gpu_nbor == 0 and tpa > 1
  // this->_nbor_data == nbor->dev_nbor for gpu_nbor == 1 or tpa == 1
  int ainum=this->ans->inum();
  int nbor_pitch=this->nbor->nbor_pitch();
  this->time_pair.start();

  this->k_pair.set_size(GX,BX);
  this->k_pair.run(&this->atom->x, &param1, &param2, &param3, &param4, &param5,
                   &map, &elem2param, &_nelements,
                   &this->nbor->dev_nbor, &this->_nbor_data->begin(),
                   &this->ans->force, &this->ans->engv,
                   &eflag, &vflag, &ainum, &nbor_pitch,
                   &this->_threads_per_atom);

  BX=this->block_size();
  GX=static_cast<int>(ceil(static_cast<double>(this->ans->inum())/
                           (BX/(KTHREADS*JTHREADS))));
  
  this->k_three_center.set_size(GX,BX);
  this->k_three_center.run(&this->atom->x, &param1, &param2, &param3, &param4, &param5,
                           &map, &elem2param, &_nelements,
                           &this->nbor->dev_nbor, &this->_nbor_data->begin(),
                           &this->ans->force, &this->ans->engv, &eflag, &vflag, &ainum,
                           &nbor_pitch, &this->_threads_per_atom, &evatom);
  Answer<numtyp,acctyp> *end_ans;
  #ifdef THREE_CONCURRENT
  end_ans=this->ans2;
  #else
  end_ans=this->ans;
  #endif
  if (evatom!=0) {
    
    this->k_three_end_vatom.set_size(GX,BX);
    this->k_three_end_vatom.run(&this->atom->x, &param1, &param2, &param3, &param4, &param5,
                          &map, &elem2param, &_nelements,
                          &this->nbor->dev_nbor, &this->_nbor_data->begin(),
                          &this->nbor->dev_acc,
                          &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum,
                          &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor);
  } else {
    
    this->k_three_end.set_size(GX,BX);
    this->k_three_end.run(&this->atom->x, &param1, &param2, &param3, &param4, &param5,
                          &map, &elem2param, &_nelements,
                          &this->nbor->dev_nbor, &this->_nbor_data->begin(),
                          &this->nbor->dev_acc,
                          &end_ans->force, &end_ans->engv, &eflag, &vflag, &ainum,
                          &nbor_pitch, &this->_threads_per_atom, &this->_gpu_nbor);
  }

  this->time_pair.stop();
}

template class Vashishta<PRECISION,ACC_PRECISION>;
+744 −0

File added.

Preview size limit exceeded, changes collapsed.

+97 −0
Original line number Diff line number Diff line
/***************************************************************************
                                vashishta.h
                             -------------------
                            Anders Hafreager (UiO9)

  Class for acceleration of the vashishta pair style.

 __________________________________________________________________________
    This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
 __________________________________________________________________________

    begin                : Mon June 12, 2017
    email                : andershaf@gmail.com
 ***************************************************************************/

#ifndef LAL_VASHISHTA_H
#define LAL_VASHISHTA_H

#include "lal_base_three.h"

namespace LAMMPS_AL {

template <class numtyp, class acctyp>
class Vashishta : public BaseThree<numtyp, acctyp> {
 public:
  Vashishta();
  ~Vashishta();

  /// Clear any previous data and set up for a new LAMMPS run
  /** \param max_nbors initial number of rows in the neighbor matrix
    * \param cell_size cutoff + skin
    * \param gpu_split fraction of particles handled by device
    *
    * Returns:
    * -  0 if successfull
    * - -1 if fix gpu not found
    * - -3 if there is an out of memory error
    * - -4 if the GPU library was not compiled for GPU
    * - -5 Double precision is not supported on card **/
  int init(const int ntypes, const int nlocal, const int nall, const int max_nbors,
           const double cell_size, const double gpu_split, FILE *screen,
           int* host_map, const int nelements, int*** host_elem2param, const int nparams,
           const double* cutsq, const double* r0, 
           const double* gamma, const double* eta,
           const double* lam1inv, const double* lam4inv,
           const double* zizj, const double* mbigd,
           const double* dvrc, const double* big6w, 
           const double* heta, const double* bigh,
           const double* bigw, const double* c0,
           const double* costheta, const double* bigb,
           const double* big2b, const double* bigc);

  /// Clear all host and device data
  /** \note This is called at the beginning of the init() routine **/
  void clear();

  /// Returns memory usage on device per atom
  int bytes_per_atom(const int max_nbors) const;

  /// Total host memory used by library for pair style
  double host_memory_usage() const;

  // --------------------------- TYPE DATA --------------------------

  /// If atom type constants fit in shared memory, use fast kernels
  bool shared_types;

  /// Number of atom types
  int _lj_types;

  /// param1.x = eta, param1.y = lam1inv, param1.z = lam4inv, param1.w = zizj
  UCL_D_Vec<numtyp4> param1;
  /// param2.x = mbigd, param2.y = dvrc, param2.z = big6w, param2.w = heta
  UCL_D_Vec<numtyp4> param2;
  /// param3.x = bigh, param3.y = bigw, param3.z = dvrc, param3.w = c0
  UCL_D_Vec<numtyp4> param3;
  /// param4.x = r0sq, param4.y = gamma, param4.z = cutsq, param4.w = r0
  UCL_D_Vec<numtyp4> param4;
  /// param5.x = bigc, param5.y = costheta, param5.z = bigb, param5.w = big2b
  UCL_D_Vec<numtyp4> param5;

  UCL_D_Vec<int> elem2param;
  UCL_D_Vec<int> map;
  int _nparams,_nelements;

  UCL_Texture param1_tex, param2_tex, param3_tex, param4_tex, param5_tex;

 private:
  bool _allocated;
  void loop(const bool _eflag, const bool _vflag, const int evatom);

};

}

#endif
+139 −0
Original line number Diff line number Diff line
/***************************************************************************
                              vashishta_ext.cpp
                             -------------------
                            Anders Hafreager (UiO)

  Class for acceleration of the vashishta pair style.

 __________________________________________________________________________
    This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
 __________________________________________________________________________

    begin                : Mon June 12, 2017
    email                : andershaf@gmail.com
 ***************************************************************************/

#include <iostream>
#include <cassert>
#include <math.h>

#include "lal_vashishta.h"
#include <iostream>
using namespace std;

using namespace std;
using namespace LAMMPS_AL;

static Vashishta<PRECISION,ACC_PRECISION> VashishtaMF;

// ---------------------------------------------------------------------------
// Allocate memory on host and device and copy constants to device
// ---------------------------------------------------------------------------
int vashishta_gpu_init(const int ntypes, const int inum, const int nall, const int max_nbors,
                const double cell_size, int &gpu_mode, FILE *screen,
                int* host_map, const int nelements, int*** host_elem2param, const int nparams,
                const double* cutsq, const double* r0,
                const double* gamma, const double* eta,
                const double* lam1inv, const double* lam4inv,
                const double* zizj, const double* mbigd,
                const double* dvrc, const double* big6w, 
                const double* heta, const double* bigh,
                const double* bigw, const double* c0,
                const double* costheta, const double* bigb,
                const double* big2b, const double* bigc) {
  VashishtaMF.clear();
  gpu_mode=VashishtaMF.device->gpu_mode();
  double gpu_split=VashishtaMF.device->particle_split();
  int first_gpu=VashishtaMF.device->first_device();
  int last_gpu=VashishtaMF.device->last_device();
  int world_me=VashishtaMF.device->world_me();
  int gpu_rank=VashishtaMF.device->gpu_rank();
  int procs_per_gpu=VashishtaMF.device->procs_per_gpu();

  // disable host/device split for now
  if (gpu_split != 1.0)
    return -8;

  VashishtaMF.device->init_message(screen,"vashishta/gpu",first_gpu,last_gpu);

  bool message=false;
  if (VashishtaMF.device->replica_me()==0 && screen)
    message=true;

  if (message) {
    fprintf(screen,"Initializing Device and compiling on process 0...");
    fflush(screen);
  }

  int init_ok=0;
  if (world_me==0)
    init_ok=VashishtaMF.init(ntypes, inum, nall, 500, cell_size, gpu_split, screen,
                      host_map, nelements, host_elem2param, nparams,
                      cutsq, r0, gamma, eta, lam1inv, 
                      lam4inv, zizj, mbigd, dvrc, big6w, heta, bigh, bigw, 
                      c0, costheta, bigb, big2b, bigc);

  VashishtaMF.device->world_barrier();
  if (message)
    fprintf(screen,"Done.\n");

  for (int i=0; i<procs_per_gpu; i++) {
    if (message) {
      if (last_gpu-first_gpu==0)
        fprintf(screen,"Initializing Device %d on core %d...",first_gpu,i);
      else
        fprintf(screen,"Initializing Devices %d-%d on core %d...",first_gpu,
                last_gpu,i);
      fflush(screen);
    }
    if (gpu_rank==i && world_me!=0)
      init_ok=VashishtaMF.init(ntypes, inum, nall, 500, cell_size, gpu_split, screen,
                        host_map, nelements, host_elem2param, nparams,
                        cutsq, r0, gamma, eta, lam1inv, 
                        lam4inv, zizj, mbigd, dvrc, big6w, heta, bigh, bigw, 
                        c0, costheta, bigb, big2b, bigc);

    VashishtaMF.device->gpu_barrier();
    if (message)
      fprintf(screen,"Done.\n");
  }
  if (message)
    fprintf(screen,"\n");

  if (init_ok==0)
    VashishtaMF.estimate_gpu_overhead();

  cout << "Seems like this was ok!" << endl;
  return init_ok;
}

void vashishta_gpu_clear() {
  VashishtaMF.clear();
}

int ** vashishta_gpu_compute_n(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) {
  return VashishtaMF.compute(ago, inum_full, nall, host_x, host_type, sublo,
                       subhi, tag, nspecial, special, eflag, vflag, eatom,
                       vatom, host_start, ilist, jnum, cpu_time, success);
}

void vashishta_gpu_compute(const int ago, const int nlocal, 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) {
  VashishtaMF.compute(ago,nlocal,nall,nlist,host_x,host_type,ilist,numj,
               firstneigh,eflag,vflag,eatom,vatom,host_start,cpu_time,success);
}

double vashishta_gpu_bytes() {
  return VashishtaMF.host_memory_usage();
}

Loading