Feb2021 GPU Package Update - GPU Package Files
This commit is contained in:
@ -20,7 +20,7 @@ namespace LAMMPS_AL {
|
||||
extern Device<PRECISION,ACC_PRECISION> global_device;
|
||||
|
||||
template <class numtyp, class acctyp>
|
||||
BaseThreeT::BaseThree() : _compiled(false), _max_bytes(0) {
|
||||
BaseThreeT::BaseThree() : _compiled(false), _max_bytes(0), _onetype(-1) {
|
||||
device=&global_device;
|
||||
ans=new Answer<numtyp,acctyp>();
|
||||
nbor=new Neighbor();
|
||||
@ -29,6 +29,9 @@ BaseThreeT::BaseThree() : _compiled(false), _max_bytes(0) {
|
||||
#endif
|
||||
pair_program=nullptr;
|
||||
ucl_device=nullptr;
|
||||
#if defined(LAL_OCL_EV_JIT)
|
||||
pair_program_noev=nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class numtyp, class acctyp>
|
||||
@ -44,12 +47,18 @@ BaseThreeT::~BaseThree() {
|
||||
k_pair.clear();
|
||||
k_short_nbor.clear();
|
||||
if (pair_program) delete pair_program;
|
||||
#if defined(LAL_OCL_EV_JIT)
|
||||
k_three_center_noev.clear();
|
||||
k_three_end_noev.clear();
|
||||
k_pair_noev.clear();
|
||||
if (pair_program_noev) delete pair_program_noev;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class numtyp, class acctyp>
|
||||
int BaseThreeT::bytes_per_atom_atomic(const int max_nbors) const {
|
||||
int b=device->atom.bytes_per_atom()+ans->bytes_per_atom()+
|
||||
nbor->bytes_per_atom(max_nbors);
|
||||
nbor->bytes_per_atom(max_nbors);
|
||||
#ifdef THREE_CONCURRENT
|
||||
b+=ans2->bytes_per_atom();
|
||||
#endif
|
||||
@ -62,7 +71,9 @@ int BaseThreeT::init_three(const int nlocal, const int nall,
|
||||
const double cell_size, const double gpu_split,
|
||||
FILE *_screen, const void *pair_program,
|
||||
const char *two, const char *three_center,
|
||||
const char *three_end, const char *short_nbor) {
|
||||
const char *three_end, const char *short_nbor,
|
||||
const int onetype, const int onetype3,
|
||||
const int spq, const int tpa_override) {
|
||||
screen=_screen;
|
||||
|
||||
int gpu_nbor=0;
|
||||
@ -77,24 +88,16 @@ int BaseThreeT::init_three(const int nlocal, const int nall,
|
||||
if (host_nlocal>0)
|
||||
_gpu_host=1;
|
||||
|
||||
_threads_per_atom=device->threads_per_atom();
|
||||
if (_threads_per_atom>1 && gpu_nbor==0) { // neigh no and tpa > 1
|
||||
nbor->packing(true);
|
||||
_nbor_data=&(nbor->dev_packed);
|
||||
} else // neigh yes or tpa == 1
|
||||
_nbor_data=&(nbor->dev_nbor);
|
||||
if (_threads_per_atom*_threads_per_atom>device->warp_size())
|
||||
return -10;
|
||||
// Allow forcing threads per atom to 1 for tersoff due to subg sync issue
|
||||
if (tpa_override)
|
||||
_threads_per_atom=tpa_override;
|
||||
else
|
||||
_threads_per_atom=device->threads_per_three();
|
||||
|
||||
int success=device->init(*ans,false,false,nlocal,nall,maxspecial);
|
||||
if (success!=0)
|
||||
return success;
|
||||
|
||||
success = device->init_nbor(nbor,nlocal,host_nlocal,nall,maxspecial,_gpu_host,
|
||||
max_nbors,cell_size,false,_threads_per_atom);
|
||||
if (success!=0)
|
||||
return success;
|
||||
|
||||
if (ucl_device!=device->gpu) _compiled=false;
|
||||
|
||||
ucl_device=device->gpu;
|
||||
@ -110,7 +113,19 @@ int BaseThreeT::init_three(const int nlocal, const int nall,
|
||||
|
||||
_block_pair=device->pair_block_size();
|
||||
_block_size=device->block_ellipse();
|
||||
compile_kernels(*ucl_device,pair_program,two,three_center,three_end,short_nbor);
|
||||
compile_kernels(*ucl_device,pair_program,two,three_center,three_end,
|
||||
short_nbor,onetype,onetype3,spq);
|
||||
|
||||
while (_threads_per_atom*_threads_per_atom>device->simd_size())
|
||||
_threads_per_atom = _threads_per_atom / 2;
|
||||
|
||||
if (_threads_per_atom*_threads_per_atom>device->simd_size())
|
||||
return -10;
|
||||
|
||||
success = device->init_nbor(nbor,nall,host_nlocal,nall,maxspecial,
|
||||
_gpu_host,max_nbors,cell_size,true,1,true);
|
||||
if (success!=0)
|
||||
return success;
|
||||
|
||||
// Initialize host-device load balancer
|
||||
hd_balancer.init(device,gpu_nbor,gpu_split);
|
||||
@ -121,22 +136,21 @@ int BaseThreeT::init_three(const int nlocal, const int nall,
|
||||
|
||||
pos_tex.bind_float(atom->x,4);
|
||||
|
||||
int ef_nall=nall;
|
||||
if (ef_nall==0)
|
||||
ef_nall=2000;
|
||||
|
||||
_max_an_bytes=ans->gpu_bytes()+nbor->gpu_bytes();
|
||||
#ifdef THREE_CONCURRENT
|
||||
_max_an_bytes+=ans2->gpu_bytes();
|
||||
#endif
|
||||
|
||||
int ef_nall=nall;
|
||||
if (ef_nall==0)
|
||||
ef_nall=2000;
|
||||
dev_short_nbor.alloc(ef_nall*(2+max_nbors),*(this->ucl_device),UCL_READ_WRITE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class numtyp, class acctyp>
|
||||
void BaseThreeT::estimate_gpu_overhead() {
|
||||
device->estimate_gpu_overhead(1,_gpu_overhead,_driver_overhead);
|
||||
void BaseThreeT::estimate_gpu_overhead(const int add_kernels) {
|
||||
device->estimate_gpu_overhead(4+add_kernels,_gpu_overhead,_driver_overhead);
|
||||
}
|
||||
|
||||
template <class numtyp, class acctyp>
|
||||
@ -152,7 +166,6 @@ void BaseThreeT::clear_atomic() {
|
||||
time_pair.clear();
|
||||
hd_balancer.clear();
|
||||
|
||||
dev_short_nbor.clear();
|
||||
nbor->clear();
|
||||
ans->clear();
|
||||
#ifdef THREE_CONCURRENT
|
||||
@ -186,6 +199,7 @@ int * BaseThreeT::reset_nbors(const int nall, const int inum, const int nlist,
|
||||
|
||||
// now the requirement is removed, allowing to work within pair hybrid
|
||||
nbor->get_host(nlist,ilist,numj,firstneigh,block_size());
|
||||
nbor->copy_unpacked(nlist,mn);
|
||||
|
||||
double bytes=ans->gpu_bytes()+nbor->gpu_bytes();
|
||||
#ifdef THREE_CONCURRENT
|
||||
@ -201,24 +215,32 @@ int * BaseThreeT::reset_nbors(const int nall, const int inum, const int nlist,
|
||||
// Build neighbor list on device
|
||||
// ---------------------------------------------------------------------------
|
||||
template <class numtyp, class acctyp>
|
||||
inline int BaseThreeT::build_nbor_list(const int inum, const int host_inum,
|
||||
const int nall, double **host_x,
|
||||
int *host_type, double *sublo,
|
||||
double *subhi, tagint *tag,
|
||||
int **nspecial, tagint **special,
|
||||
bool &success) {
|
||||
inline void BaseThreeT::build_nbor_list(const int inum, const int host_inum,
|
||||
const int nall, double **host_x,
|
||||
int *host_type, double *sublo,
|
||||
double *subhi, tagint *tag,
|
||||
int **nspecial, tagint **special,
|
||||
bool &success) {
|
||||
success=true;
|
||||
resize_atom(inum,nall,success);
|
||||
resize_local(nall,host_inum,nbor->max_nbors(),success);
|
||||
if (!success)
|
||||
return 0;
|
||||
return;
|
||||
atom->cast_copy_x(host_x,host_type);
|
||||
|
||||
_nall = nall;
|
||||
|
||||
// Increase the effective sub-domain size for neighbors of ghosts
|
||||
// This is still inefficient because we are calculating neighbors for more
|
||||
// ghosts than necessary due to increased ghost cutoff
|
||||
const double ncut=nbor->cutoff()*2.0;
|
||||
for (int i=0; i<3; i++) sublo[i]-=ncut;
|
||||
for (int i=0; i<3; i++) subhi[i]+=ncut;
|
||||
|
||||
int mn;
|
||||
nbor->build_nbor_list(host_x, nall, host_inum, nall, *atom, sublo, subhi, tag,
|
||||
nspecial, special, success, mn);
|
||||
nbor->build_nbor_list(host_x, nall, host_inum, nall, *atom, sublo, subhi,
|
||||
tag, nspecial, special, success, mn, ans->error_flag);
|
||||
nbor->copy_unpacked(nall,mn);
|
||||
|
||||
double bytes=ans->gpu_bytes()+nbor->gpu_bytes();
|
||||
#ifdef THREE_CONCURRENT
|
||||
@ -226,7 +248,6 @@ inline int BaseThreeT::build_nbor_list(const int inum, const int host_inum,
|
||||
#endif
|
||||
if (bytes>_max_an_bytes)
|
||||
_max_an_bytes=bytes;
|
||||
return mn;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -236,10 +257,24 @@ template <class numtyp, class acctyp>
|
||||
void BaseThreeT::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 bool eflag_in, const bool vflag_in,
|
||||
const bool eatom, const bool vatom, int &host_start,
|
||||
const double cpu_time, bool &success) {
|
||||
acc_timers();
|
||||
int eflag, vflag;
|
||||
if (eatom) eflag=2;
|
||||
else if (eflag_in) eflag=1;
|
||||
else eflag=0;
|
||||
if (vatom) vflag=2;
|
||||
else if (vflag_in) vflag=1;
|
||||
else vflag=0;
|
||||
|
||||
#ifdef LAL_NO_BLOCK_REDUCE
|
||||
if (eflag) eflag=2;
|
||||
if (vflag) vflag=2;
|
||||
#endif
|
||||
|
||||
set_kernel(eflag,vflag);
|
||||
if (inum_full==0) {
|
||||
host_start=0;
|
||||
// Make sure textures are correct if realloc by a different hybrid style
|
||||
@ -260,19 +295,12 @@ void BaseThreeT::compute(const int f_ago, const int inum_full, const int nall,
|
||||
reset_nbors(nall, inum, nlist, ilist, numj, firstneigh, success);
|
||||
if (!success)
|
||||
return;
|
||||
_max_nbors = nbor->max_nbor_loop(nlist,numj,ilist);
|
||||
}
|
||||
|
||||
atom->cast_x_data(host_x,host_type);
|
||||
hd_balancer.start_timer();
|
||||
atom->add_x_data(host_x,host_type);
|
||||
|
||||
// re-allocate dev_short_nbor if necessary
|
||||
if (nall*(2+_max_nbors) > dev_short_nbor.cols()) {
|
||||
int _nmax=static_cast<int>(static_cast<double>(nall)*1.10);
|
||||
dev_short_nbor.resize((2+_max_nbors)*_nmax);
|
||||
}
|
||||
|
||||
// _ainum to be used in loop() for short neighbor list build
|
||||
_ainum = nlist;
|
||||
|
||||
@ -282,11 +310,11 @@ void BaseThreeT::compute(const int f_ago, const int inum_full, const int nall,
|
||||
#ifdef THREE_CONCURRENT
|
||||
ucl_device->sync();
|
||||
#endif
|
||||
loop(eflag,vflag,evatom);
|
||||
ans->copy_answers(eflag,vflag,eatom,vatom,ilist);
|
||||
const int red_blocks=loop(eflag,vflag,evatom,success);
|
||||
ans->copy_answers(eflag_in,vflag_in,eatom,vatom,ilist,red_blocks);
|
||||
device->add_ans_object(ans);
|
||||
#ifdef THREE_CONCURRENT
|
||||
ans2->copy_answers(eflag,vflag,eatom,vatom,ilist);
|
||||
ans2->copy_answers(eflag_in,vflag_in,eatom,vatom,ilist,red_blocks);
|
||||
device->add_ans_object(ans2);
|
||||
#endif
|
||||
hd_balancer.stop_timer();
|
||||
@ -296,15 +324,29 @@ void BaseThreeT::compute(const int f_ago, const int inum_full, const int nall,
|
||||
// Reneighbor on GPU if necessary and then compute forces, virials, energies
|
||||
// ---------------------------------------------------------------------------
|
||||
template <class numtyp, class acctyp>
|
||||
int ** BaseThreeT::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) {
|
||||
int ** BaseThreeT::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_in,
|
||||
const bool vflag_in, const bool eatom,
|
||||
const bool vatom, int &host_start,
|
||||
int **ilist, int **jnum,
|
||||
const double cpu_time, bool &success) {
|
||||
acc_timers();
|
||||
int eflag, vflag;
|
||||
if (eatom) eflag=2;
|
||||
else if (eflag_in) eflag=1;
|
||||
else eflag=0;
|
||||
if (vatom) vflag=2;
|
||||
else if (vflag_in) vflag=1;
|
||||
else vflag=0;
|
||||
|
||||
#ifdef LAL_NO_BLOCK_REDUCE
|
||||
if (eflag) eflag=2;
|
||||
if (vflag) vflag=2;
|
||||
#endif
|
||||
|
||||
set_kernel(eflag,vflag);
|
||||
if (inum_full==0) {
|
||||
host_start=0;
|
||||
// Make sure textures are correct if realloc by a different hybrid style
|
||||
@ -323,7 +365,7 @@ int ** BaseThreeT::compute(const int ago, const int inum_full,
|
||||
|
||||
// Build neighbor list on GPU if necessary
|
||||
if (ago==0) {
|
||||
_max_nbors = build_nbor_list(inum, inum_full-inum, nall, host_x, host_type,
|
||||
build_nbor_list(inum, inum_full-inum, nall, host_x, host_type,
|
||||
sublo, subhi, tag, nspecial, special, success);
|
||||
if (!success)
|
||||
return nullptr;
|
||||
@ -336,12 +378,6 @@ int ** BaseThreeT::compute(const int ago, const int inum_full,
|
||||
*ilist=nbor->host_ilist.begin();
|
||||
*jnum=nbor->host_acc.begin();
|
||||
|
||||
// re-allocate dev_short_nbor if necessary
|
||||
if (nall*(2+_max_nbors) > dev_short_nbor.cols()) {
|
||||
int _nmax=static_cast<int>(static_cast<double>(nall)*1.10);
|
||||
dev_short_nbor.resize((2+_max_nbors)*_nmax);
|
||||
}
|
||||
|
||||
// _ainum to be used in loop() for short neighbor list build
|
||||
_ainum = nall;
|
||||
|
||||
@ -351,11 +387,11 @@ int ** BaseThreeT::compute(const int ago, const int inum_full,
|
||||
#ifdef THREE_CONCURRENT
|
||||
ucl_device->sync();
|
||||
#endif
|
||||
loop(eflag,vflag,evatom);
|
||||
ans->copy_answers(eflag,vflag,eatom,vatom);
|
||||
const int red_blocks=loop(eflag,vflag,evatom,success);
|
||||
ans->copy_answers(eflag_in,vflag_in,eatom,vatom,red_blocks);
|
||||
device->add_ans_object(ans);
|
||||
#ifdef THREE_CONCURRENT
|
||||
ans2->copy_answers(eflag,vflag,eatom,vatom);
|
||||
ans2->copy_answers(eflag_in,vflag_in,eatom,vatom,red_blocks);
|
||||
device->add_ans_object(ans2);
|
||||
#endif
|
||||
hd_balancer.stop_timer();
|
||||
@ -372,14 +408,24 @@ double BaseThreeT::host_memory_usage_atomic() const {
|
||||
template <class numtyp, class acctyp>
|
||||
void BaseThreeT::compile_kernels(UCL_Device &dev, const void *pair_str,
|
||||
const char *two, const char *three_center,
|
||||
const char *three_end, const char* short_nbor) {
|
||||
if (_compiled)
|
||||
const char *three_end, const char* short_nbor,
|
||||
const int onetype, const int onetype3,
|
||||
const int spq) {
|
||||
if (_compiled && _onetype==onetype && _onetype3==onetype3 && _spq==spq)
|
||||
return;
|
||||
|
||||
_onetype=onetype;
|
||||
_onetype3=onetype3;
|
||||
_spq=spq;
|
||||
|
||||
std::string vatom_name=std::string(three_end)+"_vatom";
|
||||
if (pair_program) delete pair_program;
|
||||
pair_program=new UCL_Program(dev);
|
||||
pair_program->load_string(pair_str,device->compile_string().c_str());
|
||||
std::string oclstring = device->compile_string()+" -DEVFLAG=1";
|
||||
if (_onetype>=0) oclstring+=" -DONETYPE="+device->toa(_onetype)+
|
||||
" -DONETYPE3="+device->toa(_onetype3);
|
||||
if (_spq) oclstring+=" -DSPQ="+device->toa(_spq);
|
||||
pair_program->load_string(pair_str,oclstring.c_str(),nullptr,screen);
|
||||
k_three_center.set_function(*pair_program,three_center);
|
||||
k_three_end.set_function(*pair_program,three_end);
|
||||
k_three_end_vatom.set_function(*pair_program,vatom_name.c_str());
|
||||
@ -387,12 +433,50 @@ void BaseThreeT::compile_kernels(UCL_Device &dev, const void *pair_str,
|
||||
k_short_nbor.set_function(*pair_program,short_nbor);
|
||||
pos_tex.get_texture(*pair_program,"pos_tex");
|
||||
|
||||
#if defined(LAL_OCL_EV_JIT)
|
||||
oclstring = device->compile_string()+" -DEVFLAG=0";
|
||||
if (_onetype>=0) oclstring+=" -DONETYPE="+device->toa(_onetype)+
|
||||
" -DONETYPE3="+device->toa(_onetype3);
|
||||
if (_spq) oclstring+=" -DSPQ="+device->toa(_spq);
|
||||
if (pair_program_noev) delete pair_program_noev;
|
||||
pair_program_noev=new UCL_Program(dev);
|
||||
pair_program_noev->load_string(pair_str,oclstring.c_str(),nullptr,screen);
|
||||
k_three_center_noev.set_function(*pair_program_noev,three_center);
|
||||
k_three_end_noev.set_function(*pair_program_noev,three_end);
|
||||
k_pair_noev.set_function(*pair_program_noev,two);
|
||||
#else
|
||||
k_sel = &k_pair;
|
||||
k_3center_sel = &k_three_center;
|
||||
k_3end_sel = &k_three_end;
|
||||
#endif
|
||||
|
||||
#ifdef THREE_CONCURRENT
|
||||
k_three_end.cq(ucl_device->cq(_end_command_queue));
|
||||
k_three_end_vatom.cq(ucl_device->cq(_end_command_queue));
|
||||
#if defined(LAL_OCL_EV_JIT)
|
||||
k_three_end_noev.cq(ucl_device->cq(_end_command_queue));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_compiled=true;
|
||||
|
||||
#if defined(USE_OPENCL) && (defined(CL_VERSION_2_1) || defined(CL_VERSION_3_0))
|
||||
if (dev.cl_device_version() >= 210) {
|
||||
size_t mx_subgroup_sz = k_pair.max_subgroup_size(_block_size);
|
||||
mx_subgroup_sz = std::min(mx_subgroup_sz, k_three_center.max_subgroup_size(_block_size));
|
||||
mx_subgroup_sz = std::min(mx_subgroup_sz, k_three_end.max_subgroup_size(_block_size));
|
||||
mx_subgroup_sz = std::min(mx_subgroup_sz, k_three_end_vatom.max_subgroup_size(_block_size));
|
||||
#if defined(LAL_OCL_EV_JIT)
|
||||
mx_subgroup_sz = std::min(mx_subgroup_sz, k_pair_noev.max_subgroup_size(_block_size));
|
||||
mx_subgroup_sz = std::min(mx_subgroup_sz, k_three_center_noev.max_subgroup_size(_block_size));
|
||||
mx_subgroup_sz = std::min(mx_subgroup_sz, k_three_end_noev.max_subgroup_size(_block_size));
|
||||
#endif
|
||||
if (_threads_per_atom > mx_subgroup_sz)
|
||||
_threads_per_atom = mx_subgroup_sz;
|
||||
device->set_simd_size(mx_subgroup_sz);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template class BaseThree<PRECISION,ACC_PRECISION>;
|
||||
|
||||
Reference in New Issue
Block a user