From 5056f2cfe972e51b229d780673921a55207f44b6 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Wed, 28 Aug 2019 14:08:15 +0800 Subject: [PATCH 001/147] add ewald, passed ener and force test --- source/lib/include/Ewald.h | 221 +++++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 source/lib/include/Ewald.h diff --git a/source/lib/include/Ewald.h b/source/lib/include/Ewald.h new file mode 100644 index 0000000000..b6c60f584f --- /dev/null +++ b/source/lib/include/Ewald.h @@ -0,0 +1,221 @@ +#pragma once + +#include +#include + +#include "SimulationRegion.h" + +const double ElectrostaticConvertion = 14.39964535475696995031; + +template +struct EwaldParameters +{ + VALUETYPE rcut = 6.0; + VALUETYPE beta = 2; + VALUETYPE spacing = 4; +}; + + + +template +VALUETYPE +dir_err_esti(const VALUETYPE & test_q, + const VALUETYPE & c2, + const VALUETYPE & nn, + const EwaldParameters & param) +{ + const VALUETYPE & rcut = param.rcut; + const VALUETYPE & beta = param.beta; + const VALUETYPE rho_q2 = c2/nn; + VALUETYPE sum = 2 * test_q + * sqrt (rho_q2 / rcut) + * exp (- beta*beta*rcut*rcut) * ElectrostaticConvertion; + return sum; +} + +template +VALUETYPE +rec_err_esti(const VALUETYPE & test_q, + const VALUETYPE & c2, + const VALUETYPE & nn, + const EwaldParameters& param, + const SimulationRegion& region) +{ + const VALUETYPE & beta = param.beta; + vector KK; + cmpt_k(KK, region, param); + const double * rec_box = region.getRecBoxTensor(); + double sum = 0; + int BD[3]; + for (int dd = 0; dd < 3; ++dd){ + BD[dd] = KK[dd]/2 + 10; + } + int mm[3]; + for (mm[0] = -BD[0]; mm[0] <= BD[0]; ++mm[0]){ + for (mm[1] = -BD[1]; mm[1] <= BD[1]; ++mm[1]){ + for (mm[2] = -BD[2]; mm[2] <= BD[2]; ++mm[2]){ + if (mm[0] >= - int(KK[0])/2 && mm[0] <= int(KK[0])/2 && + mm[1] >= - int(KK[1])/2 && mm[1] <= int(KK[1])/2 && + mm[2] >= - int(KK[2])/2 && mm[2] <= int(KK[2])/2) continue; + VALUETYPE rm[3] = {0,0,0}; + for (int dd = 0; dd < 3; ++dd){ + rm[0] += mm[dd] * rec_box[dd*3+0]; + rm[1] += mm[dd] * rec_box[dd*3+1]; + rm[2] += mm[dd] * rec_box[dd*3+2]; + } + VALUETYPE mm2 = rm[0] * rm[0] + rm[1] * rm[1] + rm[2] * rm[2]; + sum += exp (-2 * M_PI * M_PI / beta / beta * mm2) / mm2; + } + } + } + VALUETYPE vol = region.getVolume(); + // cout << sqrt(sum) << " " << KK[0] << " " << rec_box[0] << " " << c2 << " " << vol << endl; + sum = test_q * 2 * sqrt(sum) * sqrt(c2) / vol * ElectrostaticConvertion; + return sum; +} + +template +void +cmpt_k(vector & KK, + const SimulationRegion& region, + const EwaldParameters& param) +{ + const double * boxt_ = region.getBoxTensor(); + VALUETYPE boxt[9]; + for (int dd = 0; dd < 9; ++dd){ + boxt[dd] = static_cast(boxt_[dd]); + } + KK.resize(3); + for (int dd = 0; dd < 3; ++dd){ + VALUETYPE ll = sqrt(MathUtilities::dot(boxt+dd*3, boxt+dd*3)); + KK[dd] = ll / param.spacing; + // KK[dd] should be large enough + if (KK[dd] * param.spacing < ll) KK[dd] += 1; + assert(KK[dd] * param.spacing >= ll); + // KK[dd] should be even + if ((KK[dd] / 2) * 2 != KK[dd]) KK[dd] += 1; + assert((KK[dd] / 2) * 2 == KK[dd]); + } +} + + +// compute the reciprocal part of the Ewald sum. +// outputs: energy force virial +// inputs: coordinates charges region +template +void +EwaldReciprocal(VALUETYPE & ener, + vector & force, + vector & virial, + const vector& coord, + const vector& charge, + const SimulationRegion& region, + const EwaldParameters& param) +{ + // natoms + int natoms = charge.size(); + // init returns + force.resize(natoms * 3); + virial.resize(9); + ener = 0; + fill(force.begin(), force.end(), static_cast(0)); + fill(virial.begin(), virial.end(), static_cast(0)); + + vector KK(3); + int totK = 1; + cmpt_k(KK, region, param); + for (int dd = 0; dd < 3; ++dd){ + totK *= (KK[dd]+1); + } + + // compute the sq + VALUETYPE * sqr = new VALUETYPE[totK]; + VALUETYPE * sqi = new VALUETYPE[totK]; + for (int ii = 0; ii < totK; ++ii){ + sqr[ii] = static_cast(0); + sqi[ii] = static_cast(0); + } + // firstly loop over particles then loop over m + int mm[3]; + for (int ii = 0; ii < natoms; ++ii){ + double ir[3]; + region.phys2Inter(ir, &coord[ii*3]); + double mr[3]; + int mc = 0; + for (mm[0] = -KK[0]/2; mm[0] <= KK[0]/2; ++mm[0]){ + mr[0] = ir[0] * mm[0]; + for (mm[1] = -KK[1]/2; mm[1] <= KK[1]/2; ++mm[1]){ + mr[1] = ir[1] * mm[1]; + for (mm[2] = -KK[2]/2; mm[2] <= KK[2]/2; ++mm[2]){ + if (mm[0] == 0 && mm[1] == 0 && mm[2] == 0) continue; + mr[2] = ir[2] * mm[2]; + double mdotr = 2. * M_PI * (mr[0]+mr[1]+mr[2]); + sqr[mc] += charge[ii] * cos(mdotr); + sqi[mc] += charge[ii] * sin(mdotr); + ++mc; + } + } + } + } + VALUETYPE rec_box[9]; + const double * rec_box_ = region.getRecBoxTensor(); + for (int ii = 0; ii < 9; ++ii){ + rec_box[ii] = static_cast(rec_box_[ii]); + } + // calculate ener, force and virial + // firstly loop over particles then loop over m + int mc = 0; + for (mm[0] = -KK[0]/2; mm[0] <= KK[0]/2; ++mm[0]){ + for (mm[1] = -KK[1]/2; mm[1] <= KK[1]/2; ++mm[1]){ + for (mm[2] = -KK[2]/2; mm[2] <= KK[2]/2; ++mm[2]){ + if (mm[0] == 0 && mm[1] == 0 && mm[2] == 0) continue; + // \bm m and \vert m \vert^2 + VALUETYPE rm[3] = {0,0,0}; + for (int dd = 0; dd < 3; ++dd){ + rm[0] += mm[dd] * rec_box[dd*3+0]; + rm[1] += mm[dd] * rec_box[dd*3+1]; + rm[2] += mm[dd] * rec_box[dd*3+2]; + } + VALUETYPE mm2 = rm[0] * rm[0] + rm[1] * rm[1] + rm[2] * rm[2]; + // energy + VALUETYPE expmm2 = exp(- M_PI * M_PI * mm2 / (param.beta * param.beta)) / mm2; + VALUETYPE eincr = expmm2 * (sqr[mc] * sqr[mc] + sqi[mc] * sqi[mc]); + ener += eincr; + // virial + VALUETYPE vpref = -2. * (1. + M_PI * M_PI * mm2 / (param.beta * param.beta)) / mm2; + for (int dd0 = 0; dd0 < 3; ++dd0){ + for (int dd1 = 0; dd1 < 3; ++dd1){ + VALUETYPE tmp = vpref * rm[dd0] * rm[dd1]; + if (dd0 == dd1) tmp += 1; + virial[dd0*3+dd1] += eincr * tmp; + } + } + // force + for (int ii = 0; ii < natoms; ++ii){ + VALUETYPE mdotr = - 2. * M_PI * (coord[ii*3+0]*rm[0] + coord[ii*3+1]*rm[1] + coord[ii*3+2]*rm[2]); + VALUETYPE tmpr = charge[ii] * cos(mdotr); + VALUETYPE tmpi = charge[ii] * sin(mdotr); + VALUETYPE cc = 4. * M_PI * (tmpr * sqi[mc] + tmpi * sqr[mc]) * expmm2; + force[ii*3+0] -= rm[0] * cc; + force[ii*3+1] -= rm[1] * cc; + force[ii*3+2] -= rm[2] * cc; + } + ++mc; + } + } + } + VALUETYPE vol = static_cast(region.getVolume()); + ener /= 2 * M_PI * vol; + ener *= ElectrostaticConvertion; + for (int ii = 0; ii < 3*natoms; ++ii){ + force[ii] /= 2 * M_PI * vol; + force[ii] *= ElectrostaticConvertion; + } + for (int ii = 0; ii < 3*3; ++ii){ + virial[ii] /= 2 * M_PI * vol; + virial[ii] *= ElectrostaticConvertion; + } + delete[]sqr; + delete[]sqi; +} + From eb4ca51a95779041ca5ae03b62b7e6b7f811de03 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Wed, 16 Oct 2019 22:37:01 +0800 Subject: [PATCH 002/147] add descrption for the printed data --- source/lib/include/Ewald.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/lib/include/Ewald.h b/source/lib/include/Ewald.h index b6c60f584f..0fd110c1f0 100644 --- a/source/lib/include/Ewald.h +++ b/source/lib/include/Ewald.h @@ -15,8 +15,6 @@ struct EwaldParameters VALUETYPE spacing = 4; }; - - template VALUETYPE dir_err_esti(const VALUETYPE & test_q, @@ -69,7 +67,11 @@ rec_err_esti(const VALUETYPE & test_q, } } VALUETYPE vol = region.getVolume(); - // cout << sqrt(sum) << " " << KK[0] << " " << rec_box[0] << " " << c2 << " " << vol << endl; + // cout << "sum: " << sqrt(sum) + // << " KK: " << KK[0] + // << " rbox: " << rec_box[0] + // << " c2: " << c2 + // << " vol: " << vol << endl; sum = test_q * 2 * sqrt(sum) * sqrt(c2) / vol * ElectrostaticConvertion; return sum; } From c98dd918c8e48d73762b8f9aeee33fc82e6e4821 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 17 Oct 2019 21:07:26 +0800 Subject: [PATCH 003/147] implement op ewald_recp, tested force --- source/op/CMakeLists.txt | 2 +- source/op/ewald_recp.cc | 158 ++++++++++++++++++++++++++++++++++++ source/tests/test_ewald.py | 100 +++++++++++++++++++++++ source/train/CMakeLists.txt | 2 +- source/train/EwaldRecp.py | 22 +++++ 5 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 source/op/ewald_recp.cc create mode 100644 source/tests/test_ewald.py create mode 100644 source/train/EwaldRecp.py diff --git a/source/op/CMakeLists.txt b/source/op/CMakeLists.txt index 58051ff45b..6ad4d1b929 100644 --- a/source/op/CMakeLists.txt +++ b/source/op/CMakeLists.txt @@ -3,7 +3,7 @@ set(OP_LIB ${PROJECT_SOURCE_DIR}/lib/src/SimulationRegion.cpp ${PROJECT_SOURCE_DIR}/lib/src/NeighborList.cpp) set (OP_CXX_FLAG -D_GLIBCXX_USE_CXX11_ABI=${OP_CXX_ABI} ) -file(GLOB OP_SRC prod_force.cc prod_virial.cc descrpt.cc descrpt_se_a.cc descrpt_se_r.cc tab_inter.cc prod_force_se_a.cc prod_virial_se_a.cc prod_force_se_r.cc prod_virial_se_r.cc soft_min.cc soft_min_force.cc soft_min_virial.cc ) +file(GLOB OP_SRC prod_force.cc prod_virial.cc descrpt.cc descrpt_se_a.cc descrpt_se_r.cc tab_inter.cc prod_force_se_a.cc prod_virial_se_a.cc prod_force_se_r.cc prod_virial_se_r.cc soft_min.cc soft_min_force.cc soft_min_virial.cc ewald_recp.cc) file(GLOB OP_GRADS_SRC prod_force_grad.cc prod_force_se_a_grad.cc prod_force_se_r_grad.cc prod_virial_grad.cc prod_virial_se_a_grad.cc prod_virial_se_r_grad.cc soft_min_force_grad.cc soft_min_virial_grad.cc ) file(GLOB OP_PY *.py) diff --git a/source/op/ewald_recp.cc b/source/op/ewald_recp.cc new file mode 100644 index 0000000000..d2d04601a0 --- /dev/null +++ b/source/op/ewald_recp.cc @@ -0,0 +1,158 @@ +#include "tensorflow/core/framework/op.h" +#include "tensorflow/core/framework/op_kernel.h" +#include "tensorflow/core/framework/shape_inference.h" +#include + +#include "Ewald.h" + +typedef double boxtensor_t ; + +using namespace tensorflow; +using namespace std; + +#ifdef HIGH_PREC +typedef double VALUETYPE ; +#else +typedef float VALUETYPE ; +#endif + +#ifdef HIGH_PREC +REGISTER_OP("EwaldRecp") +.Input("coord: double") +.Input("charge: double") +.Input("natoms: int32") +.Input("box: double") +.Attr("ewald_beta: float") +.Attr("ewald_h: float") +.Output("energy: double") +.Output("force: double") +.Output("virial: double"); +#else +REGISTER_OP("EwaldRecp") +.Input("coord: float") +.Input("charge: float") +.Input("natoms: int32") +.Input("box: float") +.Attr("ewald_beta: float") +.Attr("ewald_h: float") +.Output("energy: float") +.Output("force: float") +.Output("virial: float"); +#endif + +class EwaldRecpOp : public OpKernel { +public: + explicit EwaldRecpOp(OpKernelConstruction* context) : OpKernel(context) { + float beta, spacing; + OP_REQUIRES_OK(context, context->GetAttr("ewald_beta", &(beta))); + OP_REQUIRES_OK(context, context->GetAttr("ewald_h", &(spacing))); + ep.beta = beta; + ep.spacing = spacing; + } + + void Compute(OpKernelContext* context) override { + // Grab the input tensor + int cc = 0; + const Tensor& coord_tensor = context->input(cc++); + const Tensor& charge_tensor = context->input(cc++); + const Tensor& natoms_tensor = context->input(cc++); + const Tensor& box_tensor = context->input(cc++); + + // set size of the sample + OP_REQUIRES (context, (coord_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of coord should be 2")); + OP_REQUIRES (context, (charge_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of type should be 2")); + OP_REQUIRES (context, (natoms_tensor.shape().dim_size(0) == 1), errors::InvalidArgument ("size of natoms should be 1")); + OP_REQUIRES (context, (box_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of box should be 2")); + auto natoms = natoms_tensor.flat(); + int nloc = natoms(0); + int nsamples = coord_tensor.shape().dim_size(0); + + // check the sizes + OP_REQUIRES (context, (nsamples == coord_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); + OP_REQUIRES (context, (nsamples == charge_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); + OP_REQUIRES (context, (nsamples == box_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); + + OP_REQUIRES (context, (nloc * 3 == coord_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of atoms should match")); + OP_REQUIRES (context, (nloc == charge_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of atoms should match")); + OP_REQUIRES (context, (9 == box_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of box should be 9")); + + // Create an output tensor + TensorShape energy_shape ; + energy_shape.AddDim (nsamples); + TensorShape force_shape ; + force_shape.AddDim (nsamples); + force_shape.AddDim (nloc * 3); + TensorShape virial_shape ; + virial_shape.AddDim (nsamples); + virial_shape.AddDim (9); + + cc = 0; + Tensor* energy_tensor = NULL; + OP_REQUIRES_OK(context, context->allocate_output(cc++, energy_shape, &energy_tensor)); + Tensor* force_tensor = NULL; + OP_REQUIRES_OK(context, context->allocate_output(cc++, force_shape, &force_tensor)); + Tensor* virial_tensor = NULL; + OP_REQUIRES_OK(context, context->allocate_output(cc++, virial_shape, &virial_tensor)); + + auto coord = coord_tensor .matrix(); + auto charge = charge_tensor .matrix(); + auto box = box_tensor .matrix(); + auto energy = energy_tensor ->flat(); + auto force = force_tensor ->matrix(); + auto virial = virial_tensor ->matrix(); + + for (int kk = 0; kk < nsamples; ++kk){ + // set region + boxtensor_t boxt [9] = {0}; + for (int dd = 0; dd < 9; ++dd) { + boxt[dd] = box(kk, dd); + } + SimulationRegion region; + region.reinitBox (boxt); + + // set & normalize coord + vector d_coord3_ (nloc*3); + for (int ii = 0; ii < nloc; ++ii){ + for (int dd = 0; dd < 3; ++dd){ + d_coord3_[ii*3+dd] = coord(kk, ii*3+dd); + } + double inter[3]; + region.phys2Inter (inter, &d_coord3_[3*ii]); + for (int dd = 0; dd < 3; ++dd){ + if (inter[dd] < 0 ) inter[dd] += 1.; + else if (inter[dd] >= 1) inter[dd] -= 1.; + } + } + vector d_coord3 (nloc*3); + for (int ii = 0; ii < nloc * 3; ++ii) { + d_coord3[ii] = d_coord3_[ii]; + } + + // set charge + vector d_charge (nloc); + for (int ii = 0; ii < nloc; ++ii) d_charge[ii] = charge(kk, ii); + + // prepare outputs vectors + VALUETYPE d_ener; + vector d_force(nloc*3); + vector d_virial(9); + + // compute + EwaldReciprocal(d_ener, d_force, d_virial, d_coord3, d_charge, region, ep); + + // copy output + energy(kk) = d_ener; + for (int ii = 0; ii < nloc * 3; ++ii){ + force(kk, ii) = d_force[ii]; + } + for (int ii = 0; ii < 9; ++ii){ + virial(kk, ii) = d_virial[ii]; + } + } + } +private: + EwaldParameters ep; +}; + +REGISTER_KERNEL_BUILDER(Name("EwaldRecp").Device(DEVICE_CPU), EwaldRecpOp); + diff --git a/source/tests/test_ewald.py b/source/tests/test_ewald.py new file mode 100644 index 0000000000..202fb19755 --- /dev/null +++ b/source/tests/test_ewald.py @@ -0,0 +1,100 @@ +import os,sys,platform +import numpy as np +import unittest +from deepmd.env import tf + +from deepmd.RunOptions import global_tf_float_precision +from deepmd.RunOptions import global_np_float_precision +from deepmd.RunOptions import global_ener_float_precision +from deepmd.EwaldRecp import op_module + +if global_np_float_precision == np.float32 : + global_default_fv_hh = 1e-2 + global_default_dw_hh = 1e-2 + global_default_places = 3 +else : + global_default_fv_hh = 1e-6 + global_default_dw_hh = 1e-4 + global_default_places = 5 + + +class TestEwaldRecp (unittest.TestCase) : + def setUp(self): + boxl = 6 + box_pert = 1 + self.natoms = 16 + self.nframes = 2 + self.ewald_h = 1 + self.ewald_beta = 1 + self.dbox = [] + self.dcoord = [] + self.dcharge = [] + for ii in range(self.nframes): + # box + box = np.ones([3,3]) * boxl + box += np.random.random([3,3]) * box_pert + self.dbox.append(0.5 * (box + box.T)) + # scaled + self.coord = np.random.random([self.natoms, 3]) + # real coords + self.dcoord.append(np.matmul(self.coord, box)) + # charge + dcharge = np.random.random([self.natoms]) + dcharge -= np.average(dcharge) + assert(np.abs(np.sum(self.dcharge) - 0) < 1e-12) + self.dcharge.append(dcharge) + self.dbox = np.array(self.dbox).reshape([self.nframes, 9]) + self.dcoord = np.array(self.dcoord).reshape([self.nframes, 3*self.natoms]) + self.dcharge = np.array(self.dcharge).reshape([self.nframes, self.natoms]) + # place holders + self.coord = tf.placeholder(global_tf_float_precision, [None, self.natoms * 3], name='t_coord') + self.charge = tf.placeholder(global_tf_float_precision, [None, self.natoms], name='t_charge') + self.box = tf.placeholder(global_tf_float_precision, [None, 9], name='t_box') + self.nloc = tf.placeholder(tf.int32, [1], name = "t_nloc") + + def test_force(self): + hh = 1e-4 + places = 5 + sess = tf.Session() + t_energy, t_force, t_virial \ + = op_module.ewald_recp(self.coord, self.charge, self.nloc, self.box, + ewald_h = self.ewald_h, + ewald_beta = self.ewald_beta) + [force] = sess.run([t_force], + feed_dict = { + self.coord: self.dcoord, + self.charge: self.dcharge, + self.box: self.dbox, + self.nloc: [self.natoms], + }) + for idx in range(self.natoms): + for dd in range(3): + dcoordp = np.copy(self.dcoord) + dcoordm = np.copy(self.dcoord) + dcoordp[:,idx*3+dd] = self.dcoord[:,idx*3+dd] + hh + dcoordm[:,idx*3+dd] = self.dcoord[:,idx*3+dd] - hh + energyp = sess.run([t_energy], + feed_dict = { + self.coord: dcoordp, + self.charge: self.dcharge, + self.box: self.dbox, + self.nloc: [self.natoms], + }) + energym = sess.run([t_energy], + feed_dict = { + self.coord: dcoordm, + self.charge: self.dcharge, + self.box: self.dbox, + self.nloc: [self.natoms], + }) + c_force = -(energyp[0] - energym[0]) / (2*hh) + for ff in range(self.nframes): + self.assertAlmostEqual(c_force[ff], force[ff,idx*3+dd], + places = places, + msg = "frame %d force component [%d,%d] failed" % (ff, idx, dd)) + + + + + + diff --git a/source/train/CMakeLists.txt b/source/train/CMakeLists.txt index 83f15df4c3..7b990d3df9 100644 --- a/source/train/CMakeLists.txt +++ b/source/train/CMakeLists.txt @@ -2,7 +2,7 @@ configure_file("RunOptions.py.in" "${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py" @ONLY) -file(GLOB LIB_PY main.py common.py env.py compat.py Network.py Deep*.py Data.py DataSystem.py Model*.py Descrpt*.py Fitting.py Loss.py LearningRate.py Trainer.py TabInter.py ${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py) +file(GLOB LIB_PY main.py common.py env.py compat.py Network.py Deep*.py Data.py DataSystem.py Model*.py Descrpt*.py Fitting.py Loss.py LearningRate.py Trainer.py TabInter.py EwaldRecp.py ${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py) file(GLOB CLS_PY Local.py Slurm.py) diff --git a/source/train/EwaldRecp.py b/source/train/EwaldRecp.py new file mode 100644 index 0000000000..abbeba3608 --- /dev/null +++ b/source/train/EwaldRecp.py @@ -0,0 +1,22 @@ +import platform +import os +import numpy as np +from deepmd.env import tf +from deepmd.common import ClassArg +from deepmd.RunOptions import global_tf_float_precision +from deepmd.RunOptions import global_np_float_precision +from deepmd.RunOptions import global_ener_float_precision +from deepmd.RunOptions import global_cvt_2_tf_float +from deepmd.RunOptions import global_cvt_2_ener_float + +if platform.system() == "Windows": + ext = "dll" +elif platform.system() == "Darwin": + ext = "dylib" +else: + ext = "so" + +module_path = os.path.dirname(os.path.realpath(__file__)) + "/" +assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" +op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) + From d32926879716413e64d87f99167752bb1a83821c Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 18 Oct 2019 13:24:49 +0800 Subject: [PATCH 004/147] fix bug in ewald, tested virial --- source/lib/include/Ewald.h | 10 ++-- source/tests/test_ewald.py | 96 +++++++++++++++++++++++++++++++++++--- 2 files changed, 95 insertions(+), 11 deletions(-) diff --git a/source/lib/include/Ewald.h b/source/lib/include/Ewald.h index 0fd110c1f0..f02b8600fd 100644 --- a/source/lib/include/Ewald.h +++ b/source/lib/include/Ewald.h @@ -99,7 +99,6 @@ cmpt_k(vector & KK, assert((KK[dd] / 2) * 2 == KK[dd]); } } - // compute the reciprocal part of the Ewald sum. // outputs: energy force virial @@ -174,9 +173,12 @@ EwaldReciprocal(VALUETYPE & ener, // \bm m and \vert m \vert^2 VALUETYPE rm[3] = {0,0,0}; for (int dd = 0; dd < 3; ++dd){ - rm[0] += mm[dd] * rec_box[dd*3+0]; - rm[1] += mm[dd] * rec_box[dd*3+1]; - rm[2] += mm[dd] * rec_box[dd*3+2]; + rm[0] += mm[dd] * rec_box[0*3+dd]; + rm[1] += mm[dd] * rec_box[1*3+dd]; + rm[2] += mm[dd] * rec_box[2*3+dd]; + // rm[0] += mm[dd] * rec_box[dd*3+0]; + // rm[1] += mm[dd] * rec_box[dd*3+1]; + // rm[2] += mm[dd] * rec_box[dd*3+2]; } VALUETYPE mm2 = rm[0] * rm[0] + rm[1] * rm[1] + rm[2] * rm[2]; // energy diff --git a/source/tests/test_ewald.py b/source/tests/test_ewald.py index 202fb19755..3c7f96bd77 100644 --- a/source/tests/test_ewald.py +++ b/source/tests/test_ewald.py @@ -20,30 +20,36 @@ class TestEwaldRecp (unittest.TestCase) : def setUp(self): - boxl = 6 - box_pert = 1 + boxl = 4.5 # NOTICE grid should not change before and after box pert... + box_pert = 0.2 self.natoms = 16 self.nframes = 2 self.ewald_h = 1 self.ewald_beta = 1 self.dbox = [] self.dcoord = [] + self.rcoord = [] self.dcharge = [] for ii in range(self.nframes): # box - box = np.ones([3,3]) * boxl + box = np.eye(3) * boxl + box[1][1] += 1 + box[2][2] += 2 box += np.random.random([3,3]) * box_pert - self.dbox.append(0.5 * (box + box.T)) + box = 0.5 * (box + box.T) + self.dbox.append(box) # scaled - self.coord = np.random.random([self.natoms, 3]) + coord = np.random.random([self.natoms, 3]) + self.rcoord.append(coord) # real coords - self.dcoord.append(np.matmul(self.coord, box)) + self.dcoord.append(np.matmul(coord, box)) # charge dcharge = np.random.random([self.natoms]) dcharge -= np.average(dcharge) assert(np.abs(np.sum(self.dcharge) - 0) < 1e-12) self.dcharge.append(dcharge) self.dbox = np.array(self.dbox).reshape([self.nframes, 9]) + self.rcoord = np.array(self.rcoord).reshape([self.nframes, 3*self.natoms]) self.dcoord = np.array(self.dcoord).reshape([self.nframes, 3*self.natoms]) self.dcharge = np.array(self.dcharge).reshape([self.nframes, self.natoms]) # place holders @@ -54,7 +60,7 @@ def setUp(self): def test_force(self): hh = 1e-4 - places = 5 + places = 4 sess = tf.Session() t_energy, t_force, t_virial \ = op_module.ewald_recp(self.coord, self.charge, self.nloc, self.box, @@ -94,6 +100,82 @@ def test_force(self): msg = "frame %d force component [%d,%d] failed" % (ff, idx, dd)) + def test_virial(self): + hh = 1e-4 + places = 5 + sess = tf.Session() + t_energy, t_force, t_virial \ + = op_module.ewald_recp(self.coord, self.charge, self.nloc, self.box, + ewald_h = self.ewald_h, + ewald_beta = self.ewald_beta) + [virial] = sess.run([t_virial], + feed_dict = { + self.coord: self.dcoord, + self.charge: self.dcharge, + self.box: self.dbox, + self.nloc: [self.natoms], + }) + + from scipy.stats import ortho_group + + + + self.dbox3 = np.reshape(self.dbox, [self.nframes, 3,3]) + self.drbox3 = np.linalg.inv(self.dbox3) + # print(np.matmul(self.dbox3, self.drbox3)) + # print(np.matmul(self.drbox3, self.dbox3)) + self.dcoord3 = np.reshape(self.dcoord, [self.nframes, self.natoms, 3]) + self.rcoord3 = np.matmul(self.dcoord3, self.drbox3) + # print(np.linalg.norm(self.dcoord - np.matmul(self.rcoord3, self.dbox3).reshape([self.nframes,-1]))) + # print(np.matmul(self.dcoord3, self.drbox3)) + # print('check rcoord ', np.linalg.norm(self.rcoord3 - self.rcoord.reshape([self.nframes, self.natoms, 3]))) + + num_deriv = np.zeros([self.nframes,3,3]) + for ii in range(3): + for jj in range(3): + dbox3p = np.copy(self.dbox3) + dbox3m = np.copy(self.dbox3) + dbox3p[:,ii,jj] = self.dbox3[:,ii,jj] + hh + dbox3m[:,ii,jj] = self.dbox3[:,ii,jj] - hh + dboxp = np.reshape(dbox3p, [-1,9]) + dboxm = np.reshape(dbox3m, [-1,9]) + dcoord = self.dcoord + dcoord3p = np.matmul(self.rcoord3, dbox3p) + dcoord3m = np.matmul(self.rcoord3, dbox3m) + dcoordp = np.reshape(dcoord3p, [self.nframes,-1]) + dcoordm = np.reshape(dcoord3m, [self.nframes,-1]) + energyp = sess.run([t_energy], + feed_dict = { + self.coord: dcoordp, + self.charge: self.dcharge, + self.box: dboxp, + self.nloc: [self.natoms], + }) + energym = sess.run([t_energy], + feed_dict = { + self.coord: dcoordm, + self.charge: self.dcharge, + self.box: dboxm, + self.nloc: [self.natoms], + }) + num_deriv[:,ii,jj] = -(energyp[0] - energym[0]) / (2.*hh) + dbox3t = np.transpose(self.dbox3, [0,2,1]) + t_esti = np.matmul(num_deriv, dbox3t) + # # t_esti = np.matmul(num_deriv, self.dbox3) + # print(num_deriv[0]) + # print(t_esti[0]) + # # print(0.5 * (t_esti[0] + t_esti[0].T)) + # print(virial[0].reshape([3,3])) + # # print(0.5 * (t_esti[0] + t_esti[0].T) - virial[0].reshape([3,3])) + # print(0.5 * (t_esti[0] + t_esti[0]) - virial[0].reshape([3,3])) + # print(0.5 * (t_esti[0] + t_esti[0].T) - virial[0].reshape([3,3])) + for ff in range(self.nframes): + for ii in range(3): + for jj in range(3): + self.assertAlmostEqual(t_esti[ff][ii][jj], virial[ff,ii*3+jj], + places = places, + msg = "frame %d forcvirial component [%d,%d] failed" % (ff, ii, jj)) + From fdad3ca1b6a6015b87d2547e904950876e2b0537 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Wed, 23 Oct 2019 15:55:40 +0800 Subject: [PATCH 005/147] add test for ewald_recp python interface. add test for data type sel --- source/tests/test_deepmd_data.py | 56 ++++++++++++++++++++++++++++++++ source/tests/test_ewald.py | 35 ++++++++++++++++++++ source/train/EwaldRecp.py | 42 ++++++++++++++++++++++++ 3 files changed, 133 insertions(+) diff --git a/source/tests/test_deepmd_data.py b/source/tests/test_deepmd_data.py index 6db3017d00..005ab26893 100644 --- a/source/tests/test_deepmd_data.py +++ b/source/tests/test_deepmd_data.py @@ -10,6 +10,62 @@ else: places = 12 +class TestDataTypeSel(unittest.TestCase): + def setUp(self): + self.data_name = 'test_data' + os.makedirs(self.data_name, exist_ok = True) + os.makedirs(os.path.join(self.data_name,'set.foo'), exist_ok = True) + np.savetxt(os.path.join(self.data_name, 'type.raw'), + np.array([0, 1, 1, 0, 1, 1]), + fmt = '%d') + self.nframes = 3 + self.natoms = 6 + # coord + path = os.path.join(self.data_name, 'set.foo', 'coord.npy') + self.coord = np.random.random([self.nframes, self.natoms, 3]) + np.save(path, np.reshape(self.coord, [self.nframes, -1])) + self.coord = self.coord[:,[0,3,1,2,4,5],:] + self.coord = self.coord.reshape([self.nframes, -1]) + # box + path = os.path.join(self.data_name, 'set.foo', 'box.npy') + self.box = np.random.random([self.nframes, 9]) + np.save(path, self.box) + # value + path = os.path.join(self.data_name, 'set.foo', 'value_1.npy') + self.value_1 = np.arange(self.nframes * 2) + self.value_1 = np.reshape(self.value_1, [self.nframes, 2]) + np.save(path, self.value_1) + # value + path = os.path.join(self.data_name, 'set.foo', 'value_2.npy') + self.value_2 = np.arange(self.nframes * 4) + self.value_2 = np.reshape(self.value_2, [self.nframes, 4]) + np.save(path, self.value_2) + + def tearDown(self) : + shutil.rmtree(self.data_name) + + def test_load_set_1(self) : + dd = DeepmdData(self.data_name)\ + .add('value_1', 1, atomic=True, must=True, type_sel = [0]) + data = dd._load_set(os.path.join(self.data_name, 'set.foo')) + self.assertEqual(data['value_1'].shape, (self.nframes, 2)) + for ii in range(self.nframes): + for jj in range(2): + self.assertAlmostEqual(data['value_1'][ii][jj], + self.value_1[ii][jj]) + + + def test_load_set_2(self) : + dd = DeepmdData(self.data_name)\ + .add('value_2', 1, atomic=True, must=True, type_sel = [1]) + data = dd._load_set(os.path.join(self.data_name, 'set.foo')) + self.assertEqual(data['value_2'].shape, (self.nframes, 4)) + for ii in range(self.nframes): + for jj in range(4): + self.assertAlmostEqual(data['value_2'][ii][jj], + self.value_2[ii][jj]) + + class TestData (unittest.TestCase) : def setUp (self) : self.data_name = 'test_data' diff --git a/source/tests/test_ewald.py b/source/tests/test_ewald.py index 3c7f96bd77..4e8586aa3c 100644 --- a/source/tests/test_ewald.py +++ b/source/tests/test_ewald.py @@ -7,6 +7,7 @@ from deepmd.RunOptions import global_np_float_precision from deepmd.RunOptions import global_ener_float_precision from deepmd.EwaldRecp import op_module +from deepmd.EwaldRecp import EwaldRecp if global_np_float_precision == np.float32 : global_default_fv_hh = 1e-2 @@ -58,6 +59,40 @@ def setUp(self): self.box = tf.placeholder(global_tf_float_precision, [None, 9], name='t_box') self.nloc = tf.placeholder(tf.int32, [1], name = "t_nloc") + def test_py_interface(self): + hh = 1e-4 + places = 4 + sess = tf.Session() + t_energy, t_force, t_virial \ + = op_module.ewald_recp(self.coord, self.charge, self.nloc, self.box, + ewald_h = self.ewald_h, + ewald_beta = self.ewald_beta) + [e, f, v] = sess.run([t_energy, t_force, t_virial], + feed_dict = { + self.coord: self.dcoord, + self.charge: self.dcharge, + self.box: self.dbox, + self.nloc: [self.natoms], + }) + er = EwaldRecp(self.ewald_h, self.ewald_beta) + e1, f1, v1 = er.eval(self.dcoord, self.dcharge, self.dbox) + for ff in range(self.nframes): + self.assertAlmostEqual(e[ff], e1[ff], + places = places, + msg = "frame %d energy failed" % (ff)) + for idx in range(self.natoms): + for dd in range(3): + self.assertAlmostEqual(f[ff, idx*3+dd], f1[ff,idx*3+dd], + places = places, + msg = "frame %d force component [%d,%d] failed" % (ff, idx, dd)) + for d0 in range(3): + for d1 in range(3): + self.assertAlmostEqual(v[ff, d0*3+d1], v[ff,d0*3+d1], + places = places, + msg = "frame %d virial component [%d,%d] failed" % (ff, d0, d1)) + + + def test_force(self): hh = 1e-4 places = 4 diff --git a/source/train/EwaldRecp.py b/source/train/EwaldRecp.py index abbeba3608..20217d0428 100644 --- a/source/train/EwaldRecp.py +++ b/source/train/EwaldRecp.py @@ -20,3 +20,45 @@ assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) +class EwaldRecp () : + def __init__(self, + hh, + beta): + self.hh = hh + self.beta = beta + self.sess = tf.Session() + + def eval(self, + coord, + charge, + box) : + coord = np.array(coord) + charge = np.array(charge) + box = np.array(box) + nframes = charge.shape[0] + natoms = charge.shape[1] + coord = np.reshape(coord, [nframes, 3*natoms]) + box = np.reshape(box, [nframes, 9]) + # place holders + t_coord = tf.placeholder(global_tf_float_precision, [None, natoms * 3], name='t_coord') + t_charge = tf.placeholder(global_tf_float_precision, [None, natoms], name='t_charge') + t_box = tf.placeholder(global_tf_float_precision, [None, 9], name='t_box') + t_nloc = tf.placeholder(tf.int32, [1], name = "t_nloc") + + t_energy, t_force, t_virial \ + = op_module.ewald_recp(t_coord, t_charge, t_nloc, t_box, + ewald_h = self.hh, + ewald_beta = self.beta) + + [energy, force, virial] \ + = self.sess.run([t_energy, t_force, t_virial], + feed_dict = { + t_coord: coord, + t_charge: charge, + t_box: box, + t_nloc: [natoms], + }) + + return energy, force, virial + + From 8b729fe56d4bb695f6485101c047698176736470 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sun, 27 Oct 2019 17:33:54 +0800 Subject: [PATCH 006/147] fix bug of wrong index in prod virial. more strict virial test --- source/lib/include/Ewald.h | 1 + source/op/prod_virial.cc | 6 +- source/op/prod_virial_grad.cc | 6 +- source/op/prod_virial_se_a.cc | 2 +- source/op/prod_virial_se_a_grad.cc | 2 +- source/tests/common.py | 146 ++++++++++++++++++--------- source/tests/test_descrpt_nonsmth.py | 55 ++++------ source/tests/test_descrpt_se_ar.py | 17 ++-- source/tests/test_descrpt_se_r.py | 17 ++-- source/tests/test_descrpt_smooth.py | 17 ++-- source/tests/test_ewald.py | 2 +- source/tests/test_tab_nonsmth.py | 19 ++-- source/tests/test_tab_smooth.py | 19 ++-- 13 files changed, 185 insertions(+), 124 deletions(-) diff --git a/source/lib/include/Ewald.h b/source/lib/include/Ewald.h index f02b8600fd..e6fc837386 100644 --- a/source/lib/include/Ewald.h +++ b/source/lib/include/Ewald.h @@ -5,6 +5,7 @@ #include "SimulationRegion.h" +// 8.988e9 / pc.electron_volt / pc.angstrom * (1.602e-19)**2 const double ElectrostaticConvertion = 14.39964535475696995031; template diff --git a/source/op/prod_virial.cc b/source/op/prod_virial.cc index df061aa12f..55b0b4b60d 100644 --- a/source/op/prod_virial.cc +++ b/source/op/prod_virial.cc @@ -147,7 +147,7 @@ class ProdVirialOp : public OpKernel { VALUETYPE pref = -1.0 * net_deriv (net_iter + i_idx * ndescrpt + aa); for (int dd0 = 0; dd0 < 3; ++dd0){ for (int dd1 = 0; dd1 < 3; ++dd1){ - VALUETYPE tmp_v = pref * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd0) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 3 + dd1); + VALUETYPE tmp_v = pref * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd1) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 3 + dd0); virial (virial_iter + dd0 * 3 + dd1) += tmp_v; atom_virial (atom_virial_iter + j_idx * 9 + dd0 * 3 + dd1) += tmp_v; } @@ -159,7 +159,7 @@ class ProdVirialOp : public OpKernel { VALUETYPE pref = -1.0 * net_deriv (net_iter + i_idx * ndescrpt + aa); for (int dd0 = 0; dd0 < 3; ++dd0){ for (int dd1 = 0; dd1 < 3; ++dd1){ - VALUETYPE tmp_v = pref * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd0) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 6 + dd1); + VALUETYPE tmp_v = pref * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd1) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 6 + dd0); virial (virial_iter + dd0 * 3 + dd1) += tmp_v; atom_virial (atom_virial_iter + j_idx * 9 + dd0 * 3 + dd1) += tmp_v; } @@ -173,7 +173,7 @@ class ProdVirialOp : public OpKernel { VALUETYPE pref = -1.0 * net_deriv (net_iter + i_idx * ndescrpt + aa); for (int dd0 = 0; dd0 < 3; ++dd0){ for (int dd1 = 0; dd1 < 3; ++dd1){ - VALUETYPE tmp_v = pref * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd0) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 9 + dd1); + VALUETYPE tmp_v = pref * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd1) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 9 + dd0); virial (virial_iter + dd0 * 3 + dd1) += tmp_v; atom_virial (atom_virial_iter + j_idx * 9 + dd0 * 3 + dd1) += tmp_v; } diff --git a/source/op/prod_virial_grad.cc b/source/op/prod_virial_grad.cc index aaa0e75b14..5257467029 100644 --- a/source/op/prod_virial_grad.cc +++ b/source/op/prod_virial_grad.cc @@ -152,7 +152,7 @@ class ProdVirialGradOp : public OpKernel for (int dd0 = 0; dd0 < 3; ++dd0){ for (int dd1 = 0; dd1 < 3; ++dd1){ grad_net (grad_net_iter + i_idx * ndescrpt + aa) += - -1.0 * grad (grad_iter + dd0 * 3 + dd1) * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd0) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 3 + dd1); + -1.0 * grad (grad_iter + dd0 * 3 + dd1) * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd1) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 3 + dd0); } } } @@ -162,7 +162,7 @@ class ProdVirialGradOp : public OpKernel for (int dd0 = 0; dd0 < 3; ++dd0){ for (int dd1 = 0; dd1 < 3; ++dd1){ grad_net (grad_net_iter + i_idx * ndescrpt + aa) += - -1.0 * grad (grad_iter + dd0 * 3 + dd1) * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd0) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 6 + dd1); + -1.0 * grad (grad_iter + dd0 * 3 + dd1) * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd1) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 6 + dd0); } } } @@ -174,7 +174,7 @@ class ProdVirialGradOp : public OpKernel for (int dd0 = 0; dd0 < 3; ++dd0){ for (int dd1 = 0; dd1 < 3; ++dd1){ grad_net (grad_net_iter + i_idx * ndescrpt + aa) += - -1.0 * grad (grad_iter + dd0 * 3 + dd1) * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd0) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 9 + dd1); + -1.0 * grad (grad_iter + dd0 * 3 + dd1) * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd1) * in_deriv (in_iter + i_idx * ndescrpt * 12 + aa * 12 + 9 + dd0); } } } diff --git a/source/op/prod_virial_se_a.cc b/source/op/prod_virial_se_a.cc index 89077750af..2f71d37505 100644 --- a/source/op/prod_virial_se_a.cc +++ b/source/op/prod_virial_se_a.cc @@ -134,7 +134,7 @@ class ProdVirialSeAOp : public OpKernel { VALUETYPE pref = -1.0 * net_deriv (net_iter + i_idx * ndescrpt + aa); for (int dd0 = 0; dd0 < 3; ++dd0){ for (int dd1 = 0; dd1 < 3; ++dd1){ - VALUETYPE tmp_v = pref * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd0) * in_deriv (in_iter + i_idx * ndescrpt * 3 + aa * 3 + dd1); + VALUETYPE tmp_v = pref * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd1) * in_deriv (in_iter + i_idx * ndescrpt * 3 + aa * 3 + dd0); virial (virial_iter + dd0 * 3 + dd1) -= tmp_v; atom_virial (atom_virial_iter + j_idx * 9 + dd0 * 3 + dd1) -= tmp_v; } diff --git a/source/op/prod_virial_se_a_grad.cc b/source/op/prod_virial_se_a_grad.cc index 0d19a1c19a..660f652566 100644 --- a/source/op/prod_virial_se_a_grad.cc +++ b/source/op/prod_virial_se_a_grad.cc @@ -137,7 +137,7 @@ class ProdVirialSeAGradOp : public OpKernel for (int dd0 = 0; dd0 < 3; ++dd0){ for (int dd1 = 0; dd1 < 3; ++dd1){ grad_net (grad_net_iter + i_idx * ndescrpt + aa) -= - -1.0 * grad (grad_iter + dd0 * 3 + dd1) * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd0) * in_deriv (in_iter + i_idx * ndescrpt * 3 + aa * 3 + dd1); + -1.0 * grad (grad_iter + dd0 * 3 + dd1) * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd1) * in_deriv (in_iter + i_idx * ndescrpt * 3 + aa * 3 + dd0); } } } diff --git a/source/tests/common.py b/source/tests/common.py index 812a238c4a..e9ad53dbf2 100644 --- a/source/tests/common.py +++ b/source/tests/common.py @@ -11,7 +11,7 @@ global_default_dw_hh = 1e-2 global_default_places = 3 else : - global_default_fv_hh = 1e-6 + global_default_fv_hh = 1e-5 global_default_dw_hh = 1e-4 global_default_places = 5 @@ -38,23 +38,30 @@ def __init__ (self, seed = 1) : coord = [[0.0, 0.0, 0.1], [1.1, 0.0, 0.1], [0.0, 1.1, 0.1], [4.0, 0.0, 0.0], [5.1, 0.0, 0.0], [4.0, 1.1, 0.0]] + self.nframes = 1 self.coord = np.array(coord) + self.coord = self._copy_nframes(self.coord) np.random.seed(seed) self.coord += rand_pert * np.random.random(self.coord.shape) self.fparam = np.array([[0.1, 0.2]]) self.aparam = np.tile(self.fparam, [1, 6]) + self.fparam = self._copy_nframes(self.fparam) + self.aparam = self._copy_nframes(self.aparam) self.atype = np.array([0, 1, 1, 0, 1, 1], dtype = int) self.cell = 20 * np.eye(3) - self.nframes = 1 + self.cell = self._copy_nframes(self.cell) self.coord = self.coord.reshape([self.nframes, -1]) self.cell = self.cell.reshape([self.nframes, -1]) self.natoms = len(self.atype) self.idx_map = np.lexsort ((np.arange(self.natoms), self.atype)) - self.coord = self.coord.reshape([1, -1, 3]) + self.coord = self.coord.reshape([self.nframes, -1, 3]) self.coord = self.coord[:,self.idx_map,:] - self.coord = self.coord.reshape([1, -1]) + self.coord = self.coord.reshape([self.nframes, -1]) self.atype = self.atype[self.idx_map] - self.datype = np.tile(self.atype, [self.nframes,1]) + self.datype = self._copy_nframes(self.atype) + + def _copy_nframes(self, xx): + return np.tile(xx, [self.nframes, 1]) def get_data(self) : return self.coord, self.cell, self.datype @@ -68,39 +75,80 @@ def get_natoms (self) : def get_ntypes(self) : return max(self.atype) + 1 + # def get_test_box_data (self, + # hh) : + # coord0_, box0_, type0_ = self.get_data() + # coord0 = coord0_[0] + # box0 = box0_[0] + # type0 = type0_[0] + # nc = np.array( [coord0, coord0*(1+hh), coord0*(1-hh)] ) + # nb = np.array( [box0, box0*(1+hh), box0*(1-hh)] ) + # nt = np.array( [type0, type0, type0] ) + # for dd in range(3) : + # tmpc = np.copy (coord0) + # tmpb = np.copy (box0) + # tmpc = np.reshape(tmpc, [-1, 3]) + # tmpc [:,dd] *= (1+hh) + # tmpc = np.reshape(tmpc, [-1]) + # tmpb = np.reshape(tmpb, [-1, 3]) + # tmpb [dd,:] *= (1+hh) + # tmpb = np.reshape(tmpb, [-1]) + # nc = np.append (nc, [tmpc], axis = 0) + # nb = np.append (nb, [tmpb], axis = 0) + # nt = np.append (nt, [type0], axis = 0) + # tmpc = np.copy (coord0) + # tmpb = np.copy (box0) + # tmpc = np.reshape(tmpc, [-1, 3]) + # tmpc [:,dd] *= (1-hh) + # tmpc = np.reshape(tmpc, [-1]) + # tmpb = np.reshape(tmpb, [-1, 3]) + # tmpb [dd,:] *= (1-hh) + # tmpb = np.reshape(tmpb, [-1]) + # nc = np.append (nc, [tmpc], axis = 0) + # nb = np.append (nb, [tmpb], axis = 0) + # nt = np.append (nt, [type0], axis = 0) + # return nc, nb, nt + def get_test_box_data (self, - hh) : + hh, + rand_pert = 0.1) : coord0_, box0_, type0_ = self.get_data() - coord0 = coord0_[0] - box0 = box0_[0] - type0 = type0_[0] - nc = np.array( [coord0, coord0*(1+hh), coord0*(1-hh)] ) - nb = np.array( [box0, box0*(1+hh), box0*(1-hh)] ) - nt = np.array( [type0, type0, type0] ) - for dd in range(3) : - tmpc = np.copy (coord0) - tmpb = np.copy (box0) - tmpc = np.reshape(tmpc, [-1, 3]) - tmpc [:,dd] *= (1+hh) - tmpc = np.reshape(tmpc, [-1]) - tmpb = np.reshape(tmpb, [-1, 3]) - tmpb [dd,:] *= (1+hh) - tmpb = np.reshape(tmpb, [-1]) - nc = np.append (nc, [tmpc], axis = 0) - nb = np.append (nb, [tmpb], axis = 0) - nt = np.append (nt, [type0], axis = 0) - tmpc = np.copy (coord0) - tmpb = np.copy (box0) - tmpc = np.reshape(tmpc, [-1, 3]) - tmpc [:,dd] *= (1-hh) - tmpc = np.reshape(tmpc, [-1]) - tmpb = np.reshape(tmpb, [-1, 3]) - tmpb [dd,:] *= (1-hh) - tmpb = np.reshape(tmpb, [-1]) - nc = np.append (nc, [tmpc], axis = 0) - nb = np.append (nb, [tmpb], axis = 0) - nt = np.append (nt, [type0], axis = 0) - return nc, nb, nt + coord = coord0_[0] + box = box0_[0] + box += rand_pert * np.random.random(box.shape) + atype = type0_[0] + nframes = 1 + natoms = coord.size // 3 + box3 = np.reshape(box, [nframes, 3,3]) + rbox3 = np.linalg.inv(box3) + coord3 = np.reshape(coord, [nframes, natoms, 3]) + rcoord3 = np.matmul(coord3, rbox3) + + all_coord = [coord.reshape([nframes, natoms*3])] + all_box = [box.reshape([nframes,9])] + all_atype = [atype] + for ii in range(3): + for jj in range(3): + box3p = np.copy(box3) + box3m = np.copy(box3) + box3p[:,ii,jj] = box3[:,ii,jj] + hh + box3m[:,ii,jj] = box3[:,ii,jj] - hh + boxp = np.reshape(box3p, [-1,9]) + boxm = np.reshape(box3m, [-1,9]) + coord3p = np.matmul(rcoord3, box3p) + coord3m = np.matmul(rcoord3, box3m) + coordp = np.reshape(coord3p, [nframes,-1]) + coordm = np.reshape(coord3m, [nframes,-1]) + all_coord.append(coordp) + all_coord.append(coordm) + all_box.append(boxp) + all_box.append(boxm) + all_atype.append(atype) + all_atype.append(atype) + all_coord = np.reshape(all_coord, [-1, natoms * 3]) + all_box = np.reshape(all_box, [-1, 9]) + all_atype = np.reshape(all_atype, [-1, natoms]) + return all_coord, all_box, all_atype def force_test (inter, @@ -178,16 +226,22 @@ def virial_test (inter, inter.type: dtype, inter.tnatoms: inter.natoms} ) - # check - ana_vir3 = (virial[0][0] + virial[0][4] + virial[0][8])/3. / comp_vol(dbox[0]) - num_vir3 = -(energy[1] - energy[2]) / (comp_vol(dbox[1]) - comp_vol(dbox[2])) - testCase.assertAlmostEqual(ana_vir3, num_vir3, places=places) - vir_idx = [0, 4, 8] - for dd in range (3) : - ana_v = (virial[0][vir_idx[dd]] / comp_vol(dbox[0])) - idx = 2 * (dd+1) + 1 - num_v = ( -(energy[idx] - energy[idx+1]) / (comp_vol(dbox[idx]) - comp_vol(dbox[idx+1])) ) - testCase.assertAlmostEqual(ana_v, num_v, places=places) + ana_vir = virial[0].reshape([3,3]) + num_vir = np.zeros([3,3]) + for ii in range(3): + for jj in range(3): + ep = energy[1+(ii*3+jj)*2+0] + em = energy[1+(ii*3+jj)*2+1] + num_vir[ii][jj] = -(ep - em) / (2.*hh) + num_vir = np.transpose(num_vir, [1,0]) + box3 = dbox[0].reshape([3,3]) + num_vir = np.matmul(num_vir, box3) + for ii in range(3): + for jj in range(3): + testCase.assertAlmostEqual(ana_vir[ii][jj], num_vir[ii][jj], + places=places, + msg = 'virial component %d %d ' % (ii,jj)) + def force_dw_test (inter, diff --git a/source/tests/test_descrpt_nonsmth.py b/source/tests/test_descrpt_nonsmth.py index 0414607b58..91a8915ef8 100644 --- a/source/tests/test_descrpt_nonsmth.py +++ b/source/tests/test_descrpt_nonsmth.py @@ -24,9 +24,9 @@ from deepmd.RunOptions import global_ener_float_precision class Inter(): - def __init__ (self, - data, - comp = 0) : + def setUp (self, + data, + comp = 0) : self.sess = tf.Session() self.data = data self.natoms = self.data.get_natoms() @@ -77,12 +77,13 @@ def comp_ef (self, tnatoms, name, reuse = None) : + t_default_mesh = tf.constant(self.default_mesh) descrpt, descrpt_deriv, rij, nlist, axis, rot_mat \ = op_module.descrpt (dcoord, dtype, tnatoms, dbox, - tf.constant(self.default_mesh), + t_default_mesh, self.t_avg, self.t_std, rcut_a = self.rcut_a, @@ -153,49 +154,29 @@ def comp_v_dw (self, class TestNonSmooth(Inter, unittest.TestCase): - def __init__ (self, *args, **kwargs): + # def __init__ (self, *args, **kwargs): + # self.places = 5 + # data = Data() + # Inter.__init__(self, data) + # unittest.TestCase.__init__(self, *args, **kwargs) + # self.controller = object() + + def setUp(self): self.places = 5 data = Data() - Inter.__init__(self, data) - unittest.TestCase.__init__(self, *args, **kwargs) - self.controller = object() + Inter.setUp(self, data) def test_force (self) : - force_test(self, self) - # t_energy, t_force, t_virial \ - # = self.comp_ef (self.coord, self.box, self.type, self.tnatoms, name = "test") - # self.sess.run (tf.global_variables_initializer()) - # dcoord, dbox, dtype = self.data.get_data () - # hh = 1e-6 - # dcoordp = np.copy(dcoord) - # dcoordm = np.copy(dcoord) - # dcoordp[0,0] = dcoord[0,0] + hh - # dcoordm[0,0] = dcoord[0,0] - hh - # [axis0, nlist0, d0] = self.sess.run ([self.axis, self.nlist, self.descrpt], - # feed_dict = { - # self.coord: dcoordp, - # self.box: dbox, - # self.type: dtype, - # self.tnatoms: self.natoms} - # ) - # [axis1, nlist1, d1] = self.sess.run ([self.axis, self.nlist, self.descrpt], - # feed_dict = { - # self.coord: dcoordm, - # self.box: dbox, - # self.type: dtype, - # self.tnatoms: self.natoms} - # ) - # print((nlist0 - nlist1)) - # print((axis0 - axis1)) + force_test(self, self, suffix = '_se') def test_virial (self) : - virial_test(self, self) + virial_test(self, self, suffix = '_se') def test_force_dw (self) : - force_dw_test(self, self) + force_dw_test(self, self, suffix = '_se') def test_virial_dw (self) : - virial_dw_test(self, self) + virial_dw_test(self, self, suffix = '_se') if __name__ == '__main__': diff --git a/source/tests/test_descrpt_se_ar.py b/source/tests/test_descrpt_se_ar.py index 823bbb67ec..651724ae7a 100644 --- a/source/tests/test_descrpt_se_ar.py +++ b/source/tests/test_descrpt_se_ar.py @@ -26,8 +26,8 @@ from deepmd.RunOptions import global_ener_float_precision class Inter(): - def __init__ (self, - data) : + def setUp (self, + data) : self.sess = tf.Session() self.data = data self.natoms = self.data.get_natoms() @@ -99,11 +99,16 @@ def comp_ef (self, class TestDescrptAR(Inter, unittest.TestCase): - def __init__ (self, *args, **kwargs): + # def __init__ (self, *args, **kwargs): + # data = Data() + # Inter.__init__(self, data) + # unittest.TestCase.__init__(self, *args, **kwargs) + # self.controller = object() + + def setUp(self): + self.places = 5 data = Data() - Inter.__init__(self, data) - unittest.TestCase.__init__(self, *args, **kwargs) - self.controller = object() + Inter.setUp(self, data) def test_force (self) : force_test(self, self, suffix = '_se_ar') diff --git a/source/tests/test_descrpt_se_r.py b/source/tests/test_descrpt_se_r.py index 83d6dd1f47..ece2fb229c 100644 --- a/source/tests/test_descrpt_se_r.py +++ b/source/tests/test_descrpt_se_r.py @@ -26,8 +26,8 @@ from deepmd.RunOptions import global_ener_float_precision class Inter(): - def __init__ (self, - data) : + def setUp (self, + data) : self.sess = tf.Session() self.data = data self.natoms = self.data.get_natoms() @@ -137,11 +137,16 @@ def comp_v_dw (self, class TestSmooth(Inter, unittest.TestCase): - def __init__ (self, *args, **kwargs): + # def __init__ (self, *args, **kwargs): + # data = Data() + # Inter.__init__(self, data) + # unittest.TestCase.__init__(self, *args, **kwargs) + # self.controller = object() + + def setUp(self): + self.places = 5 data = Data() - Inter.__init__(self, data) - unittest.TestCase.__init__(self, *args, **kwargs) - self.controller = object() + Inter.setUp(self, data) def test_force (self) : force_test(self, self, suffix = '_se_r') diff --git a/source/tests/test_descrpt_smooth.py b/source/tests/test_descrpt_smooth.py index f718a5925d..415f56a9aa 100644 --- a/source/tests/test_descrpt_smooth.py +++ b/source/tests/test_descrpt_smooth.py @@ -26,8 +26,8 @@ from deepmd.RunOptions import global_ener_float_precision class Inter(): - def __init__ (self, - data) : + def setUp (self, + data) : self.sess = tf.Session() self.data = data self.natoms = self.data.get_natoms() @@ -148,11 +148,16 @@ def comp_v_dw (self, class TestSmooth(Inter, unittest.TestCase): - def __init__ (self, *args, **kwargs): + # def __init__ (self, *args, **kwargs): + # data = Data() + # Inter.__init__(self, data) + # unittest.TestCase.__init__(self, *args, **kwargs) + # self.controller = object() + + def setUp(self): + self.places = 5 data = Data() - Inter.__init__(self, data) - unittest.TestCase.__init__(self, *args, **kwargs) - self.controller = object() + Inter.setUp(self, data) def test_force (self) : force_test(self, self, suffix = '_smth') diff --git a/source/tests/test_ewald.py b/source/tests/test_ewald.py index 4e8586aa3c..b6aee7d6b0 100644 --- a/source/tests/test_ewald.py +++ b/source/tests/test_ewald.py @@ -209,7 +209,7 @@ def test_virial(self): for jj in range(3): self.assertAlmostEqual(t_esti[ff][ii][jj], virial[ff,ii*3+jj], places = places, - msg = "frame %d forcvirial component [%d,%d] failed" % (ff, ii, jj)) + msg = "frame %d virial component [%d,%d] failed" % (ff, ii, jj)) diff --git a/source/tests/test_tab_nonsmth.py b/source/tests/test_tab_nonsmth.py index ef77792071..007d41cd63 100644 --- a/source/tests/test_tab_nonsmth.py +++ b/source/tests/test_tab_nonsmth.py @@ -35,10 +35,10 @@ def _make_tab(ntype) : class IntplInter(Inter): - def __init__ (self, - data) : + def setUp (self, + data) : # tabulated - Inter.__init__(self, data) + Inter.setUp(self, data) _make_tab(data.get_ntypes()) self.srtab = TabInter('tab.xvg') self.smin_alpha = 0.3 @@ -153,12 +153,17 @@ def comp_interpl_ef (self, class TestTabNonSmooth(IntplInter, unittest.TestCase): - def __init__ (self, *args, **kwargs): + # def __init__ (self, *args, **kwargs): + # self.places = 5 + # data = Data() + # IntplInter.__init__(self, data) + # unittest.TestCase.__init__(self, *args, **kwargs) + # self.controller = object() + + def setUp(self): self.places = 5 data = Data() - IntplInter.__init__(self, data) - unittest.TestCase.__init__(self, *args, **kwargs) - self.controller = object() + IntplInter.setUp(self, data) def test_force (self) : force_test(self, self, places=5, suffix = '_tab') diff --git a/source/tests/test_tab_smooth.py b/source/tests/test_tab_smooth.py index 28219cd504..6d34aa06d1 100644 --- a/source/tests/test_tab_smooth.py +++ b/source/tests/test_tab_smooth.py @@ -35,10 +35,10 @@ def _make_tab(ntype) : class IntplInter(Inter): - def __init__ (self, - data) : + def setUp (self, + data) : # tabulated - Inter.__init__(self, data) + Inter.setUp(self, data) _make_tab(data.get_ntypes()) self.srtab = TabInter('tab.xvg') self.smin_alpha = 0.3 @@ -151,12 +151,17 @@ def comp_ef (self, class TestTabSmooth(IntplInter, unittest.TestCase): - def __init__ (self, *args, **kwargs): + # def __init__ (self, *args, **kwargs): + # self.places = 5 + # data = Data() + # IntplInter.__init__(self, data) + # unittest.TestCase.__init__(self, *args, **kwargs) + # self.controller = object() + + def setUp(self): self.places = 5 data = Data() - IntplInter.__init__(self, data) - unittest.TestCase.__init__(self, *args, **kwargs) - self.controller = object() + IntplInter.setUp(self, data) def test_force (self) : force_test(self, self, places=5, suffix = '_tab_smth') From c23adeeda7c879f596be98fb8825b12a07b856eb Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 28 Oct 2019 11:12:53 +0800 Subject: [PATCH 007/147] implement data modifier, substract long-range interaction from data --- source/scripts/freeze.py | 2 +- source/tests/test_data_modifier.py | 157 ++++++++++++++++ source/tests/test_sel_idx.py | 20 ++ source/train/CMakeLists.txt | 2 +- source/train/Data.py | 14 +- source/train/DataModifier.py | 293 +++++++++++++++++++++++++++++ source/train/DataSystem.py | 7 +- source/train/DeepEval.py | 22 +-- source/train/DescrptSeA.py | 10 + source/train/common.py | 11 ++ source/train/train.py | 27 ++- 11 files changed, 542 insertions(+), 23 deletions(-) create mode 100644 source/tests/test_data_modifier.py create mode 100644 source/tests/test_sel_idx.py create mode 100644 source/train/DataModifier.py diff --git a/source/scripts/freeze.py b/source/scripts/freeze.py index 62a7f4559f..06f1df86c1 100755 --- a/source/scripts/freeze.py +++ b/source/scripts/freeze.py @@ -41,7 +41,7 @@ def _make_node_names(model_type = None) : elif model_type == 'wfc': nodes = "o_wfc,descrpt_attr/rcut,descrpt_attr/ntypes,model_attr/tmap,model_attr/sel_type,model_attr/model_type" elif model_type == 'dipole': - nodes = "o_dipole,descrpt_attr/rcut,descrpt_attr/ntypes,model_attr/tmap,model_attr/sel_type,model_attr/model_type" + nodes = "o_dipole,o_rmat,o_rmat_deriv,o_nlist,o_rij,descrpt_attr/rcut,descrpt_attr/ntypes,descrpt_attr/sel,descrpt_attr/ndescrpt,model_attr/tmap,model_attr/sel_type,model_attr/model_type" elif model_type == 'polar': nodes = "o_polar,descrpt_attr/rcut,descrpt_attr/ntypes,model_attr/tmap,model_attr/sel_type,model_attr/model_type" else: diff --git a/source/tests/test_data_modifier.py b/source/tests/test_data_modifier.py new file mode 100644 index 0000000000..dd41a27863 --- /dev/null +++ b/source/tests/test_data_modifier.py @@ -0,0 +1,157 @@ +import os,sys,platform,json +import numpy as np +import unittest +from deepmd.env import tf + +from deepmd.common import j_must_have, data_requirement +from deepmd.RunOptions import RunOptions +from deepmd.Trainer import NNPTrainer +from deepmd.DataSystem import DeepmdDataSystem +from deepmd.RunOptions import global_tf_float_precision +from deepmd.RunOptions import global_np_float_precision +from deepmd.RunOptions import global_ener_float_precision +from deepmd.EwaldRecp import EwaldRecp +from deepmd.DataModifier import DipoleChargeModifier + +from common import Data + +if global_np_float_precision == np.float32 : + global_default_fv_hh = 1e-2 + global_default_dw_hh = 1e-2 + global_default_places = 3 +else : + global_default_fv_hh = 1e-6 + global_default_dw_hh = 1e-4 + global_default_places = 5 + +modifier_datapath = 'data_modifier' + +class Args() : + INPUT = os.path.join(modifier_datapath, 'dipole.json') + restart = None + init_model = None + inter_threads = 0 + +class TestDataModifier (unittest.TestCase) : + + def setUp(self): + # with tf.variable_scope('load', reuse = False) : + tf.reset_default_graph() + self._setUp() + + def tearDown(self): + tf.reset_default_graph() + + def _setUp(self): + args = Args() + run_opt = RunOptions(args, False) + with open (args.INPUT, 'r') as fp: + jdata = json.load (fp) + + # init model + model = NNPTrainer (jdata, run_opt = run_opt) + rcut = model.model.get_rcut() + + # init data system + systems = j_must_have(jdata['training'], 'systems') + set_pfx = j_must_have(jdata['training'], 'set_prefix') + batch_size = j_must_have(jdata['training'], 'batch_size') + test_size = j_must_have(jdata['training'], 'numb_test') + data = DeepmdDataSystem(systems, + batch_size, + test_size, + rcut, + set_prefix=set_pfx, + run_opt=run_opt) + data.add_dict(data_requirement) + + # clear the default graph + tf.reset_default_graph() + + # build the model with stats from the first system + model.build (data) + + # freeze the graph + with tf.Session() as sess: + init_op = tf.global_variables_initializer() + sess.run(init_op) + graph = tf.get_default_graph() + input_graph_def = graph.as_graph_def() + nodes = "o_dipole,o_rmat,o_rmat_deriv,o_nlist,o_rij,descrpt_attr/rcut,descrpt_attr/ntypes,descrpt_attr/sel,descrpt_attr/ndescrpt,model_attr/tmap,model_attr/sel_type,model_attr/model_type" + output_graph_def = tf.graph_util.convert_variables_to_constants( + sess, + input_graph_def, + nodes.split(",") + ) + output_graph = os.path.join(modifier_datapath, 'dipole.pb') + with tf.gfile.GFile(output_graph, "wb") as f: + f.write(output_graph_def.SerializeToString()) + + def test_fv(self): + # with tf.variable_scope('load', reuse = False) : + self._test_fv() + + def _test_fv (self): + dcm = DipoleChargeModifier(os.path.join(modifier_datapath, "dipole.pb"), + [-8], + [6, 1], + 1, + 0.25) + data = Data() + coord, box, atype = data.get_data() + + ve, vf, vv = dcm.eval_modify(coord, box, atype) + + hh = global_default_fv_hh + hh=1e-4 + places = global_default_places + places=1 + nframes = coord.shape[0] + ndof = coord.shape[1] + natoms = ndof // 3 + for ii in range(ndof): + coordp = np.copy(coord) + coordm = np.copy(coord) + coordp[:,ii] += hh + coordm[:,ii] -= hh + ep, _, __ = dcm.eval_modify(coordp, box, atype, eval_fv = False) + em, _, __ = dcm.eval_modify(coordm, box, atype, eval_fv = False) + num_f = -(ep - em) / (2.*hh) + for ff in range(nframes): + self.assertAlmostEqual(vf[ff,ii], num_f[ff], + places = places, + msg = 'frame %d dof %d does not match' % (ff, ii)) + + box3 = np.reshape(box, [nframes, 3,3]) + rbox3 = np.linalg.inv(box3) + coord3 = np.reshape(coord, [nframes, natoms, 3]) + rcoord3 = np.matmul(coord3, rbox3) + num_deriv = np.zeros([nframes,3,3]) + for ii in range(3): + for jj in range(3): + box3p = np.copy(box3) + box3m = np.copy(box3) + box3p[:,ii,jj] = box3[:,ii,jj] + hh + box3m[:,ii,jj] = box3[:,ii,jj] - hh + boxp = np.reshape(box3p, [-1,9]) + boxm = np.reshape(box3m, [-1,9]) + coord3p = np.matmul(rcoord3, box3p) + coord3m = np.matmul(rcoord3, box3m) + coordp = np.reshape(coord3p, [nframes,-1]) + coordm = np.reshape(coord3m, [nframes,-1]) + ep, _, __ = dcm.eval_modify(coordp, boxp, atype, eval_fv = False) + em, _, __ = dcm.eval_modify(coordm, boxm, atype, eval_fv = False) + num_deriv[:,ii,jj] = -(ep - em) / (2.*hh) + # box3t = np.transpose(box3, [0,2,1]) + # t_esti = np.matmul(num_deriv, box3t) + num_deriv = np.transpose(num_deriv, [0,2,1]) + t_esti = np.matmul(num_deriv, box3) + + print(t_esti, '\n', vv.reshape([-1, 3, 3])) + for ff in range(nframes): + for ii in range(3): + for jj in range(3): + self.assertAlmostEqual(t_esti[ff][ii][jj], vv[ff,ii*3+jj], + places = places, + msg = "frame %d virial component [%d,%d] failed" % (ff, ii, jj)) + diff --git a/source/tests/test_sel_idx.py b/source/tests/test_sel_idx.py new file mode 100644 index 0000000000..47ef9c8496 --- /dev/null +++ b/source/tests/test_sel_idx.py @@ -0,0 +1,20 @@ +import os,sys +import numpy as np +import unittest + +from deepmd.common import select_idx_map + +def test(): + raise RuntimeError + +class TestSelIdx (unittest.TestCase) : + def test_add (self) : + atom_type = np.array([0,1,2,2,1,0], dtype = int) + type_sel = np.array([1,0], dtype = int) + idx_map = select_idx_map(atom_type, type_sel) + new_atom_type = atom_type[idx_map] + self.assertEqual(list(idx_map), [0, 5, 1, 4]) + self.assertEqual(list(new_atom_type), [0, 0, 1, 1]) + +if __name__ == '__main__': + unittest.main() diff --git a/source/train/CMakeLists.txt b/source/train/CMakeLists.txt index 7b990d3df9..6f507d0607 100644 --- a/source/train/CMakeLists.txt +++ b/source/train/CMakeLists.txt @@ -2,7 +2,7 @@ configure_file("RunOptions.py.in" "${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py" @ONLY) -file(GLOB LIB_PY main.py common.py env.py compat.py Network.py Deep*.py Data.py DataSystem.py Model*.py Descrpt*.py Fitting.py Loss.py LearningRate.py Trainer.py TabInter.py EwaldRecp.py ${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py) +file(GLOB LIB_PY main.py common.py env.py compat.py Network.py Deep*.py Data.py DataSystem.py Model*.py Descrpt*.py Fitting.py Loss.py LearningRate.py Trainer.py TabInter.py EwaldRecp.py DataModifier.py ${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py) file(GLOB CLS_PY Local.py Slurm.py) diff --git a/source/train/Data.py b/source/train/Data.py index 399a13712b..7445f5ec1c 100644 --- a/source/train/Data.py +++ b/source/train/Data.py @@ -14,7 +14,8 @@ def __init__ (self, sys_path, set_prefix = 'set', shuffle_test = True, - type_map = None) : + type_map = None, + modifier = None) : self.dirs = glob.glob (os.path.join(sys_path, set_prefix + ".*")) self.dirs.sort() # load atom type @@ -46,6 +47,8 @@ def __init__ (self, self.set_count = 0 self.iterator = 0 self.shuffle_test = shuffle_test + # set modifier + self.modifier = modifier def add(self, @@ -139,7 +142,7 @@ def get_numb_set (self) : return len (self.train_dirs) def get_numb_batch (self, batch_size, set_idx) : - data = self._load_set(self.train_dirs[set_idx]) + data = self._load_set(self.train_dirs[set_idx], modify = False) return data["coord"].shape[0] // batch_size def get_sys_numb_batch (self, batch_size) : @@ -237,7 +240,7 @@ def _shuffle_data (self, ret[kk] = data[kk] return ret, idx - def _load_set(self, set_name) : + def _load_set(self, set_name, modify = True) : ret = {} # get nframes path = os.path.join(set_name, "coord.npy") @@ -269,7 +272,10 @@ def _load_set(self, set_name) : data['find_'+kk] = data['find_'+k_in] tmp_in = data[k_in].astype(global_ener_float_precision) data[kk] = np.sum(np.reshape(tmp_in, [nframes, self.natoms, ndof]), axis = 1) - + + if modify and self.modifier is not None: + self.modifier.modify(data) + return data diff --git a/source/train/DataModifier.py b/source/train/DataModifier.py new file mode 100644 index 0000000000..165a1abc71 --- /dev/null +++ b/source/train/DataModifier.py @@ -0,0 +1,293 @@ +import os,platform +import numpy as np +from deepmd import DeepDipole +from deepmd.env import tf +from deepmd.common import select_idx_map +from deepmd.EwaldRecp import EwaldRecp +from deepmd.RunOptions import global_tf_float_precision +from deepmd.RunOptions import global_np_float_precision +from deepmd.RunOptions import global_ener_float_precision +from deepmd.RunOptions import global_cvt_2_tf_float +from deepmd.RunOptions import global_cvt_2_ener_float + +if platform.system() == "Windows": + ext = "dll" +elif platform.system() == "Darwin": + ext = "dylib" +else: + ext = "so" + +module_path = os.path.dirname(os.path.realpath(__file__)) + "/" +assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" +op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) + + +class DipoleChargeModifier(DeepDipole): + def __init__(self, + model_name, + model_charge_map, + sys_charge_map, + ewald_h = 1, + ewald_beta = 1): + DeepDipole.__init__(self, model_name) + self.er = EwaldRecp(ewald_h, ewald_beta) + self.model_charge_map = model_charge_map + self.sys_charge_map = sys_charge_map + self.sel_type = list(self.get_sel_type()) + # dimension of dipole + self.ext_dim = 3 + self.t_ndesc = self.graph.get_tensor_by_name ('load/descrpt_attr/ndescrpt:0') + self.t_sela = self.graph.get_tensor_by_name ('load/descrpt_attr/sel:0') + [self.ndescrpt, self.sel_a] = self.sess.run([self.t_ndesc, self.t_sela]) + self.sel_r = [ 0 for ii in range(len(self.sel_a)) ] + self.nnei_a = np.cumsum(self.sel_a)[-1] + self.nnei_r = np.cumsum(self.sel_r)[-1] + self.nnei = self.nnei_a + self.nnei_r + self.ndescrpt_a = self.nnei_a * 4 + self.ndescrpt_r = self.nnei_r * 1 + assert(self.ndescrpt == self.ndescrpt_a + self.ndescrpt_r) + self.force = None + self.ntypes = len(self.sel_a) + + def build_fv_graph(self): + with self.graph.as_default(): + return self._build_fv_graph_inner() + + def _build_fv_graph_inner(self): + self.t_ef = tf.placeholder(global_tf_float_precision, [None], name = 't_ef') + nf = 10 + nfxnas = 64*nf + nfxna = 192*nf + nf = -1 + nfxnas = -1 + nfxna = -1 + self.t_box_reshape = tf.reshape(self.t_box, [-1, 9]) + t_nframes = tf.shape(self.t_box_reshape)[0] + # (nframes x natoms_sel) x 1 x 3 + self.t_ef_reshape = tf.reshape(self.t_ef, [nfxnas, 1, 3]) + # (nframes x natoms) x ndescrpt + self.descrpt = self.graph.get_tensor_by_name('load/o_rmat:0') + self.descrpt_deriv = self.graph.get_tensor_by_name('load/o_rmat_deriv:0') + self.nlist = self.graph.get_tensor_by_name('load/o_nlist:0') + self.rij = self.graph.get_tensor_by_name('load/o_rij:0') + # self.descrpt_reshape = tf.reshape(self.descrpt, [nf, 192 * self.ndescrpt]) + # self.descrpt_deriv = tf.reshape(self.descrpt_deriv, [nf, 192 * self.ndescrpt * 3]) + + # nframes x (natoms_sel x 3) + self.t_tensor_reshpe = tf.reshape(self.t_tensor, [t_nframes, -1]) + # nframes x (natoms x 3) + self.t_tensor_reshpe = self._enrich(self.t_tensor_reshpe, dof = 3) + # (nframes x natoms) x 3 + self.t_tensor_reshpe = tf.reshape(self.t_tensor_reshpe, [nfxna, 3]) + # (nframes x natoms) x 1 + self.t_dipole_x = tf.slice(self.t_tensor_reshpe, [0, 0], [nfxna, 1]) + self.t_dipole_y = tf.slice(self.t_tensor_reshpe, [0, 1], [nfxna, 1]) + self.t_dipole_z = tf.slice(self.t_tensor_reshpe, [0, 2], [nfxna, 1]) + self.t_dipole_z = tf.reshape(self.t_dipole_z, [nfxna, 1]) + # (nframes x natoms) x ndescrpt + [self.t_dipole_x_d] = tf.gradients(self.t_dipole_x, self.descrpt) + [self.t_dipole_y_d] = tf.gradients(self.t_dipole_y, self.descrpt) + [self.t_dipole_z_d] = tf.gradients(self.t_dipole_z, self.descrpt) + # nframes x (natoms x ndescrpt) + self.t_dipole_x_d = tf.reshape(self.t_dipole_x_d, [-1, self.t_natoms[0] * self.ndescrpt]) + self.t_dipole_y_d = tf.reshape(self.t_dipole_y_d, [-1, self.t_natoms[0] * self.ndescrpt]) + self.t_dipole_z_d = tf.reshape(self.t_dipole_z_d, [-1, self.t_natoms[0] * self.ndescrpt]) + # nframes x (natoms_sel x ndescrpt) + self.t_dipole_x_d = self._slice_descrpt_deriv(self.t_dipole_x_d) + self.t_dipole_y_d = self._slice_descrpt_deriv(self.t_dipole_y_d) + self.t_dipole_z_d = self._slice_descrpt_deriv(self.t_dipole_z_d) + # (nframes x natoms_sel) x ndescrpt + self.t_dipole_x_d = tf.reshape(self.t_dipole_x_d, [nfxnas, self.ndescrpt]) + self.t_dipole_y_d = tf.reshape(self.t_dipole_y_d, [nfxnas, self.ndescrpt]) + self.t_dipole_z_d = tf.reshape(self.t_dipole_z_d, [nfxnas, self.ndescrpt]) + # (nframes x natoms_sel) x 3 x ndescrpt + self.t_dipole_d = tf.concat([self.t_dipole_x_d, self.t_dipole_y_d, self.t_dipole_z_d], axis = 1) + self.t_dipole_d = tf.reshape(self.t_dipole_d, [nfxnas, 3*self.ndescrpt]) + # (nframes x natoms_sel) x 3 x ndescrpt + self.t_dipole_d = tf.reshape(self.t_dipole_d, [-1, 3, self.ndescrpt]) + # (nframes x natoms_sel) x 1 x ndescrpt + self.t_ef_d = tf.matmul(self.t_ef_reshape, self.t_dipole_d) + # nframes x (natoms_sel x ndescrpt) + self.t_ef_d = tf.reshape(self.t_ef_d, [t_nframes, -1]) + # nframes x (natoms x ndescrpt) + self.t_ef_d = self._enrich(self.t_ef_d, dof = self.ndescrpt) + self.t_ef_d = tf.reshape(self.t_ef_d, [nf, self.t_natoms[0] * self.ndescrpt]) + # t_ef_d is force (with -1), prod_forc takes deriv, so we need the opposite + self.t_ef_d_oppo = -self.t_ef_d + + force = op_module.prod_force_se_a(self.t_ef_d_oppo, + self.descrpt_deriv, + self.nlist, + self.t_natoms, + n_a_sel = self.nnei_a, + n_r_sel = self.nnei_r) + virial, atom_virial \ + = op_module.prod_virial_se_a (self.t_ef_d_oppo, + self.descrpt_deriv, + self.rij, + self.nlist, + self.t_natoms, + n_a_sel = self.nnei_a, + n_r_sel = self.nnei_r) + return force, virial, atom_virial + + def _enrich(self, dipole, dof = 3): + coll = [] + sel_start_idx = 0 + for type_i in range(self.ntypes): + if type_i in self.sel_type: + di = tf.slice(dipole, + [ 0, sel_start_idx * dof], + [-1, self.t_natoms[2+type_i] * dof]) + sel_start_idx += self.t_natoms[2+type_i] + else: + di = tf.zeros([tf.shape(dipole)[0], self.t_natoms[2+type_i] * dof], + dtype = global_tf_float_precision) + coll.append(di) + return tf.concat(coll, axis = 1) + + def _slice_descrpt_deriv(self, deriv): + coll = [] + start_idx = 0 + for type_i in range(self.ntypes): + if type_i in self.sel_type: + di = tf.slice(deriv, + [ 0, start_idx * self.ndescrpt], + [-1, self.t_natoms[2+type_i] * self.ndescrpt]) + coll.append(di) + start_idx += self.t_natoms[2+type_i] + return tf.concat(coll, axis = 1) + + + def eval_modify(self, coord, box, atype, eval_fv = True): + natoms = coord.shape[1] // 3 + nframes = coord.shape[0] + box = np.reshape(box, [nframes, 9]) + atype = np.reshape(atype, [nframes, natoms]) + sel_idx_map = select_idx_map(atype[0], self.sel_type) + nsel = len(sel_idx_map) + # setup charge + charge = np.zeros([natoms]) + for ii in range(natoms): + charge[ii] = self.sys_charge_map[atype[0][ii]] + charge = np.tile(charge, [nframes, 1]) + + # add wfcc + all_coord, all_charge, dipole = self._extend_system(coord, box, atype, charge) + + # print('compute er') + tot_e, all_f, all_v = self.er.eval(all_coord, all_charge, box) + # print('finish er') + + tot_f = None + tot_v = None + if self.force is None: + self.force, self.virial, self.av = self.build_fv_graph() + if eval_fv: + # compute f + ext_f = all_f[:,natoms*3:] + corr_f, corr_v, corr_av = self.eval_fv(coord, box, atype[0], ext_f) + tot_f = all_f[:,:natoms*3] + corr_f + for ii in range(nsel): + orig_idx = sel_idx_map[ii] + tot_f[:,orig_idx*3:orig_idx*3+3] += ext_f[:,ii*3:ii*3+3] + # compute v + dipole3 = np.reshape(dipole, [nframes, nsel, 3]) + ext_f3 = np.reshape(ext_f, [nframes, nsel, 3]) + ext_f3 = np.transpose(ext_f3, [0, 2, 1]) + # fd_corr_v = -np.matmul(ext_f3, dipole3).T.reshape([nframes, 9]) + # fd_corr_v = -np.matmul(ext_f3, dipole3) + # fd_corr_v = np.transpose(fd_corr_v, [0, 2, 1]).reshape([nframes, 9]) + fd_corr_v = -np.matmul(ext_f3, dipole3).reshape([nframes, 9]) + # print(all_v, '\n', corr_v, '\n', fd_corr_v) + tot_v = all_v + corr_v + fd_corr_v + + return tot_e, tot_f, tot_v + + + def eval_fv(self, coords, cells, atom_types, ext_f) : + # reshape the inputs + cells = np.reshape(cells, [-1, 9]) + nframes = cells.shape[0] + coords = np.reshape(coords, [nframes, -1]) + natoms = coords.shape[1] // 3 + + # sort inputs + coords, atom_types, imap, sel_at, sel_imap = self.sort_input(coords, atom_types, sel_atoms = self.get_sel_type()) + + # make natoms_vec and default_mesh + natoms_vec = self.make_natoms_vec(atom_types) + assert(natoms_vec[0] == natoms) + default_mesh = self.make_default_mesh(cells) + + # evaluate + tensor = [] + feed_dict_test = {} + feed_dict_test[self.t_natoms] = natoms_vec + feed_dict_test[self.t_type ] = np.tile(atom_types, [nframes, 1]).reshape([-1]) + feed_dict_test[self.t_coord ] = coords.reshape([-1]) + feed_dict_test[self.t_box ] = cells.reshape([-1]) + feed_dict_test[self.t_mesh ] = default_mesh.reshape([-1]) + feed_dict_test[self.t_ef ] = ext_f.reshape([-1]) + # print(self.sess.run(tf.shape(self.t_tensor), feed_dict = feed_dict_test)) + fout, vout, avout \ + = self.sess.run([self.force, self.virial, self.av], + feed_dict = feed_dict_test) + # print('fout: ', fout.shape, fout) + return fout, vout, avout + + + def _extend_system(self, coord, box, atype, charge): + natoms = coord.shape[1] // 3 + nframes = coord.shape[0] + # sel atoms and setup ref coord + sel_idx_map = select_idx_map(atype[0], self.sel_type) + nsel = len(sel_idx_map) + coord3 = coord.reshape([nframes, natoms, 3]) + ref_coord = coord3[:,sel_idx_map,:] + ref_coord = np.reshape(ref_coord, [nframes, nsel * 3]) + + dipole = self.eval(coord, box, atype[0]) + dipole = np.reshape(dipole, [nframes, nsel * 3]) + + wfcc_coord = ref_coord + dipole + # wfcc_coord = dipole + wfcc_charge = np.zeros([nsel]) + for ii in range(nsel): + orig_idx = self.sel_type.index(atype[0][sel_idx_map[ii]]) + wfcc_charge[ii] = self.model_charge_map[orig_idx] + wfcc_charge = np.tile(wfcc_charge, [nframes, 1]) + + wfcc_coord = np.reshape(wfcc_coord, [nframes, nsel * 3]) + wfcc_charge = np.reshape(wfcc_charge, [nframes, nsel]) + + all_coord = np.concatenate((coord, wfcc_coord), axis = 1) + all_charge = np.concatenate((charge, wfcc_charge), axis = 1) + + return all_coord, all_charge, dipole + + + def modify(self, + data): + if 'find_energy' not in data and 'find_force' not in data and 'find_virial' not in data: + return + + get_nframes=None + coord = data['coord'][:get_nframes,:] + box = data['box'][:get_nframes,:] + atype = data['type'][:get_nframes,:] + nframes = coord.shape[0] + + tot_e, tot_f, tot_v = self.eval_modify(coord, box, atype) + + # print(tot_f[:,0]) + + if 'find_energy' in data and data['find_energy'] == 1.0 : + data['energy'] -= tot_e.reshape([nframes, 1]) + if 'find_force' in data and data['find_force'] == 1.0 : + data['force'] -= tot_f + if 'find_virial' in data and data['find_virial'] == 1.0 : + data['virial'] -= tot_v.reshape([nframes, 9]) + + + diff --git a/source/train/DataSystem.py b/source/train/DataSystem.py index 7bb61b477c..b967074a64 100644 --- a/source/train/DataSystem.py +++ b/source/train/DataSystem.py @@ -19,7 +19,8 @@ def __init__ (self, set_prefix = 'set', shuffle_test = True, run_opt = None, - type_map = None) : + type_map = None, + modifier = None) : # init data self.rcut = rcut self.system_dirs = systems @@ -29,8 +30,8 @@ def __init__ (self, self.data_systems.append(DeepmdData(ii, set_prefix=set_prefix, shuffle_test=shuffle_test, - type_map = type_map)) - + type_map = type_map, + modifier = modifier)) # batch size self.batch_size = batch_size if isinstance(self.batch_size, int) : diff --git a/source/train/DeepEval.py b/source/train/DeepEval.py index f78699b6f8..8e9e1d7113 100644 --- a/source/train/DeepEval.py +++ b/source/train/DeepEval.py @@ -52,17 +52,17 @@ def load_graph(self, return graph def make_default_mesh(self, test_box) : - ncell = np.ones (3, dtype=np.int32) - avg_box = np.average (test_box, axis = 0) cell_size = 3 - avg_box = np.reshape (avg_box, [3,3]) - for ii in range (3) : - ncell[ii] = int ( np.linalg.norm(avg_box[ii]) / cell_size ) - if (ncell[ii] < 2) : ncell[ii] = 2 - default_mesh = np.zeros (6, dtype = np.int32) - default_mesh[3] = ncell[0] - default_mesh[4] = ncell[1] - default_mesh[5] = ncell[2] + nframes = test_box.shape[0] + default_mesh = np.zeros([nframes, 6], dtype = np.int32) + for ff in range(nframes): + ncell = np.ones (3, dtype=np.int32) + for ii in range(3) : + ncell[ii] = int ( np.linalg.norm(test_box[ff][ii]) / cell_size ) + if (ncell[ii] < 2) : ncell[ii] = 2 + default_mesh[ff][3] = ncell[0] + default_mesh[ff][4] = ncell[1] + default_mesh[ff][5] = ncell[2] return default_mesh def sort_input(self, coord, atom_type, sel_atoms = None) : @@ -173,12 +173,12 @@ def eval(self, tensor = [] feed_dict_test = {} feed_dict_test[self.t_natoms] = natoms_vec - feed_dict_test[self.t_mesh ] = default_mesh feed_dict_test[self.t_type ] = atom_types t_out = [self.t_tensor] for ii in range(nframes) : feed_dict_test[self.t_coord] = np.reshape(coords[ii:ii+1, :], [-1]) feed_dict_test[self.t_box ] = np.reshape(cells [ii:ii+1, :], [-1]) + feed_dict_test[self.t_mesh ] = default_mesh[ii] v_out = self.sess.run (t_out, feed_dict = feed_dict_test) tensor.append(v_out[0]) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index aa5221d7c7..5df382f683 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -136,6 +136,12 @@ def build (self, t_ntypes = tf.constant(self.ntypes, name = 'ntypes', dtype = tf.int32) + t_ndescrpt = tf.constant(self.ndescrpt, + name = 'ndescrpt', + dtype = tf.int32) + t_sel = tf.constant(self.sel_a, + name = 'sel', + dtype = tf.int32) self.t_avg = tf.get_variable('t_avg', davg.shape, dtype = global_tf_float_precision, @@ -166,6 +172,10 @@ def build (self, sel_r = self.sel_r) self.descrpt_reshape = tf.reshape(self.descrpt, [-1, self.ndescrpt]) + self.descrpt_reshape = tf.identity(self.descrpt_reshape, name = 'o_rmat') + self.descrpt_deriv = tf.identity(self.descrpt_deriv, name = 'o_rmat_deriv') + self.rij = tf.identity(self.rij, name = 'o_rij') + self.nlist = tf.identity(self.nlist, name = 'o_nlist') self.dout, self.qmat = self._pass_filter(self.descrpt_reshape, natoms, suffix = suffix, reuse = reuse) diff --git a/source/train/common.py b/source/train/common.py index f725ae4ec6..7d8e530460 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -1,3 +1,5 @@ +import numpy as np + data_requirement = {} def add_data_requirement(key, @@ -16,6 +18,15 @@ def add_data_requirement(key, } +def select_idx_map(atom_type, + type_sel): + sort_type_sel = np.sort(type_sel) + idx_map = np.array([], dtype = int) + for ii in sort_type_sel: + idx_map = np.append(idx_map, np.where(atom_type == ii)) + return idx_map + + class ClassArg () : def __init__ (self) : self.arg_dict = {} diff --git a/source/train/train.py b/source/train/train.py index a57cb735f1..b41c471a3f 100755 --- a/source/train/train.py +++ b/source/train/train.py @@ -16,6 +16,7 @@ from deepmd.DataSystem import DataSystem, DeepmdDataSystem from deepmd.Trainer import NNPTrainer from deepmd.common import data_requirement +from deepmd.DataModifier import DipoleChargeModifier def create_done_queue(cluster_spec, task_index): with tf.device("/job:ps/task:%d" % (task_index)): @@ -53,8 +54,8 @@ def j_must_have (jdata, key) : def train (args) : # load json database - fp = open (args.INPUT, 'r') - jdata = json.load (fp) + with open (args.INPUT, 'r') as fp: + jdata = json.load (fp) if not 'model' in jdata.keys(): jdata = convert_input_v0_v1(jdata, warning = True, @@ -107,7 +108,27 @@ def _do_work(jdata, run_opt): ipt_type_map = None else: ipt_type_map = type_map - data = DeepmdDataSystem(systems, batch_size, test_size, rcut, set_prefix=set_pfx, run_opt=run_opt, type_map = ipt_type_map) + # data modifier + modifier = None + modi_data = jdata['training'].get("data_modifier", None) + if modi_data is not None: + if modi_data['type'] == 'dipole_charge': + modifier = DipoleChargeModifier(modi_data['model_name'], + modi_data['model_charge_map'], + modi_data['sys_charge_map'], + modi_data['ewald_h'], + modi_data['ewald_beta']) + else: + raise RuntimeError('unknown modifier type ' + str(modi_data['type'])) + # init data + data = DeepmdDataSystem(systems, + batch_size, + test_size, + rcut, + set_prefix=set_pfx, + run_opt=run_opt, + type_map = ipt_type_map, + modifier = modifier) data.add_dict(data_requirement) # build the model with stats from the first system model.build (data) From 8d5d3e8ce503f0a232f3c9369edb2fcd64b76663 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Tue, 5 Nov 2019 18:34:45 +0800 Subject: [PATCH 008/147] batch evaluate ewald and correction --- source/train/DataModifier.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/source/train/DataModifier.py b/source/train/DataModifier.py index 165a1abc71..044b1d8182 100644 --- a/source/train/DataModifier.py +++ b/source/train/DataModifier.py @@ -176,7 +176,18 @@ def eval_modify(self, coord, box, atype, eval_fv = True): all_coord, all_charge, dipole = self._extend_system(coord, box, atype, charge) # print('compute er') - tot_e, all_f, all_v = self.er.eval(all_coord, all_charge, box) + batch_size = 5 + tot_e = [] + all_f = [] + all_v = [] + for ii in range(0,nframes,batch_size): + e,f,v = self.er.eval(all_coord[ii:ii+batch_size], all_charge[ii:ii+batch_size], box[ii:ii+batch_size]) + tot_e.append(e) + all_f.append(f) + all_v.append(v) + tot_e = np.concatenate(tot_e, axis = 0) + all_f = np.concatenate(all_f, axis = 0) + all_v = np.concatenate(all_v, axis = 0) # print('finish er') tot_f = None @@ -186,7 +197,18 @@ def eval_modify(self, coord, box, atype, eval_fv = True): if eval_fv: # compute f ext_f = all_f[:,natoms*3:] - corr_f, corr_v, corr_av = self.eval_fv(coord, box, atype[0], ext_f) + corr_f = [] + corr_v = [] + corr_av = [] + for ii in range(0,nframes,batch_size): + print(ii, nframes) + f, v, av = self.eval_fv(coord[ii:ii+batch_size], box[ii:ii+batch_size], atype[0], ext_f[ii:ii+batch_size]) + corr_f.append(f) + corr_v.append(v) + corr_av.append(av) + corr_f = np.concatenate(corr_f, axis = 0) + corr_v = np.concatenate(corr_v, axis = 0) + corr_av = np.concatenate(corr_av, axis = 0) tot_f = all_f[:,:natoms*3] + corr_f for ii in range(nsel): orig_idx = sel_idx_map[ii] From 06394584c8cf611876ab8ef2f8c46e36b6e433be Mon Sep 17 00:00:00 2001 From: Han Wang Date: Wed, 6 Nov 2019 11:08:49 +0800 Subject: [PATCH 009/147] result of data statisitic (davg, dstd) are private members of descriptor classes --- source/tests/test_descrpt_se_ar.py | 2 +- source/train/DescrptLocFrame.py | 14 +++++++------- source/train/DescrptSeA.py | 14 ++++++-------- source/train/DescrptSeAR.py | 19 ++++++++++++++----- source/train/DescrptSeR.py | 12 ++++++------ source/train/Loss.py | 2 +- source/train/Model.py | 27 +++++++++++---------------- 7 files changed, 46 insertions(+), 44 deletions(-) diff --git a/source/tests/test_descrpt_se_ar.py b/source/tests/test_descrpt_se_ar.py index 651724ae7a..01c9e99496 100644 --- a/source/tests/test_descrpt_se_ar.py +++ b/source/tests/test_descrpt_se_ar.py @@ -89,7 +89,7 @@ def comp_ef (self, tnatoms, name, reuse = None) : - dout = self.descrpt.build(dcoord, dtype, tnatoms, dbox, self.default_mesh, self.avg, self.std, suffix=name, reuse=reuse) + dout = self.descrpt.build(dcoord, dtype, tnatoms, dbox, self.default_mesh, suffix=name, reuse=reuse) inputs_reshape = tf.reshape (dout, [-1, self.descrpt.get_dim_out()]) atom_ener = self._net (inputs_reshape, name, reuse = reuse) atom_ener_reshape = tf.reshape(atom_ener, [-1, self.natoms[0]]) diff --git a/source/train/DescrptLocFrame.py b/source/train/DescrptLocFrame.py index ab00ac31e2..302bdf7496 100644 --- a/source/train/DescrptLocFrame.py +++ b/source/train/DescrptLocFrame.py @@ -42,7 +42,8 @@ def __init__(self, jdata): self.ndescrpt_a = self.nnei_a * 4 self.ndescrpt_r = self.nnei_r * 1 self.ndescrpt = self.ndescrpt_a + self.ndescrpt_r - + self.davg = None + self.dstd = None def get_rcut (self) : return self.rcut_r @@ -85,10 +86,9 @@ def compute_dstats (self, dstd[ii] = 1e-2 all_davg.append(davg) all_dstd.append(dstd) - davg = np.array(all_davg) - dstd = np.array(all_dstd) - return davg, dstd - + self.davg = np.array(all_davg) + self.dstd = np.array(all_dstd) + def build (self, coord_, @@ -96,10 +96,10 @@ def build (self, natoms, box_, mesh, - davg = None, - dstd = None, suffix = '', reuse = None): + davg = self.davg + dstd = self.dstd with tf.variable_scope('descrpt_attr' + suffix, reuse = reuse) : if davg is None: davg = np.zeros([self.ntypes, self.ndescrpt]) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 5df382f683..c13e553aa1 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -50,8 +50,9 @@ def __init__ (self, jdata): self.ndescrpt_a = self.nnei_a * 4 self.ndescrpt_r = self.nnei_r * 1 self.ndescrpt = self.ndescrpt_a + self.ndescrpt_r - self.useBN = False + self.dstd = None + self.davg = None def get_rcut (self) : @@ -108,10 +109,8 @@ def compute_dstats (self, all_davg.append(davg) all_dstd.append(dstd) - davg = np.array(all_davg) - dstd = np.array(all_dstd) - - return davg, dstd + self.davg = np.array(all_davg) + self.dstd = np.array(all_dstd) def build (self, @@ -120,11 +119,10 @@ def build (self, natoms, box_, mesh, - davg = None, - dstd = None, suffix = '', reuse = None): - + davg = self.davg + dstd = self.dstd with tf.variable_scope('descrpt_attr' + suffix, reuse = reuse) : if davg is None: davg = np.zeros([self.ntypes, self.ndescrpt]) diff --git a/source/train/DescrptSeAR.py b/source/train/DescrptSeAR.py index 929b660248..97a254df9a 100644 --- a/source/train/DescrptSeAR.py +++ b/source/train/DescrptSeAR.py @@ -33,6 +33,8 @@ def __init__ (self, jdata): self.descrpt_a = DescrptSeA(self.param_a) self.descrpt_r = DescrptSeR(self.param_r) assert(self.descrpt_a.get_ntypes() == self.descrpt_r.get_ntypes()) + self.davg = None + self.dstd = None def get_rcut (self) : return np.max([self.descrpt_a.get_rcut(), self.descrpt_r.get_rcut()]) @@ -57,7 +59,8 @@ def compute_dstats (self, mesh) : davg_a, dstd_a = self.descrpt_a.compute_dstats(data_coord, data_box, data_atype, natoms_vec, mesh) davg_r, dstd_r = self.descrpt_r.compute_dstats(data_coord, data_box, data_atype, natoms_vec, mesh) - return [davg_a, davg_r], [dstd_a, dstd_r] + self.davg = [davg_a, davg_r] + self.dstd = [dstd_a, dstd_r] def build (self, @@ -66,13 +69,19 @@ def build (self, natoms, box, mesh, - davg, - dstd, suffix = '', reuse = None): + davg = self.davg + dstd = self.dstd + if davg is None: + davg = [np.zeros([self.descrpt_a.ntypes, self.descrpt_a.ndescrpt]), + np.zeros([self.descrpt_r.ntypes, self.descrpt_r.ndescrpt])] + if dstd is None: + dstd = [np.ones ([self.descrpt_a.ntypes, self.descrpt_a.ndescrpt]), + np.ones ([self.descrpt_r.ntypes, self.descrpt_r.ndescrpt])] # dout - self.dout_a = self.descrpt_a.build(coord_, atype_, natoms, box, mesh, davg[0], dstd[0], suffix=suffix+'_a', reuse=reuse) - self.dout_r = self.descrpt_r.build(coord_, atype_, natoms, box, mesh, davg[1], dstd[1], suffix=suffix+'_r', reuse=reuse) + self.dout_a = self.descrpt_a.build(coord_, atype_, natoms, box, mesh, suffix=suffix+'_a', reuse=reuse) + self.dout_r = self.descrpt_r.build(coord_, atype_, natoms, box, mesh, suffix=suffix+'_r', reuse=reuse) self.dout_a = tf.reshape(self.dout_a, [-1, self.descrpt_a.get_dim_out()]) self.dout_r = tf.reshape(self.dout_r, [-1, self.descrpt_r.get_dim_out()]) self.dout = tf.concat([self.dout_a, self.dout_r], axis = 1) diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index b057a0afd3..1f0bd614f6 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -46,8 +46,9 @@ def __init__ (self, jdata): self.ndescrpt_a = self.nnei_a * 4 self.ndescrpt_r = self.nnei_r * 1 self.ndescrpt = self.nnei_r - self.useBN = False + self.davg = None + self.dstd = None def get_rcut (self) : @@ -90,10 +91,9 @@ def compute_dstats (self, all_davg.append(davg) all_dstd.append(dstd) - davg = np.array(all_davg) - dstd = np.array(all_dstd) + self.davg = np.array(all_davg) + self.dstd = np.array(all_dstd) - return davg, dstd def build (self, coord_, @@ -101,10 +101,10 @@ def build (self, natoms, box_, mesh, - davg = None, - dstd = None, suffix = '', reuse = None): + davg = self.davg + dstd = self.dstd with tf.variable_scope('descrpt_attr' + suffix, reuse = reuse) : if davg is None: davg = np.zeros([self.ntypes, self.ndescrpt]) diff --git a/source/train/Loss.py b/source/train/Loss.py index 6d9abf7026..ad1d2211c7 100644 --- a/source/train/Loss.py +++ b/source/train/Loss.py @@ -75,7 +75,7 @@ def build (self, force_hat_reshape = tf.reshape (force_hat, [-1]) atom_pref_reshape = tf.reshape (atom_pref, [-1]) diff_f = force_hat_reshape - force_reshape - if self.relative_f is not None: + if self.relative_f is not None: force_hat_3 = tf.reshape(force_hat, [-1, 3]) norm_f = tf.reshape(tf.norm(force_hat_3, axis = 1), [-1, 1]) + self.relative_f diff_f_3 = tf.reshape(diff_f, [-1, 3]) diff --git a/source/train/Model.py b/source/train/Model.py index 9cbb8e1123..8f54d80e59 100644 --- a/source/train/Model.py +++ b/source/train/Model.py @@ -81,13 +81,13 @@ def data_stat(self, data): def _compute_dstats (self, all_stat, protection = 1e-2) : - self.davg, self.dstd \ - = self.descrpt.compute_dstats(all_stat['coord'], - all_stat['box'], - all_stat['type'], - all_stat['natoms_vec'], - all_stat['default_mesh']) + self.descrpt.compute_dstats(all_stat['coord'], + all_stat['box'], + all_stat['type'], + all_stat['natoms_vec'], + all_stat['default_mesh']) self.fitting.compute_dstats(all_stat, protection = protection) + def build (self, coord_, @@ -129,8 +129,6 @@ def build (self, natoms, box, mesh, - davg = self.davg, - dstd = self.dstd, suffix = suffix, reuse = reuse) dout = tf.identity(dout, name='o_descriptor') @@ -266,12 +264,11 @@ def data_stat(self, data): self._compute_dstats (all_stat) def _compute_dstats (self, all_stat) : - self.davg, self.dstd \ - = self.descrpt.compute_dstats(all_stat['coord'], - all_stat['box'], - all_stat['type'], - all_stat['natoms_vec'], - all_stat['default_mesh']) + self.descrpt.compute_dstats(all_stat['coord'], + all_stat['box'], + all_stat['type'], + all_stat['natoms_vec'], + all_stat['default_mesh']) def build (self, coord_, @@ -302,8 +299,6 @@ def build (self, natoms, box, mesh, - davg = self.davg, - dstd = self.dstd, suffix = suffix, reuse = reuse) dout = tf.identity(dout, name='o_descriptor') From a23ec38cb363c3c0ce1a4374670307e9f8de548b Mon Sep 17 00:00:00 2001 From: Han Wang Date: Wed, 6 Nov 2019 15:30:58 +0800 Subject: [PATCH 010/147] rename dstat to input_stat. Refactorize the stat data generation --- source/tests/test_fitting_stat.py | 2 +- source/tests/test_gen_stat_data.py | 92 +++++++++++++++++++++++++++++ source/train/DescrptLocFrame.py | 2 +- source/train/DescrptSeA.py | 2 +- source/train/DescrptSeAR.py | 6 +- source/train/DescrptSeR.py | 2 +- source/train/Fitting.py | 2 +- source/train/Loss.py | 10 ++-- source/train/Model.py | 95 +++++++++++++++++++++++------- 9 files changed, 179 insertions(+), 34 deletions(-) create mode 100644 source/tests/test_gen_stat_data.py diff --git a/source/tests/test_fitting_stat.py b/source/tests/test_fitting_stat.py index aed3a6992a..0cbd693ae1 100644 --- a/source/tests/test_fitting_stat.py +++ b/source/tests/test_fitting_stat.py @@ -69,7 +69,7 @@ def test (self) : all_data = _make_fake_data(sys_natoms, sys_nframes, avgs, stds) frefa, frefs = _brute_fparam(all_data, len(avgs)) arefa, arefs = _brute_aparam(all_data, len(avgs)) - fitting.compute_dstats(all_data, protection = 1e-2) + fitting.compute_input_stats(all_data, protection = 1e-2) # print(frefa, frefs) for ii in range(len(avgs)): self.assertAlmostEqual(frefa[ii], fitting.fparam_avg[ii]) diff --git a/source/tests/test_gen_stat_data.py b/source/tests/test_gen_stat_data.py new file mode 100644 index 0000000000..d9f99b5818 --- /dev/null +++ b/source/tests/test_gen_stat_data.py @@ -0,0 +1,92 @@ +import os,sys,platform,json,shutil +import numpy as np +import unittest +import dpdata + +from deepmd.DataSystem import DeepmdDataSystem +from deepmd.Model import make_all_stat, merge_sys_stat, _make_all_stat_ref + +def gen_sys(nframes, atom_types): + natoms = len(atom_types) + data = {} + data['coords'] = np.random.random([nframes, natoms, 3]) + data['forces'] = np.random.random([nframes, natoms, 3]) + data['cells'] = np.random.random([nframes, 9]) + data['energies'] = np.random.random([nframes, 1]) + types = list(set(list(atom_types))) + types.sort() + data['atom_names'] = [] + data['atom_numbs'] = [] + for ii in range(len(types)): + data['atom_names'] .append( 'TYPE_%d' % ii ) + data['atom_numbs'] .append(np.sum(atom_types == ii)) + data['atom_types'] = np.array(atom_types, dtype = int) + return data + +class TestGenStatData(unittest.TestCase) : + def setUp(self): + data0 = gen_sys(20, [0, 1, 0, 2, 1]) + data1 = gen_sys(30, [0, 1, 0, 0]) + sys0 = dpdata.LabeledSystem() + sys1 = dpdata.LabeledSystem() + sys0.data = data0 + sys1.data = data1 + sys0.to_deepmd_npy('system_0', set_size = 10) + sys0.to_deepmd_npy('system_1', set_size = 10) + + def tearDown(self): + shutil.rmtree('system_0') + shutil.rmtree('system_1') + + def _comp_data(self, d0, d1) : + for ii in range(d0.shape[0]): + for jj in range(d0.shape[1]): + for kk in range(d0.shape[2]): + self.assertAlmostEqual(d0[ii][jj][kk], d1[ii][jj][kk]) + + def test_merge_all_stat(self): + np.random.seed(0) + data0 = DeepmdDataSystem(['system_0', 'system_1'], + 5, + 10, + 1.0) + data0.add('energy', 1, must = True) + np.random.seed(0) + data1 = DeepmdDataSystem(['system_0', 'system_1'], + 5, + 10, + 1.0) + data1.add('force', 3, atomic = True, must = True) + np.random.seed(0) + data2 = DeepmdDataSystem(['system_0', 'system_1'], + 5, + 10, + 1.0) + data2.add('force', 3, atomic = True, must = True) + + np.random.seed(0) + all_stat_0 = make_all_stat(data0, 10, merge_sys = False) + np.random.seed(0) + all_stat_1 = make_all_stat(data1, 10, merge_sys = True) + all_stat_2 = merge_sys_stat(all_stat_0) + np.random.seed(0) + all_stat_3 = _make_all_stat_ref(data2, 10) + + # print(all_stat_1) + # print(all_stat_2) + for dd in all_stat_0 : + if 'find_' in dd: continue + if 'natoms_vec' in dd: continue + if 'default_mesh' in dd: continue + # print(all_stat_2[dd]) + # print(all_stat_1[dd]) + d1 = np.array(all_stat_1[dd]) + d2 = np.array(all_stat_2[dd]) + d3 = np.array(all_stat_3[dd]) + # print(dd) + # print(d1.shape) + # print(d2.shape) + # self.assertEqual(all_stat_2[dd], all_stat_1[dd]) + self._comp_data(d1, d2) + self._comp_data(d1, d3) + diff --git a/source/train/DescrptLocFrame.py b/source/train/DescrptLocFrame.py index 302bdf7496..25748e2770 100644 --- a/source/train/DescrptLocFrame.py +++ b/source/train/DescrptLocFrame.py @@ -57,7 +57,7 @@ def get_dim_out (self) : def get_nlist (self) : return self.nlist, self.rij, self.sel_a, self.sel_r - def compute_dstats (self, + def compute_input_stats (self, data_coord, data_box, data_atype, diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index c13e553aa1..9b599a0eff 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -70,7 +70,7 @@ def get_dim_rot_mat_1 (self) : def get_nlist (self) : return self.nlist, self.rij, self.sel_a, self.sel_r - def compute_dstats (self, + def compute_input_stats (self, data_coord, data_box, data_atype, diff --git a/source/train/DescrptSeAR.py b/source/train/DescrptSeAR.py index 97a254df9a..699f34ecbe 100644 --- a/source/train/DescrptSeAR.py +++ b/source/train/DescrptSeAR.py @@ -51,14 +51,14 @@ def get_nlist_a (self) : def get_nlist_r (self) : return self.descrpt_r.nlist, self.descrpt_r.rij, self.descrpt_r.sel_a, self.descrpt_r.sel_r - def compute_dstats (self, + def compute_input_stats (self, data_coord, data_box, data_atype, natoms_vec, mesh) : - davg_a, dstd_a = self.descrpt_a.compute_dstats(data_coord, data_box, data_atype, natoms_vec, mesh) - davg_r, dstd_r = self.descrpt_r.compute_dstats(data_coord, data_box, data_atype, natoms_vec, mesh) + davg_a, dstd_a = self.descrpt_a.compute_input_stats(data_coord, data_box, data_atype, natoms_vec, mesh) + davg_r, dstd_r = self.descrpt_r.compute_input_stats(data_coord, data_box, data_atype, natoms_vec, mesh) self.davg = [davg_a, davg_r] self.dstd = [dstd_a, dstd_r] diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index 1f0bd614f6..2399eff54f 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -63,7 +63,7 @@ def get_dim_out (self) : def get_nlist (self) : return self.nlist, self.rij, self.sel_a, self.sel_r - def compute_dstats (self, + def compute_input_stats (self, data_coord, data_box, data_atype, diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 59ea7a5ed8..7039afb5a4 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -49,7 +49,7 @@ def get_numb_fparam(self) : def get_numb_aparam(self) : return self.numb_fparam - def compute_dstats(self, all_stat, protection): + def compute_input_stats(self, all_stat, protection): # stat fparam if self.numb_fparam > 0: cat_data = np.concatenate(all_stat['fparam'], axis = 0) diff --git a/source/train/Loss.py b/source/train/Loss.py index ad1d2211c7..264e8b7b9c 100644 --- a/source/train/Loss.py +++ b/source/train/Loss.py @@ -42,11 +42,11 @@ def __init__ (self, jdata, **kwarg) : self.has_ae = (self.start_pref_ae != 0 or self.limit_pref_ae != 0) self.has_pf = (self.start_pref_pf != 0 or self.limit_pref_pf != 0) # data required - add_data_requirement('energy', 1, atomic=False, must=False, high_prec=True) - add_data_requirement('force', 3, atomic=True, must=False, high_prec=False) - add_data_requirement('virial', 9, atomic=False, must=False, high_prec=False) - add_data_requirement('atom_ener', 1, atomic=True, must=False, high_prec=False) - add_data_requirement('atom_pref', 1, atomic=True, must=False, high_prec=False, repeat=3) + add_data_requirement('energy', 1, atomic=False, must=self.has_e, high_prec=True) + add_data_requirement('force', 3, atomic=True, must=self.has_f, high_prec=False) + add_data_requirement('virial', 9, atomic=False, must=self.has_v, high_prec=False) + add_data_requirement('atom_ener', 1, atomic=True, must=self.has_ae, high_prec=False) + add_data_requirement('atom_pref', 1, atomic=True, must=self.has_pf, high_prec=False, repeat=3) def build (self, learning_rate, diff --git a/source/train/Model.py b/source/train/Model.py index 8f54d80e59..3b69bf590d 100644 --- a/source/train/Model.py +++ b/source/train/Model.py @@ -22,6 +22,66 @@ assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) + +def _make_all_stat_ref(data, nbatches): + all_stat = defaultdict(list) + for ii in range(data.get_nsystems()) : + for jj in range(nbatches) : + stat_data = data.get_batch (sys_idx = ii) + for dd in stat_data: + if dd == "natoms_vec": + stat_data[dd] = stat_data[dd].astype(np.int32) + all_stat[dd].append(stat_data[dd]) + return all_stat + + +def make_all_stat(data, nbatches, merge_sys = True): + """ + pack data for statistics + Parameters + ---------- + data: + The data + merge_sys: bool (True) + Merge system data + Returns + ------- + all_stat: + A dictionary of list of list storing data for stat. + if merge_sys == False data can be accessed by + all_stat[key][sys_idx][batch_idx][frame_idx] + else merge_sys == True can be accessed by + all_stat[key][batch_idx][frame_idx] + """ + all_stat = defaultdict(list) + for ii in range(data.get_nsystems()) : + sys_stat = defaultdict(list) + for jj in range(nbatches) : + stat_data = data.get_batch (sys_idx = ii) + for dd in stat_data: + if dd == "natoms_vec": + stat_data[dd] = stat_data[dd].astype(np.int32) + sys_stat[dd].append(stat_data[dd]) + for dd in sys_stat: + if merge_sys: + for bb in sys_stat[dd]: + all_stat[dd].append(bb) + else: + all_stat[dd].append(sys_stat[dd]) + return all_stat + +def merge_sys_stat(all_stat): + first_key = list(all_stat.keys())[0] + nsys = len(all_stat[first_key]) + # print('nsys is ---------------', nsys) + ret = defaultdict(list) + for ii in range(nsys): + for dd in all_stat: + for bb in all_stat[dd][ii]: + ret[dd].append(bb) + return ret + + class Model() : model_type = 'ener' @@ -68,25 +128,18 @@ def get_type_map (self) : return self.type_map def data_stat(self, data): - all_stat = defaultdict(list) - for ii in range(data.get_nsystems()) : - for jj in range(self.data_stat_nbatch) : - stat_data = data.get_batch (sys_idx = ii) - for dd in stat_data: - if dd == "natoms_vec": - stat_data[dd] = stat_data[dd].astype(np.int32) - all_stat[dd].append(stat_data[dd]) - self._compute_dstats (all_stat, protection = self.data_stat_protect) + all_stat = make_all_stat(data, self.data_stat_nbatch, merge_sys = False) + m_all_stat = merge_sys_stat(all_stat) + self._compute_dstats (m_all_stat, protection = self.data_stat_protect) self.bias_atom_e = data.compute_energy_shift(self.rcond) - def _compute_dstats (self, all_stat, protection = 1e-2) : - self.descrpt.compute_dstats(all_stat['coord'], - all_stat['box'], - all_stat['type'], - all_stat['natoms_vec'], - all_stat['default_mesh']) - self.fitting.compute_dstats(all_stat, protection = protection) + self.descrpt.compute_input_stats(all_stat['coord'], + all_stat['box'], + all_stat['type'], + all_stat['natoms_vec'], + all_stat['default_mesh']) + self.fitting.compute_input_stats(all_stat, protection = protection) def build (self, @@ -264,11 +317,11 @@ def data_stat(self, data): self._compute_dstats (all_stat) def _compute_dstats (self, all_stat) : - self.descrpt.compute_dstats(all_stat['coord'], - all_stat['box'], - all_stat['type'], - all_stat['natoms_vec'], - all_stat['default_mesh']) + self.descrpt.compute_input_stats(all_stat['coord'], + all_stat['box'], + all_stat['type'], + all_stat['natoms_vec'], + all_stat['default_mesh']) def build (self, coord_, From afd400f526cc44f57f48479029038f56e179179c Mon Sep 17 00:00:00 2001 From: Han Wang Date: Wed, 6 Nov 2019 17:08:31 +0800 Subject: [PATCH 011/147] mv energy shift computation to output data stat of fitting classes --- source/tests/test_gen_stat_data.py | 64 +++++++++++++++++++------- source/tests/test_model_loc_frame.py | 4 +- source/tests/test_model_se_a.py | 4 +- source/tests/test_model_se_a_aparam.py | 4 +- source/tests/test_model_se_a_fparam.py | 4 +- source/tests/test_model_se_a_srtab.py | 4 +- source/tests/test_model_se_r.py | 4 +- source/train/Fitting.py | 34 +++++++++++++- source/train/Model.py | 14 +++--- 9 files changed, 98 insertions(+), 38 deletions(-) diff --git a/source/tests/test_gen_stat_data.py b/source/tests/test_gen_stat_data.py index d9f99b5818..852915bd12 100644 --- a/source/tests/test_gen_stat_data.py +++ b/source/tests/test_gen_stat_data.py @@ -4,6 +4,7 @@ import dpdata from deepmd.DataSystem import DeepmdDataSystem +from deepmd.Fitting import EnerFitting from deepmd.Model import make_all_stat, merge_sys_stat, _make_all_stat_ref def gen_sys(nframes, atom_types): @@ -32,7 +33,7 @@ def setUp(self): sys0.data = data0 sys1.data = data1 sys0.to_deepmd_npy('system_0', set_size = 10) - sys0.to_deepmd_npy('system_1', set_size = 10) + sys1.to_deepmd_npy('system_1', set_size = 10) def tearDown(self): shutil.rmtree('system_0') @@ -72,21 +73,50 @@ def test_merge_all_stat(self): np.random.seed(0) all_stat_3 = _make_all_stat_ref(data2, 10) - # print(all_stat_1) - # print(all_stat_2) - for dd in all_stat_0 : - if 'find_' in dd: continue - if 'natoms_vec' in dd: continue - if 'default_mesh' in dd: continue + #################################### + # only check if the energy is concatenated correctly + #################################### + dd = 'energy' + # if 'find_' in dd: continue + # if 'natoms_vec' in dd: continue + # if 'default_mesh' in dd: continue # print(all_stat_2[dd]) - # print(all_stat_1[dd]) - d1 = np.array(all_stat_1[dd]) - d2 = np.array(all_stat_2[dd]) - d3 = np.array(all_stat_3[dd]) - # print(dd) - # print(d1.shape) - # print(d2.shape) - # self.assertEqual(all_stat_2[dd], all_stat_1[dd]) - self._comp_data(d1, d2) - self._comp_data(d1, d3) + # print(dd, all_stat_1[dd]) + d1 = np.array(all_stat_1[dd]) + d2 = np.array(all_stat_2[dd]) + d3 = np.array(all_stat_3[dd]) + # print(dd) + # print(d1.shape) + # print(d2.shape) + # self.assertEqual(all_stat_2[dd], all_stat_1[dd]) + self._comp_data(d1, d2) + self._comp_data(d1, d3) + +class TestEnerShift(unittest.TestCase): + def setUp(self): + data0 = gen_sys(30, [0, 1, 0, 2, 1]) + data1 = gen_sys(30, [0, 1, 0, 0]) + sys0 = dpdata.LabeledSystem() + sys1 = dpdata.LabeledSystem() + sys0.data = data0 + sys1.data = data1 + sys0.to_deepmd_npy('system_0', set_size = 10) + sys1.to_deepmd_npy('system_1', set_size = 10) + + def tearDown(self): + shutil.rmtree('system_0') + shutil.rmtree('system_1') + + def test_ener_shift(self): + np.random.seed(0) + data = DeepmdDataSystem(['system_0', 'system_1'], + 5, + 10, + 1.0) + data.add('energy', 1, must = True) + ener_shift0 = data.compute_energy_shift(rcond = 1) + all_stat = make_all_stat(data, 4, merge_sys = False) + ener_shift1 = EnerFitting._compute_output_stats(all_stat, rcond = 1) + for ii in range(len(ener_shift0)): + self.assertAlmostEqual(ener_shift0[ii], ener_shift1[ii]) diff --git a/source/tests/test_model_loc_frame.py b/source/tests/test_model_loc_frame.py index 5981ee6497..b651862885 100644 --- a/source/tests/test_model_loc_frame.py +++ b/source/tests/test_model_loc_frame.py @@ -49,8 +49,8 @@ def test_model(self): 'natoms_vec' : [test_data['natoms_vec']], 'default_mesh' : [test_data['default_mesh']] } - model._compute_dstats(input_data) - model.bias_atom_e = data.compute_energy_shift() + model._compute_input_stat(input_data) + model.fitting.bias_atom_e = data.compute_energy_shift() t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') t_energy = tf.placeholder(global_ener_float_precision, [None], name='t_energy') diff --git a/source/tests/test_model_se_a.py b/source/tests/test_model_se_a.py index d5be148358..0d54f14c5f 100644 --- a/source/tests/test_model_se_a.py +++ b/source/tests/test_model_se_a.py @@ -49,8 +49,8 @@ def test_model(self): 'natoms_vec' : [test_data['natoms_vec']], 'default_mesh' : [test_data['default_mesh']] } - model._compute_dstats(input_data) - model.bias_atom_e = data.compute_energy_shift() + model._compute_input_stat(input_data) + model.descrpt.bias_atom_e = data.compute_energy_shift() t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') t_energy = tf.placeholder(global_ener_float_precision, [None], name='t_energy') diff --git a/source/tests/test_model_se_a_aparam.py b/source/tests/test_model_se_a_aparam.py index 293145e377..58b060225c 100644 --- a/source/tests/test_model_se_a_aparam.py +++ b/source/tests/test_model_se_a_aparam.py @@ -51,8 +51,8 @@ def test_model(self): 'default_mesh' : [test_data['default_mesh']], 'aparam': [test_data['aparam']], } - model._compute_dstats(input_data) - model.bias_atom_e = data.compute_energy_shift() + model._compute_input_stat(input_data) + model.descrpt.bias_atom_e = data.compute_energy_shift() t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') t_energy = tf.placeholder(global_ener_float_precision, [None], name='t_energy') diff --git a/source/tests/test_model_se_a_fparam.py b/source/tests/test_model_se_a_fparam.py index 4f85af0579..ec4a46c7d4 100644 --- a/source/tests/test_model_se_a_fparam.py +++ b/source/tests/test_model_se_a_fparam.py @@ -49,8 +49,8 @@ def test_model(self): 'default_mesh' : [test_data['default_mesh']], 'fparam': [test_data['fparam']], } - model._compute_dstats(input_data) - model.bias_atom_e = data.compute_energy_shift() + model._compute_input_stat(input_data) + model.descrpt.bias_atom_e = data.compute_energy_shift() t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') t_energy = tf.placeholder(global_ener_float_precision, [None], name='t_energy') diff --git a/source/tests/test_model_se_a_srtab.py b/source/tests/test_model_se_a_srtab.py index 82d1492067..c2950fe788 100644 --- a/source/tests/test_model_se_a_srtab.py +++ b/source/tests/test_model_se_a_srtab.py @@ -58,8 +58,8 @@ def test_model(self): 'natoms_vec' : [test_data['natoms_vec']], 'default_mesh' : [test_data['default_mesh']] } - model._compute_dstats(input_data) - model.bias_atom_e = data.compute_energy_shift() + model._compute_input_stat(input_data) + model.descrpt.bias_atom_e = data.compute_energy_shift() t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') t_energy = tf.placeholder(global_ener_float_precision, [None], name='t_energy') diff --git a/source/tests/test_model_se_r.py b/source/tests/test_model_se_r.py index 965e89a1bd..d3607a9164 100644 --- a/source/tests/test_model_se_r.py +++ b/source/tests/test_model_se_r.py @@ -48,8 +48,8 @@ def test_model(self): 'natoms_vec' : [test_data['natoms_vec']], 'default_mesh' : [test_data['default_mesh']] } - model._compute_dstats(input_data) - model.bias_atom_e = data.compute_energy_shift() + model._compute_input_stat(input_data) + model.descrpt.bias_atom_e = data.compute_energy_shift() t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') t_energy = tf.placeholder(global_ener_float_precision, [None], name='t_energy') diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 7039afb5a4..62fcf2a7dc 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -23,14 +23,17 @@ def __init__ (self, jdata, descrpt): .add('numb_aparam', int, default = 0)\ .add('neuron', list, default = [120,120,120], alias = 'n_neuron')\ .add('resnet_dt', bool, default = True)\ + .add('rcond', float, default = 1e-3) \ .add('seed', int) class_data = args.parse(jdata) self.numb_fparam = class_data['numb_fparam'] self.numb_aparam = class_data['numb_aparam'] self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] + self.rcond = class_data['rcond'] self.seed = class_data['seed'] self.useBN = False + self.bias_atom_e = None # data requirement if self.numb_fparam > 0 : add_data_requirement('fparam', self.numb_fparam, atomic=False, must=True, high_prec=False) @@ -49,6 +52,32 @@ def get_numb_fparam(self) : def get_numb_aparam(self) : return self.numb_fparam + def compute_output_stats(self, all_stat): + self.bias_atom_e = self._compute_output_stats(all_stat, rcond = self.rcond) + + @classmethod + def _compute_output_stats(self, all_stat, rcond = 1e-3): + data = all_stat['energy'] + # data[sys_idx][batch_idx][frame_idx] + sys_ener = np.array([]) + for ss in range(len(data)): + sys_data = [] + for ii in range(len(data[ss])): + for jj in range(len(data[ss][ii])): + sys_data.append(data[ss][ii][jj]) + sys_data = np.concatenate(sys_data) + sys_ener = np.append(sys_ener, np.average(sys_data)) + data = all_stat['natoms_vec'] + sys_tynatom = np.array([]) + nsys = len(data) + for ss in range(len(data)): + sys_tynatom = np.append(sys_tynatom, data[ss][0].astype(np.float64)) + sys_tynatom = np.reshape(sys_tynatom, [nsys,-1]) + sys_tynatom = sys_tynatom[:,2:] + energy_shift,resd,rank,s_value \ + = np.linalg.lstsq(sys_tynatom, sys_ener, rcond = rcond) + return energy_shift + def compute_input_stats(self, all_stat, protection): # stat fparam if self.numb_fparam > 0: @@ -78,7 +107,8 @@ def compute_input_stats(self, all_stat, protection): for ii in range(self.aparam_std.size): if self.aparam_std[ii] < protection: self.aparam_std[ii] = protection - self.aparam_inv_std = 1./self.aparam_std + self.aparam_inv_std = 1./self.aparam_std + def _compute_std (self, sumv2, sumv, sumn) : return np.sqrt(sumv2/sumn - np.multiply(sumv/sumn, sumv/sumn)) @@ -88,9 +118,9 @@ def build (self, inputs, input_dict, natoms, - bias_atom_e = None, reuse = None, suffix = '') : + bias_atom_e = self.bias_atom_e if self.numb_fparam > 0 and ( self.fparam_avg is None or self.fparam_inv_std is None ): raise RuntimeError('No data stat result. one should do data statisitic, before build') if self.numb_aparam > 0 and ( self.aparam_avg is None or self.aparam_inv_std is None ): diff --git a/source/train/Model.py b/source/train/Model.py index 3b69bf590d..d0ef0bf2fc 100644 --- a/source/train/Model.py +++ b/source/train/Model.py @@ -73,7 +73,6 @@ def make_all_stat(data, nbatches, merge_sys = True): def merge_sys_stat(all_stat): first_key = list(all_stat.keys())[0] nsys = len(all_stat[first_key]) - # print('nsys is ---------------', nsys) ret = defaultdict(list) for ii in range(nsys): for dd in all_stat: @@ -95,14 +94,12 @@ def __init__ (self, jdata, descrpt, fitting): args = ClassArg()\ .add('type_map', list, default = []) \ - .add('rcond', float, default = 1e-3) \ .add('data_stat_nbatch', int, default = 10) \ .add('data_stat_protect',float, default = 1e-2) \ .add('use_srtab', str) class_data = args.parse(jdata) self.type_map = class_data['type_map'] self.srtab_name = class_data['use_srtab'] - self.rcond = class_data['rcond'] self.data_stat_nbatch = class_data['data_stat_nbatch'] self.data_stat_protect = class_data['data_stat_protect'] if self.srtab_name is not None : @@ -130,10 +127,11 @@ def get_type_map (self) : def data_stat(self, data): all_stat = make_all_stat(data, self.data_stat_nbatch, merge_sys = False) m_all_stat = merge_sys_stat(all_stat) - self._compute_dstats (m_all_stat, protection = self.data_stat_protect) - self.bias_atom_e = data.compute_energy_shift(self.rcond) + self._compute_input_stat(m_all_stat, protection = self.data_stat_protect) + self._compute_output_stat(all_stat) + # self.bias_atom_e = data.compute_energy_shift(self.rcond) - def _compute_dstats (self, all_stat, protection = 1e-2) : + def _compute_input_stat (self, all_stat, protection = 1e-2) : self.descrpt.compute_input_stats(all_stat['coord'], all_stat['box'], all_stat['type'], @@ -141,6 +139,9 @@ def _compute_dstats (self, all_stat, protection = 1e-2) : all_stat['default_mesh']) self.fitting.compute_input_stats(all_stat, protection = protection) + def _compute_output_stat (self, all_stat) : + self.fitting.compute_output_stats(all_stat) + def build (self, coord_, @@ -194,7 +195,6 @@ def build (self, atom_ener = self.fitting.build (dout, input_dict, natoms, - bias_atom_e = self.bias_atom_e, reuse = reuse, suffix = suffix) From fd9cff20ec5228a03476ce272571b52eff764f35 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 7 Nov 2019 17:04:35 +0800 Subject: [PATCH 012/147] modify data only when the data is asked. save computational cost --- source/train/Data.py | 28 ++++++++++++++++++++-------- source/train/DataModifier.py | 5 ++--- source/train/DataSystem.py | 23 ++++++++++++++++------- source/train/DeepEval.py | 16 ++-------------- source/train/DescrptSeAR.py | 8 ++++---- source/train/Trainer.py | 2 +- source/train/common.py | 14 ++++++++++++++ 7 files changed, 59 insertions(+), 37 deletions(-) diff --git a/source/train/Data.py b/source/train/Data.py index 7445f5ec1c..07057d9fec 100644 --- a/source/train/Data.py +++ b/source/train/Data.py @@ -125,12 +125,24 @@ def get_batch(self, batch_size) : iterator_1 = set_size idx = np.arange (self.iterator, iterator_1) self.iterator += batch_size - return self._get_subdata(self.batch_set, idx) + ret = self._get_subdata(self.batch_set, idx) + if self.modifier is not None: + self.modifier.modify(ret) + return ret - def get_test (self) : + def get_test (self, ntests = -1) : if not hasattr(self, 'test_set') : self._load_test_set(self.test_dir, self.shuffle_test) - return self._get_subdata(self.test_set) + if ntests == -1: + idx = None + else : + ntests_ = ntests if ntests < self.test_set['type'].shape[0] else self.test_set['type'].shape[0] + # print('ntest', self.test_set['type'].shape[0], ntests, ntests_) + idx = np.arange(ntests_) + ret = self._get_subdata(self.test_set, idx = idx) + if self.modifier is not None: + self.modifier.modify(ret) + return ret def get_type_map(self) : return self.type_map @@ -142,7 +154,7 @@ def get_numb_set (self) : return len (self.train_dirs) def get_numb_batch (self, batch_size, set_idx) : - data = self._load_set(self.train_dirs[set_idx], modify = False) + data = self._load_set(self.train_dirs[set_idx]) return data["coord"].shape[0] // batch_size def get_sys_numb_batch (self, batch_size) : @@ -214,6 +226,9 @@ def _load_batch_set (self, set_name) : self.batch_set = self._load_set(set_name) self.batch_set, sf_idx = self._shuffle_data(self.batch_set) + self.reset_get_batch() + + def reset_get_batch(self): self.iterator = 0 def _load_test_set (self, @@ -240,7 +255,7 @@ def _shuffle_data (self, ret[kk] = data[kk] return ret, idx - def _load_set(self, set_name, modify = True) : + def _load_set(self, set_name) : ret = {} # get nframes path = os.path.join(set_name, "coord.npy") @@ -273,9 +288,6 @@ def _load_set(self, set_name, modify = True) : tmp_in = data[k_in].astype(global_ener_float_precision) data[kk] = np.sum(np.reshape(tmp_in, [nframes, self.natoms, ndof]), axis = 1) - if modify and self.modifier is not None: - self.modifier.modify(data) - return data diff --git a/source/train/DataModifier.py b/source/train/DataModifier.py index 044b1d8182..029e64219f 100644 --- a/source/train/DataModifier.py +++ b/source/train/DataModifier.py @@ -2,7 +2,7 @@ import numpy as np from deepmd import DeepDipole from deepmd.env import tf -from deepmd.common import select_idx_map +from deepmd.common import select_idx_map, make_default_mesh from deepmd.EwaldRecp import EwaldRecp from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision @@ -201,7 +201,6 @@ def eval_modify(self, coord, box, atype, eval_fv = True): corr_v = [] corr_av = [] for ii in range(0,nframes,batch_size): - print(ii, nframes) f, v, av = self.eval_fv(coord[ii:ii+batch_size], box[ii:ii+batch_size], atype[0], ext_f[ii:ii+batch_size]) corr_f.append(f) corr_v.append(v) @@ -240,7 +239,7 @@ def eval_fv(self, coords, cells, atom_types, ext_f) : # make natoms_vec and default_mesh natoms_vec = self.make_natoms_vec(atom_types) assert(natoms_vec[0] == natoms) - default_mesh = self.make_default_mesh(cells) + default_mesh = make_default_mesh(cells) # evaluate tensor = [] diff --git a/source/train/DataSystem.py b/source/train/DataSystem.py index b967074a64..997baf878c 100644 --- a/source/train/DataSystem.py +++ b/source/train/DataSystem.py @@ -88,14 +88,20 @@ def __init__ (self, self.print_summary(run_opt) - def _load_test(self): + def _load_test(self, ntests = -1): self.test_data = collections.defaultdict(list) - self.default_mesh = [] for ii in range(self.nsystems) : - test_system_data = self.data_systems[ii].get_test () + test_system_data = self.data_systems[ii].get_test(ntests = ntests) for nn in test_system_data: self.test_data[nn].append(test_system_data[nn]) - cell_size = np.max (self.rcut) + + def _make_default_mesh(self): + self.default_mesh = [] + cell_size = np.max (self.rcut) + for ii in range(self.nsystems) : + test_system_data = self.data_systems[ii].get_batch(self.batch_size[ii]) + self.data_systems[ii].reset_get_batch() + # test_system_data = self.data_systems[ii].get_test() avg_box = np.average (test_system_data["box"], axis = 0) avg_box = np.reshape (avg_box, [3,3]) ncell = (np.linalg.norm(avg_box, axis=1)/ cell_size).astype(np.int32) @@ -152,7 +158,7 @@ def get_batch (self, sys_weights = None, style = "prob_sys_size") : if not hasattr(self, 'default_mesh') : - self._load_test() + self._make_default_mesh() if sys_idx is not None : self.pick_idx = sys_idx else : @@ -172,9 +178,12 @@ def get_batch (self, return b_data def get_test (self, - sys_idx = None) : + sys_idx = None, + ntests = -1) : if not hasattr(self, 'default_mesh') : - self._load_test() + self._make_default_mesh() + if not hasattr(self, 'test_data') : + self._load_test(ntests = ntests) if sys_idx is not None : idx = sys_idx else : diff --git a/source/train/DeepEval.py b/source/train/DeepEval.py index 8e9e1d7113..e452dc860d 100644 --- a/source/train/DeepEval.py +++ b/source/train/DeepEval.py @@ -4,6 +4,7 @@ import numpy as np from deepmd.env import tf +from deepmd.common import make_default_mesh from tensorflow.python.framework import ops @@ -51,19 +52,6 @@ def load_graph(self, ) return graph - def make_default_mesh(self, test_box) : - cell_size = 3 - nframes = test_box.shape[0] - default_mesh = np.zeros([nframes, 6], dtype = np.int32) - for ff in range(nframes): - ncell = np.ones (3, dtype=np.int32) - for ii in range(3) : - ncell[ii] = int ( np.linalg.norm(test_box[ff][ii]) / cell_size ) - if (ncell[ii] < 2) : ncell[ii] = 2 - default_mesh[ff][3] = ncell[0] - default_mesh[ff][4] = ncell[1] - default_mesh[ff][5] = ncell[2] - return default_mesh def sort_input(self, coord, atom_type, sel_atoms = None) : if sel_atoms is not None: @@ -167,7 +155,7 @@ def eval(self, # make natoms_vec and default_mesh natoms_vec = self.make_natoms_vec(atom_types) assert(natoms_vec[0] == natoms) - default_mesh = self.make_default_mesh(cells) + default_mesh = make_default_mesh(cells) # evaluate tensor = [] diff --git a/source/train/DescrptSeAR.py b/source/train/DescrptSeAR.py index 699f34ecbe..b7005ff22c 100644 --- a/source/train/DescrptSeAR.py +++ b/source/train/DescrptSeAR.py @@ -57,10 +57,10 @@ def compute_input_stats (self, data_atype, natoms_vec, mesh) : - davg_a, dstd_a = self.descrpt_a.compute_input_stats(data_coord, data_box, data_atype, natoms_vec, mesh) - davg_r, dstd_r = self.descrpt_r.compute_input_stats(data_coord, data_box, data_atype, natoms_vec, mesh) - self.davg = [davg_a, davg_r] - self.dstd = [dstd_a, dstd_r] + self.descrpt_a.compute_input_stats(data_coord, data_box, data_atype, natoms_vec, mesh) + self.descrpt_r.compute_input_stats(data_coord, data_box, data_atype, natoms_vec, mesh) + self.davg = [self.descrpt_a.davg, self.descrpt_r.davg] + self.dstd = [self.descrpt_a.dstd, self.descrpt_r.dstd] def build (self, diff --git a/source/train/Trainer.py b/source/train/Trainer.py index 10472d828b..2cc73e673e 100644 --- a/source/train/Trainer.py +++ b/source/train/Trainer.py @@ -463,7 +463,7 @@ def test_on_the_fly (self, fp, data, feed_dict_batch) : - test_data = data.get_test () + test_data = data.get_test(ntests = self.numb_test) feed_dict_test = {} for kk in test_data.keys(): if kk == 'find_type' or kk == 'type' : diff --git a/source/train/common.py b/source/train/common.py index 7d8e530460..c322f0e9c4 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -27,6 +27,20 @@ def select_idx_map(atom_type, return idx_map +def make_default_mesh(test_box, cell_size = 3) : + nframes = test_box.shape[0] + default_mesh = np.zeros([nframes, 6], dtype = np.int32) + for ff in range(nframes): + ncell = np.ones (3, dtype=np.int32) + for ii in range(3) : + ncell[ii] = int ( np.linalg.norm(test_box[ff][ii]) / cell_size ) + if (ncell[ii] < 2) : ncell[ii] = 2 + default_mesh[ff][3] = ncell[0] + default_mesh[ff][4] = ncell[1] + default_mesh[ff][5] = ncell[2] + return default_mesh + + class ClassArg () : def __init__ (self) : self.arg_dict = {} From 4da6faee1ff14f9d905a07da657bf81e7624dd15 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 7 Nov 2019 20:34:49 +0800 Subject: [PATCH 013/147] modify batch data on load --- source/train/Data.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/train/Data.py b/source/train/Data.py index 07057d9fec..6c0672afc2 100644 --- a/source/train/Data.py +++ b/source/train/Data.py @@ -120,14 +120,14 @@ def get_batch(self, batch_size) : self._load_batch_set (self.train_dirs[self.set_count % self.get_numb_set()]) self.set_count += 1 set_size = self.batch_set["coord"].shape[0] + if self.modifier is not None: + self.modifier.modify(self.batch_set) iterator_1 = self.iterator + batch_size if iterator_1 >= set_size : iterator_1 = set_size idx = np.arange (self.iterator, iterator_1) self.iterator += batch_size ret = self._get_subdata(self.batch_set, idx) - if self.modifier is not None: - self.modifier.modify(ret) return ret def get_test (self, ntests = -1) : From 835140f866df1696e94247d8e05ba979f17a03f3 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 8 Nov 2019 13:50:08 +0800 Subject: [PATCH 014/147] infer global polar --- deepmd/__init__.py | 1 + source/scripts/freeze.py | 2 ++ source/train/DeepEval.py | 14 +++++++++----- source/train/DeepPolar.py | 11 +++++++++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/deepmd/__init__.py b/deepmd/__init__.py index b2711088e8..231145b989 100644 --- a/deepmd/__init__.py +++ b/deepmd/__init__.py @@ -3,6 +3,7 @@ from .DeepPot import DeepPot from .DeepDipole import DeepDipole from .DeepPolar import DeepPolar +from .DeepPolar import DeepGlobalPolar from .DeepWFC import DeepWFC set_mkl() diff --git a/source/scripts/freeze.py b/source/scripts/freeze.py index 06f1df86c1..4dd51492a4 100755 --- a/source/scripts/freeze.py +++ b/source/scripts/freeze.py @@ -44,6 +44,8 @@ def _make_node_names(model_type = None) : nodes = "o_dipole,o_rmat,o_rmat_deriv,o_nlist,o_rij,descrpt_attr/rcut,descrpt_attr/ntypes,descrpt_attr/sel,descrpt_attr/ndescrpt,model_attr/tmap,model_attr/sel_type,model_attr/model_type" elif model_type == 'polar': nodes = "o_polar,descrpt_attr/rcut,descrpt_attr/ntypes,model_attr/tmap,model_attr/sel_type,model_attr/model_type" + elif model_type == 'global_polar': + nodes = "o_global_polar,descrpt_attr/rcut,descrpt_attr/ntypes,model_attr/tmap,model_attr/sel_type,model_attr/model_type" else: raise RuntimeError('unknow model type ' + model_type) return nodes diff --git a/source/train/DeepEval.py b/source/train/DeepEval.py index e452dc860d..2c0f613c27 100644 --- a/source/train/DeepEval.py +++ b/source/train/DeepEval.py @@ -137,7 +137,8 @@ def get_sel_type(self): def eval(self, coords, cells, - atom_types) : + atom_types, + atomic = True) : # standarize the shape of inputs coords = np.array(coords) cells = np.array(cells) @@ -171,10 +172,13 @@ def eval(self, tensor.append(v_out[0]) # reverse map of the outputs - tensor = np.array(tensor) - tensor = self.reverse_map(np.reshape(tensor, [nframes,-1,self.variable_dof]), sel_imap) - - tensor = np.reshape(tensor, [nframes, len(sel_at), self.variable_dof]) + if atomic: + tensor = np.array(tensor) + tensor = self.reverse_map(np.reshape(tensor, [nframes,-1,self.variable_dof]), sel_imap) + tensor = np.reshape(tensor, [nframes, len(sel_at), self.variable_dof]) + else: + tensor = np.reshape(tensor, [nframes, self.variable_dof]) + return tensor diff --git a/source/train/DeepPolar.py b/source/train/DeepPolar.py index 0ec37876ca..3af499dd07 100644 --- a/source/train/DeepPolar.py +++ b/source/train/DeepPolar.py @@ -9,3 +9,14 @@ def __init__(self, model_file) : DeepTensor.__init__(self, model_file, 'polar', 9) + +class DeepGlobalPolar (DeepTensor) : + def __init__(self, + model_file) : + DeepTensor.__init__(self, model_file, 'global_polar', 9) + + def eval(self, + coords, + cells, + atom_types) : + return DeepTensor.eval(self, coords, cells, atom_types, atomic = False) From 1c9c74d3818fad0a61ac25d702796fcb0baf5fe7 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 8 Nov 2019 16:05:08 +0800 Subject: [PATCH 015/147] use average eig value as bias of polar fitting --- source/train/Fitting.py | 29 +++++++++++++++++++--- source/train/Model.py | 53 ++++++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 28 deletions(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 62fcf2a7dc..650aac8115 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -401,6 +401,21 @@ def get_sel_type(self): def get_out_size(self): return 9 + def compute_input_stats(self, all_stat, protection = 1e-2): + assert('polarizability' in all_stat.keys()) + data = all_stat['polarizability'] + all_tmp = [] + for ss in range(len(data)): + tmp = np.concatenate(data[ss], axis = 0) + print(tmp.shape) + tmp = np.reshape(tmp, [-1, 3, 3]) + tmp,_ = np.linalg.eig(tmp) + tmp = np.absolute(tmp) + tmp = np.sort(tmp, axis = 1) + all_tmp.append(tmp) + all_tmp = np.concatenate(all_tmp, axis = 1) + self.avgeig = np.average(all_tmp, axis = 0) + def build (self, input_d, rot_mat, @@ -433,15 +448,23 @@ def build (self, else : layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) if self.fit_diag : + bavg = np.zeros(self.dim_rot_mat_1) + bavg[0] = self.avgeig[0] + bavg[1] = self.avgeig[1] + bavg[2] = self.avgeig[2] # (nframes x natoms) x naxis - final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, bavg = bavg) # (nframes x natoms) x naxis final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], self.dim_rot_mat_1]) # (nframes x natoms) x naxis x naxis final_layer = tf.matrix_diag(final_layer) - else : + else : + bavg = np.zeros(self.dim_rot_mat_1*self.dim_rot_mat_1) + bavg[0*self.dim_rot_mat_1+0] = self.avgeig[0] + bavg[1*self.dim_rot_mat_1+1] = self.avgeig[1] + bavg[2*self.dim_rot_mat_1+2] = self.avgeig[2] # (nframes x natoms) x (naxis x naxis) - final_layer = one_layer(layer, self.dim_rot_mat_1*self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + final_layer = one_layer(layer, self.dim_rot_mat_1*self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, bavg = bavg) # (nframes x natoms) x naxis x naxis final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], self.dim_rot_mat_1, self.dim_rot_mat_1]) # (nframes x natoms) x naxis x naxis diff --git a/source/train/Model.py b/source/train/Model.py index d0ef0bf2fc..d00d1bfaa4 100644 --- a/source/train/Model.py +++ b/source/train/Model.py @@ -126,18 +126,18 @@ def get_type_map (self) : def data_stat(self, data): all_stat = make_all_stat(data, self.data_stat_nbatch, merge_sys = False) - m_all_stat = merge_sys_stat(all_stat) - self._compute_input_stat(m_all_stat, protection = self.data_stat_protect) + self._compute_input_stat(all_stat, protection = self.data_stat_protect) self._compute_output_stat(all_stat) # self.bias_atom_e = data.compute_energy_shift(self.rcond) def _compute_input_stat (self, all_stat, protection = 1e-2) : - self.descrpt.compute_input_stats(all_stat['coord'], - all_stat['box'], - all_stat['type'], - all_stat['natoms_vec'], - all_stat['default_mesh']) - self.fitting.compute_input_stats(all_stat, protection = protection) + m_all_stat = merge_sys_stat(all_stat) + self.descrpt.compute_input_stats(m_all_stat['coord'], + m_all_stat['box'], + m_all_stat['type'], + m_all_stat['natoms_vec'], + m_all_stat['default_mesh']) + self.fitting.compute_input_stats(m_all_stat, protection = protection) def _compute_output_stat (self, all_stat) : self.fitting.compute_output_stats(all_stat) @@ -285,10 +285,12 @@ def __init__ (self, jdata, descrpt, fitting, var_name): args = ClassArg()\ .add('type_map', list, default = []) \ - .add('data_stat_nbatch', int, default = 10) + .add('data_stat_nbatch', int, default = 10) \ + .add('data_stat_protect',float, default = 1e-2) class_data = args.parse(jdata) self.type_map = class_data['type_map'] self.data_stat_nbatch = class_data['data_stat_nbatch'] + self.data_stat_protect = class_data['data_stat_protect'] def get_rcut (self) : return self.rcut @@ -306,22 +308,23 @@ def get_out_size (self) : return self.fitting.get_out_size() def data_stat(self, data): - all_stat = defaultdict(list) - for ii in range(data.get_nsystems()) : - for jj in range(self.data_stat_nbatch) : - stat_data = data.get_batch (sys_idx = ii) - for dd in stat_data: - if dd == "natoms_vec": - stat_data[dd] = stat_data[dd].astype(np.int32) - all_stat[dd].append(stat_data[dd]) - self._compute_dstats (all_stat) - - def _compute_dstats (self, all_stat) : - self.descrpt.compute_input_stats(all_stat['coord'], - all_stat['box'], - all_stat['type'], - all_stat['natoms_vec'], - all_stat['default_mesh']) + all_stat = make_all_stat(data, self.data_stat_nbatch, merge_sys = False) + self._compute_input_stat (all_stat, protection = self.data_stat_protect) + self._compute_output_stat(all_stat) + + def _compute_input_stat(self, all_stat, protection = 1e-2) : + m_all_stat = merge_sys_stat(all_stat) + self.descrpt.compute_input_stats(m_all_stat['coord'], + m_all_stat['box'], + m_all_stat['type'], + m_all_stat['natoms_vec'], + m_all_stat['default_mesh']) + if hasattr(self.fitting, 'compute_input_stats'): + self.fitting.compute_input_stats(all_stat, protection = protection) + + def _compute_output_stat (self, all_stat) : + if hasattr(self.fitting, 'compute_output_stats'): + self.fitting.compute_output_stats(all_stat) def build (self, coord_, From 3668f1913c1ab6803b30e899ac8348983df97ad9 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 8 Nov 2019 18:08:06 +0800 Subject: [PATCH 016/147] fix bug. return to old convention of pass merged data to input stat, pass unmerged data to output stat --- source/tests/test_polar_se_a.py | 2 +- source/tests/test_wfc.py | 2 +- source/train/Fitting.py | 5 ++++- source/train/Model.py | 30 +++++++++++++++--------------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/source/tests/test_polar_se_a.py b/source/tests/test_polar_se_a.py index 0506c84ff2..275b4fa707 100644 --- a/source/tests/test_polar_se_a.py +++ b/source/tests/test_polar_se_a.py @@ -49,7 +49,7 @@ def test_model(self): 'default_mesh' : [test_data['default_mesh']], 'fparam': [test_data['fparam']], } - model._compute_dstats(input_data) + model._compute_input_stat(input_data) t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') t_energy = tf.placeholder(global_ener_float_precision, [None], name='t_energy') diff --git a/source/tests/test_wfc.py b/source/tests/test_wfc.py index fc0d850b01..d4b408cd60 100644 --- a/source/tests/test_wfc.py +++ b/source/tests/test_wfc.py @@ -48,7 +48,7 @@ def test_model(self): 'default_mesh' : [test_data['default_mesh']], 'fparam': [test_data['fparam']], } - model._compute_dstats(input_data) + model._compute_input_stat(input_data) t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') t_energy = tf.placeholder(global_ener_float_precision, [None], name='t_energy') diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 650aac8115..506f8188b9 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -402,7 +402,10 @@ def get_out_size(self): return 9 def compute_input_stats(self, all_stat, protection = 1e-2): - assert('polarizability' in all_stat.keys()) + if not ('polarizability' in all_stat.keys()): + self.avgeig = np.zeros([9]) + warnings.warn('no polarizability data, cannot do data stat. use zeros as guess') + return data = all_stat['polarizability'] all_tmp = [] for ss in range(len(data)): diff --git a/source/train/Model.py b/source/train/Model.py index d00d1bfaa4..c568dbe9ec 100644 --- a/source/train/Model.py +++ b/source/train/Model.py @@ -126,18 +126,18 @@ def get_type_map (self) : def data_stat(self, data): all_stat = make_all_stat(data, self.data_stat_nbatch, merge_sys = False) - self._compute_input_stat(all_stat, protection = self.data_stat_protect) + m_all_stat = merge_sys_stat(all_stat) + self._compute_input_stat(m_all_stat, protection = self.data_stat_protect) self._compute_output_stat(all_stat) # self.bias_atom_e = data.compute_energy_shift(self.rcond) def _compute_input_stat (self, all_stat, protection = 1e-2) : - m_all_stat = merge_sys_stat(all_stat) - self.descrpt.compute_input_stats(m_all_stat['coord'], - m_all_stat['box'], - m_all_stat['type'], - m_all_stat['natoms_vec'], - m_all_stat['default_mesh']) - self.fitting.compute_input_stats(m_all_stat, protection = protection) + self.descrpt.compute_input_stats(all_stat['coord'], + all_stat['box'], + all_stat['type'], + all_stat['natoms_vec'], + all_stat['default_mesh']) + self.fitting.compute_input_stats(all_stat, protection = protection) def _compute_output_stat (self, all_stat) : self.fitting.compute_output_stats(all_stat) @@ -309,16 +309,16 @@ def get_out_size (self) : def data_stat(self, data): all_stat = make_all_stat(data, self.data_stat_nbatch, merge_sys = False) - self._compute_input_stat (all_stat, protection = self.data_stat_protect) + m_all_stat = merge_sys_stat(all_stat) + self._compute_input_stat (m_all_stat, protection = self.data_stat_protect) self._compute_output_stat(all_stat) def _compute_input_stat(self, all_stat, protection = 1e-2) : - m_all_stat = merge_sys_stat(all_stat) - self.descrpt.compute_input_stats(m_all_stat['coord'], - m_all_stat['box'], - m_all_stat['type'], - m_all_stat['natoms_vec'], - m_all_stat['default_mesh']) + self.descrpt.compute_input_stats(all_stat['coord'], + all_stat['box'], + all_stat['type'], + all_stat['natoms_vec'], + all_stat['default_mesh']) if hasattr(self.fitting, 'compute_input_stats'): self.fitting.compute_input_stats(all_stat, protection = protection) From 122007be2c2fe2e0d6446441d912e6acf09e7796 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 8 Nov 2019 19:01:49 +0800 Subject: [PATCH 017/147] add missing test file --- source/tests/data_modifier/dipole.json | 60 ++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 source/tests/data_modifier/dipole.json diff --git a/source/tests/data_modifier/dipole.json b/source/tests/data_modifier/dipole.json new file mode 100644 index 0000000000..283ebe161b --- /dev/null +++ b/source/tests/data_modifier/dipole.json @@ -0,0 +1,60 @@ +{ + "with_distrib": false, + "_comment": " model parameters", + "model":{ + "type_map": ["O", "H"], + "descriptor" :{ + "type": "se_a", + "sel": [46, 92], + "rcut_smth": 3.80, + "rcut": 4.00, + "neuron": [25, 50, 100], + "resnet_dt": false, + "axis_neuron": 6, + "seed": 1, + "_comment": " that's all" + }, + "fitting_net": { + "type": "dipole", + "dipole_type": [0], + "neuron": [100, 100, 100], + "resnet_dt": true, + "seed": 1, + "_comment": " that's all" + }, + "_comment": " that's all" + }, + + "learning_rate" :{ + "type": "exp", + "start_lr": 0.01, + "decay_steps": 5000, + "decay_rate": 0.95, + "_comment": "that's all" + }, + + "_comment": " traing controls", + "training": { + "systems": ["data_modifier/sys_10"], + "set_prefix": "set", + "stop_batch": 1000000, + "batch_size": 4, + + "seed": 1, + + "_comment": " display and restart", + "_comment": " frequencies counted in batch", + "disp_file": "lcurve.out", + "disp_freq": 100, + "numb_test": 5, + "save_freq": 500, + "save_ckpt": "model.ckpt", + "load_ckpt": "model.ckpt", + "disp_training":true, + "time_training":true, + "_comment": "that's all" + }, + + "_comment": "that's all" +} + From 83509c4813034cc121dfdd7fa61b19c2446c395b Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 8 Nov 2019 19:26:49 +0800 Subject: [PATCH 018/147] add missing test data --- .../data_modifier/sys_10/set.000/box.npy | Bin 0 -> 488 bytes .../data_modifier/sys_10/set.000/coord.npy | Bin 0 -> 5888 bytes .../data_modifier/sys_10/set.000/dipole.npy | Bin 0 -> 2048 bytes .../data_modifier/sys_10/set.000/energy.npy | Bin 0 -> 168 bytes .../data_modifier/sys_10/set.000/force.npy | Bin 0 -> 5888 bytes source/tests/data_modifier/sys_10/type.raw | 48 ++++++++++++++++++ .../tests/data_modifier/sys_10/type_map.raw | 2 + 7 files changed, 50 insertions(+) create mode 100644 source/tests/data_modifier/sys_10/set.000/box.npy create mode 100644 source/tests/data_modifier/sys_10/set.000/coord.npy create mode 100644 source/tests/data_modifier/sys_10/set.000/dipole.npy create mode 100644 source/tests/data_modifier/sys_10/set.000/energy.npy create mode 100644 source/tests/data_modifier/sys_10/set.000/force.npy create mode 100644 source/tests/data_modifier/sys_10/type.raw create mode 100644 source/tests/data_modifier/sys_10/type_map.raw diff --git a/source/tests/data_modifier/sys_10/set.000/box.npy b/source/tests/data_modifier/sys_10/set.000/box.npy new file mode 100644 index 0000000000000000000000000000000000000000..4935ebe88cf4f03b30b6310fad4ca9388d1615d1 GIT binary patch literal 488 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+l>qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I$-2099snmP)#3giMVM%C>O3`pRw3M&6SkRPaxD&~vEw*&I44N=vUqwzC= z{MqKHYNn&{JAwRjwy0`Oq49SE`35eiYIM-}vOxYVFH|+x(fB8T{KtW)YVM=)F97*r Xk*I2d(D=?kzC|Lc8WS|WDv%EV4H!>N literal 0 HcmV?d00001 diff --git a/source/tests/data_modifier/sys_10/set.000/coord.npy b/source/tests/data_modifier/sys_10/set.000/coord.npy new file mode 100644 index 0000000000000000000000000000000000000000..7bd26fdc0523cd22861e958f190818359f63515d GIT binary patch literal 5888 zcmbW5_g53?`-Tw|q=R&@&=e6wl+Y8N+b$>;RD{qK5ESW%9m|S|K|}?m1OiEbwSj^G zg#>jK*Hy%hZFd#>x@$!gL-9MGf8jg7%$fJhoH=LC_1^dO%%O$L0~d!5Q(3RF*&#MA zV^z9?kF^6kp5@?d?GT@mo|zt#9F>wD8~4BUIWb8Yam;!~LQHBLb3JjYtF!e~7R%Au zdaL#S@6cL$y^F1Q+w1#mMg=>o%Nw)9_bXg+TM_n{B_H;;CpN{Va3%$Kz<(wiqonGb z@9+PWmpMM;EIa6qs#-7n8)eXD@x}+Dbmo3h)gaOl~DJOFp<#0sOYgs5h*cPAE^1jU699jB}B*p`BWH z@Udr6Bi(w*gJ6aL6UOHuK7kLD#{vivm(aSS@pR20g8EuA!ESb>EU63W)frIis7UOr zv8S!k5n$h6fg=I#)azkEoBp0mFIB=Y?9FP}eOy7@z$83Wn?n22gD^|ZMZwr~oVt;Q zw#zBF&@+`%4jW@2RtG|d7|8xHz+OE=I8A3$ldJ;A%s&yYB@s8uD-hxLDvwW)%ioJW2GR7|G2-%nOUa{C#4Sa;lK%B!utUI4Ya{gN~`0z@$%; z>S8T%&9)Tw6VoufZ#d=^m_v191g`8e#Fw?zm{y@rj(}p6iB_~RM}jM3L|C;f z7O~GnDCMakJ0uCq_f(+LqmOou9inGDf@oBi6zM}+FiN$jrv1GXJ5h)av;67K@fy_Y zOTgVZlPqScB3#~2DNUKku_?idDO%91U4w@oG;!pD2>I(nVHR4A{@@y1njea18$YlU zuRZcjwUe=TU-ZW7(|pB9`|FC=2YXsoWS&@wjT|GP2d2fd(Y8pH6YBRsF1Y%db1Kvw zQ!>0@-eb^KXXK06&XMxF={_jF!NPbiFZeJVDF;}XqjjGCc~nQo54KYD01uxxG|<2| z31Rgqs#X;sYk4c_sqwM1M1U)&WHesAnM%}8QpYqtCXdR+?A&(h*~CY8eIw0e_;GX- zplVbeL@9izz7b&Dfkjlti6u?1NV;8>i8^g(s*ZOdt=IZ=TrCp2e%euTPz1g&4nae~ zG}<3*POFbiB3?fii+U6AMn9Acqmu9?b$t};RC zVI3Hy#h_@qA-Xph;IGvj%1NkzN9jizR3u{Ng$jiBC}~eCmsa%jknnUFKFfn~#@zyu z@+uhAyVKE2#n`k(h%1=b5(*B(IP10V$o9}!uc{aC?6zY z+>8oj`1a95t09uVSxS{1QtWrp#_ZenbU^zXbzd&S(gc5M{Hq2wonq*21o057_6j@vN+$?T~p%e%tRo=gByCOyqcB>r}%w8Tn%8 zzm2W^QXe#5W?|9{FXR=m@WS35+mE)q4$x`lS0k0xOg4C}3d(qMn9e?EWbfyv&U90v%}N zH!cRptU>x#E^+oG;n=Y$v`!-k$$xTD@iZO(y-UST>r{+=?nHGbO!44}4qjKqV5r;> zZ=dMn_f$WcH=zQ9@gFJwVj_f3E3mespQay-q)EyzRMb$0!nrF@^szlh$G6P&pj4`Y6(I zhyoWbr@s|aY+a{~c#ZM2ukag*R+Yi4+@A(U)FP}zjLix*)l{pZ>RcaP%g@AyktI;C zABp8fiP&VTg~o%Gc&f_9Z+TJ(o2y}v6^he;>vGP268TCBp0n>2cq6H7qoTV)u24LS zK6hxjCu~}FbMCr$!brk~h58rv;(e#(7Xo`YvR5qZQul(+Xv4NgYkaYIs$J{*n?8ta zVu7{L3!lSS_%+ZS7iY9l`Hwo<<|L=nW_*0}XryJkC3LZ~p4{C9c)Y8Xl#h6Lo+Chy zWfL9aHj&iwB;8%c$1nQ1=qPNb`Zzu~nP=#iCp<*!2+;pgfQ$`%3@8P#c3(iNMUm9G zG@71F$i&+%Qz`!bWV(1vkG$VU;LHzOvI=21+8GMJC}$GRFeTA5J97QXMJRVIqMgDi z=TZ_B@28O1I0$D=!*Dww1NXC2agUpdSLzc%!R9&c_je*8bLnQj><5v%&im&B( z&ihEeUP(lrl40q$0SYx*N$cqg^|h6u;nfN}ooIoQRbm*fo<_ZO#bD_PaZ)!DBbfYY zno$Y4s}Qd0D=FSaNq6oWL!(fIj5nI&wRb6Ab*ADHUk&p&n1PzZLtNirYfm)F`JC^` zp12`r!|mJ~HfN7mE<4-D={nAI(=AW*oi=EDQ0R-4!&W{~Uwx1(VWBI`3y6ZNiDKMl*7tBDQF2g>-j5>KxCkM65KUL2 zlw@_?7(vZSzm~IRI5oW#F4t0VSzQgY;>=;D5{(x+hPYKP!Q-jS-l&zLW55KhrK5=> zm10G|2zis@5PG!&!8_D&=J#Zj=al0>+7A+}93qcNA=GtHip54cnAvYn7B|1s@P<+h zjSC=KpIRIb5#vOV8_j?kO1FKZlW#Nd{jXv~TvW&Jw-XSUtc4{}RT%b>i+>(6zQwA> zW~R&Zb8R@;BNq5h8Kcgb7wwJmj}eOaJI56z(x<+`OmAJCvyW5#t0(5(Wn)^wpX`tB zN96Yd20540Sx7JQ#KT_wwiOCr*lMQxZe%>DW*-YT)_5W3vm46G8OM%QP|Nsw>boGP z9(O)szco_VObJEC*OMJrfFnCvDXN)=HLC>3+|xwDi!xfnhXIuB(}_TtqY0k&=CBT6F=)a6ev4}?%@*-GkWawGq^C!KPbOlInOWW+ebnXR_u zC62%ZoiIFjIG$nyjLB%u7-H*%q5R)_np16oOrY}=ksOC;NuD$p~$xjl|!}#lMvU1@kH)xHk@*AvAY)($nULH@w@87!lwjJ zTzae5X7th*%_si!mAUw$c0CKto4lZQ$qnw8+#&xUr{#Y2q&HGQQFHj15`2c4fh5#7 zr=D`-1t?E$rJ29-;Iv$TY(*0}@05|9!ATmvhYzyMg)8GfEN?yzFzdFz@lbz$FZ_QO zpoHP)rB)tRx%<=hisdxo=_)d9Nr(A+AG&(onOeT-QoySST;Fa>L(F;d*D&~=u%-P6 zji_?5C5ha^;NqMD(H}8%^uju5?{%fWyp|$yRXBdn&BR~oDVV08hN)sps@i4=vq(K$ z3W|ZLml19()5UMrMC)Ib!)f#va(6Mx_nI*=#GSa;ionDp741j}A@+PWr3ip3j6%3lG{4Y6#~OReX8)i&<4e&Y4IsmSTIeqnqw|LYZ5&d==bv9G|-*{jPudQ8|S9XR7mqn z6!U{4*p3+lT`soq+v!h7KB_uolzoLkOL&eiGIX(Y3B{YWI;sV}&mE z57|+Rs**Inl)(FC0Qt=IMc^^@W^#=6}wx z;T(h*G_faS9gqv$RQ>X9x?#VrC$7HGZqs&Rqcp^y-4pGL6AM|`DD*;iwi`4wn7Los zO8Kev@8Lj;H1a(OGxa*n= zn_t>VZpF-E+D$Z2$3xHdy)bANAdc~$4-7vWmiv?IlErjQ7EiaiX>cfOWbrHJLj%;r!>Gt&!sMyaZ z1Fu@lNoCkLX+`Nx!*NpkE4|80gJ*s*@)xLLU{V5FRJ9R#T8zd=5wNmk^5?Y_eoTK= zUiRU{TX4@=RoHTJ9KCV+xRYXBY_8&ziI{CZ;10_}MVy`>FFe!ZV2rYsozz((FR@qk zGcI>y=4}sb`lQ)*E`W{OwJGfG&Aup{!NP@;UI+?z!+m=X$hNl9J6=6SUr|uf7CtVf z%ZRg5LOj=cVr4P&_h1VNcktjmMS!#w&D5;veq)k5;~PavHGsWAU{7I{8%B8`_!{tQN-qRx(Z`lht99Od3wH#M{BH^2!g+T5)JldUx#-n-^ zVm%szYWkR^9*uvqjIp&`8_m9K5*Jp$bHjJ~Z`K;<{;WW%xhl@zTT8$C^wRy!)yj~#B?^Ui#dxM6!eDOE4pGKJB)xMPwes*h93GZONGncV$Ad&hUeA^aJSY*@E0-OU5o_JL;@?7YK%S_ivI(zZ=R?C literal 0 HcmV?d00001 diff --git a/source/tests/data_modifier/sys_10/set.000/dipole.npy b/source/tests/data_modifier/sys_10/set.000/dipole.npy new file mode 100644 index 0000000000000000000000000000000000000000..960a39f74a2b64e5887d18a5b4541d41115e98fd GIT binary patch literal 2048 zcmbV}`#%+U8h{TnljM@xE)zORm`TcIcTG9(d%ApR6d$Ix>rA1@s3@5k6Um@Lg_RJZ zi;OL|m>TJP-}exri%X$wY)HB|uBlbYZu>9n^V{?M`kZwAn~U2fHOWts5c3`0`?m+0 zFOix%_}H0SO3i%&0)qlQ{kH`K?(qI!cl6x7-}_VF@9VkO`;%K(FSeB0*?(y%Jt+M@ znKb!H36suNQ0|IUJX)ZV6-n!1w|^qb$F?XMbcC#{E*UqQMB|IezMm2M3UEl!yu~EijPQK(BTZ>(ARF)_gRBbeGfE z<9GstgA&BL4ReSZ7trp9Ka>B8d_3>?Pi{^z#DU2LbhuDQUKeh`d)p__ce_r2kM}ib z>1pSaRA8$`u0 zcI6ttS@l>4`QQhK(1%^zq4k?6@~|NYK7r0={baMRlk2{o$$GPuOj!mnxE)2u`^yg6 z+djk3TvPakq+IAf`T^dXr{VP*C(&-%VIetXLTxX#C@<|x(mj0*{ZtRR`K=BX<<`>o zt0&2KXU^e{)kESd)k*MMdLLFeJmD9AHRHOE3vh34FCUq1g}JSlIZAOIvU4xc-Qs(A zV4XdW4ep2Vl4Y`))r=c8PRR@cUZH(j1Ppr45^KISBHe+fJfTdTR+Y@5HQSD3Rr5VM zFsY4;+l_gq!!0&lRWI|%h!@gMf0?XK6PK8u<&lLN^wXPEXq2VnSadpCnjRH~pBYl> zCO=XS^dnd0P4q8oVhv{rUa#q-(}SAwk(UO%*p9>m+hiD@H3X|ZeRmm~!38_Mz|#Cd zUOLSH`z>;Kac2x%S{p-#Q>yV)hz;-DR{}Lz=Y-#2CAOLCfQLkdc1aOXQ)eohP`HxZ z-@Ia}WFd`wGl_JZk72RXWjdAG!h5Ucv5Q|l>rV-k)tpg?hLLjFZwECo-}xV`x?o27 zcooJUr=ib+3mB~)B~+?el(r&^65Z0s=UgM|YTRc6ejv*NiTtpygx%D3U_T0PRX&jMR9`e$29Qg9i|*V=DWH0u)9~3E*X{i+S;#?Ctb~^yhZM`B|g9(Mb*Ccja){Xe3y!bfD7y ztLRy4#7S@o!u_knn`_mmxP1Ut1oWZACIZ51^fo*(9D!wjdCo(33#r-uDr8!} zXV)YBa9*0jLERy+uIf)zx-B0o^Yr=i`g7oB*(J(HZ()+`1ibR-!_DK7U}7H$$==y? z{M84RXUwKmR@UU6aS|tfw}=`;s@d$!Tz)ms%cW24sY9_}gsW|Y4x=%MwXWpBTWe`x z#%s_}B;#?98z`AC_KypLJvkWqM1x~<5+Swvy?C~v z1|1{QVDt4}ba)pDVmKRoDoRLcCQ+vTBBvwqdgOj61(P%E!7~^M@NB2tO2c_6FAfdA3R}WsJQK6DYmetDYY^QN>#RxvS7(gAF`Lb@WY`D}t6|FjkSxyqoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I$-20EHL3bhL41Fn{dFOOzUdU;f4^2?($f%q*Dt4w)$)EkJ?fVdHeHv%yL Dz!Wx$ literal 0 HcmV?d00001 diff --git a/source/tests/data_modifier/sys_10/set.000/force.npy b/source/tests/data_modifier/sys_10/set.000/force.npy new file mode 100644 index 0000000000000000000000000000000000000000..9fe56bda580de79e873d7539a8c7690595a8edd9 GIT binary patch literal 5888 zcmbVQ`8${U^G14?k|?Aidx%0f$orY0>{}|LjU;JTaZ2Q5$y!RGEM-YaM4^;;UZW^k z(xDvKe4uoB+Sc+gw*4~^N{fI=A&%LqSh$hetLC3ZL1t1lO5hOQ|+l1$;p%+KXkotXpG zlfJV=*@+~7;tFo>*w346kHY~8iCVt3jXVsO;vu_!3(A;lr1}u5Sf4nq-1ThXkc1U8Msn zzrY2H2C}xjLRD$mkgzy`GK}|26DD7Jd99byxbBV}zdN93Qi7F34^^$m#n? zLtl*#BuGxdpJx_R{D(H?Ge?yCb#Cy9vkv09-gD>{r$Kg{_nW54pNf)r5JyNADO zB!Z`MeBj>;t~e#?3^P(t!^q%P&^j-HZq7?VXt)Shmzt18o;JC9^zeIg7qC3-I!?2G z6STbe!H)VpV@4t2TzY9cyibc|8KFp9GVj2tin-Ld?jU>JdXN3uu8A*Bgu`y9NLqaS z9vAskg34_-qw30L_Q^lGXQ<>I@uHJC z8&Nc2QTApy<6bd)15tcH%ITU@F1qA*D+`Odo}zKt$tnlSV^q-hleLL8&{cmI$_+AL zCM{Cb`{FixSigzI`BktP8yL!86lJwXmSI=$nA$@MZFH>P9Q|vQIi;u4*f?VmDNZxN z+l3rxw(p0~*=bzIm8+;%E0a+)H4foismz=@bxO0$ZgjpwW(Oih)JE|KORs4XSmGI>n&n#YSj z+z!UGD>=)lj*#wJ0lnumF@5TET5Xrc^a@K^pYPJESM&XmTdRu|ryS99z5*NWX~2|> zAbd2c7^F)Kgf<4X@Xz%^`Z?>I#qTl$+!(o%Vh+xLJ18KwJEGAh5tO}Xi7Mu~Z1G(g3@MPo>bwu2Bkc?W3#Z|Y;ZH1oJF%1y z$v-}hsqDQXq)!OZVo^;-2xc44bH zW_dB@KW-gZg`0wy-V7+Zt4oP;o6!1w3+>kY1Viw(QrPpO9cG6sQfhUK2%XqcX42<2llJTI~XO z&klhxWtOCHR0d1?CApb*@?rRc1gBAT3$0VjQF-AFTIKpLwVVvaIg_L)w=suH`Vt3^ zeEL|! zo0pQJt0?wgOXn+xkHEtvE!^qJk>Kd@15TbZM(O4TCc8zznnu3yar=L8W9QC7^)x9= zQZ~kvuwZ_Sdjk&dj==N0GbDx?@O3lyz=jDaBsV0=suW~#QQcPZZdZejU@7(hr_!#3 zqZl)e@YGo^Zq>=-Y#}d(y)UgP_xu6W$#=%OK3()2lg9QP6~Q4ij(RT5?k3|~qqw$bisym()IDcoYA!{u*_6>r4j~X+R$zv4~`&m#* zH7~BY9QN2wClMWAJhf$j3k}&wGY3;G+=j(zB+d=XET%I_mk+GXRta^kJAzcL2X1-p z1(UzO5XM@aW^Kts@M(WFi;@V0h~_JxBvQfEEYYFL$RM04T0@euBB*+K18RIaNO$6M z*|Dl^)bV&Ojx1ja0cy|qFaArh@54(-uO5d*e)51XR?xCz=PYEVjiod2ML4GQC%lfz zM%h7E7UU94@4{EoqkBD6vV1eSan;Ojd>d23#>UmcyxXtn zWoI5$$h3pVCm|}8AL0-Ha-rdi18~!K0&^SF2p+9&oMiGn+)><(m+Xe=%FP}!-m(VO zU$nDro3C+AirRSp4bU37OEr^}!%#6>@P}g#QdHz6RysF^&KQ&vH96q^>kH}Oq$Dcd zCxy9_ga2^hbIBTkBDrxx#lAILE7Iy+#k* zIN8nH+K93Z8z<2o30p{s?1MWiHR!!y3l3`aR=@b-NHe9&_^7A9*|9h)T&!AIk%XTlO8)DIPY~mYQedBMs9r}T}=#Hw*-us^FD-kSA3n1vi zCG0-(i0L0F<(k^A(YY93GIuS8hucDN{VT>U76Gk3kOS87v22UnUC=fDOE~1wkD2>F zV0*fB?Q`~+)Sfut4EZqT+wXZrT2agG)B6T z4wS6IE{{1BlNd)K{qxY>Xf*%wm^uV?dy?J!Y_Q6Ae!xDNMWXMcx4|kk_M$Ig@6R^~Df0_%xMy^r%zBa|f1F^q!@K z%))t(+PMXm!R*$If1n`YIZXdG1>>*JvABM*gDVaWXW#DgVDl=KP2A%PkAgL^vt)U7 zTbl-b3fPW@RR_pCFCSQz2ePGMv~yJhAGc@*`Bnevmyb7v-**y|Hg-o3v32Nb5sn)b zRqO($+lrv5`!G}sb>11n_c6FWe^ihR)KjtYcKae^8dcRDN+0AChgu1Tgw@QxFO zsQw1fuQSK#UGDhZ?ax$Bc?Cg5ld$8s5~fwBGAk(!Ha6owuGUGwK0iH+muoHYy!!^$ zpSGQSu25sYE?O};=0G}IAMwZi!bqz$pIiR3lnZnZCO*Cc?M7O0an)=P36!Trm8U@g zODVSJF^XR($Mv!2ApWT*Q!7dXd6R=^GU@<~Kcfj7b6nY~t`ZpfYL9iJg>3PPpWHti zvspsR6<%jjF&N6eWf8weapzKs;HH5;SAD6O3%MRkH?~bho#>_L+N(;Mi?`#Jv|JV) z@Qi8SFJLClgG_&kEc#WuLF)D+e2Lf-;eF9*m{!;a(Rw@|JEQ=%xgN|eC8U^O&U9ZW7+9c4dT@@kvjFb%;% zd={_|w`Uwe?T?q)&WGnI(t9^oKevDk5<*cXQHn0w=wpt21ADIdi;YYwq%XVvqn-tU zbSPAmlJsWR_L!;EZrBn9byIXu*R&k9pKDOu8+Ed7ok@L7wqWJ^lk?WRjB#D&6zn;f zUX)95b2GlP`R>;tPpP3syX6BKc@3aL@RZu9<3u~3N#HT78czSjZ{DM?4ELN}MUq+b z$Zh>S6cmK9dUvy$RI^grF;c+t{;sBTjtRK=;VUNk=N21W6oJLDJk((r)DPH^Nc9vD zTdpF!FL@s(?ER0+61Ib;g8_aqU5K?u4uY7M3ObwGVon#L3TbPdTDmH_BrWR;hpJ%V-oEO$7TYy zG<5P4K8+!_6No$ZC*z>eaWoEi!PeAOQ1#_EoSH9DyGRcD4SP}NLuGug-^_ZQbJ;YL zQpzZ5qm!Rk(Dol~tS#TX)-GAU7JCYy>xUgKj5&{w_RpnD#{W>E{f9eb6;4=h8MZux2x6kdewURxXGJROYYTJk6#Kt1;3fz zltNr0b^wFUnU=?1c=NTF9gkFH@-07L&x1VnEp8&L-aHNj1N-2aC%~?A`Ls^X z31ixl@a78-LPEY~|wjiYDKm(R*L+diA!6pv!R8=ga|oPccq zxdXwwvN^B1r%?8G40B#4MT@iaurn$h)BnlC&g0|h*1-xg`ZxvNT69qHUks0ri>LJ; zq_9k^oPC)n$%6YX)A(Q2RIKVmg79*d)@WM0C)v2xd0z)8o%Y1LV@lBAr9EBwUO@vE zoem@(E3NijBP2wmwr`DqjM_NB>%#b%2{0TJwMz$^k;`kW^xfHZ;|emBlv!2DhoMv zfV`F@V^Og#*0x8$w*4BkOI3?|{ap;^Ot}rIF{#{S@yGttbd2*z~T;hDRU zm^8Q;|5m$5`??FsCSnoI#wPZ?)DFwV>$#5~-mun&Y&Nd(HY@2mgT7y%Q9{{SIxONq zIR!WQWqbC4)!o0??RkH=j}OFHS8EV^JCD@c=fSyCn+UF)!KWkMC>wvh#>?OZ|Jk;Q zGx0c%W3#;>g+s8J{F{YNkVU7CljtqGon=hSguc7KS@$PZ7Jf~D8Ml@)UpX)E)Jqa3 z{>?+%Qxovx3u&&B2e$Sf#T6MX%&gWFf0x@*qw08=nP*OhQBBOmtQg$=pFr2KPmp;- zjS_Z8qrmMLw@2$NtJClT)9H74x8xQsnbq*(U8lLz54NChf+<(fq)cN59>5vB3l?SJ ze>i1!9?V-)$xLo5;>^HvAXt77k|quFFa4xx&TeVE8k&XWiurh^U>Y^a6;UggfR)@U zQg&&^4-rS{)1(djLRe#}O0idi=Q=MKq9rMSNPD_zQ51`o1s zlAtmf?|gP-hp(lP{q)1QRn!)b-C7NHYa~cz?k5Y;z0P2>=?1tPXmW=Zc7gBO68Qd0 z41c7b0@{jrAtDwfyRES0P6q}2`!AVxMUs>HR~8{EkD8S;*k{$B%qRCC+s?X}amzz= zJ2tA8q}yn-mo~k*s>^Q09)@f4wINwU59>%?yiuMmpoY{i$y+qns2 zRq52G#V~rH5RSMi(~sviz%^R1%0IszLAM-Ulp76ESMKm_PsUJL Date: Fri, 8 Nov 2019 23:08:01 +0800 Subject: [PATCH 019/147] multi-threading for ewald --- source/lib/include/Ewald.h | 143 +++++++++++++++++++++++++------------ 1 file changed, 98 insertions(+), 45 deletions(-) diff --git a/source/lib/include/Ewald.h b/source/lib/include/Ewald.h index e6fc837386..9b96e9dcde 100644 --- a/source/lib/include/Ewald.h +++ b/source/lib/include/Ewald.h @@ -2,6 +2,7 @@ #include #include +#include #include "SimulationRegion.h" @@ -122,77 +123,115 @@ EwaldReciprocal(VALUETYPE & ener, ener = 0; fill(force.begin(), force.end(), static_cast(0)); fill(virial.begin(), virial.end(), static_cast(0)); - + + // number of threads + int nthreads = 1; +#pragma omp parallel + { + if (0 == omp_get_thread_num()) { + nthreads = omp_get_num_threads(); + } + } + + // K grid vector KK(3); int totK = 1; cmpt_k(KK, region, param); for (int dd = 0; dd < 3; ++dd){ totK *= (KK[dd]+1); } + int stride[3]; + for (int dd = 0; dd < 3; ++dd) stride[dd] = KK[dd]+1; // compute the sq - VALUETYPE * sqr = new VALUETYPE[totK]; - VALUETYPE * sqi = new VALUETYPE[totK]; - for (int ii = 0; ii < totK; ++ii){ - sqr[ii] = static_cast(0); - sqi[ii] = static_cast(0); - } + vector > thread_sqr(nthreads), thread_sqi(nthreads); + for (int ii = 0; ii < nthreads; ++ii){ + thread_sqr[ii].resize(totK, static_cast(0)); + thread_sqi[ii].resize(totK, static_cast(0)); + } // firstly loop over particles then loop over m - int mm[3]; +#pragma omp parallel for num_threads(nthreads) for (int ii = 0; ii < natoms; ++ii){ + int thread_id = omp_get_thread_num(); double ir[3]; region.phys2Inter(ir, &coord[ii*3]); - double mr[3]; - int mc = 0; - for (mm[0] = -KK[0]/2; mm[0] <= KK[0]/2; ++mm[0]){ - mr[0] = ir[0] * mm[0]; - for (mm[1] = -KK[1]/2; mm[1] <= KK[1]/2; ++mm[1]){ - mr[1] = ir[1] * mm[1]; - for (mm[2] = -KK[2]/2; mm[2] <= KK[2]/2; ++mm[2]){ - if (mm[0] == 0 && mm[1] == 0 && mm[2] == 0) continue; - mr[2] = ir[2] * mm[2]; + for (int mm0 = -KK[0]/2; mm0 <= KK[0]/2; ++mm0){ + double mr[3]; + mr[0] = ir[0] * mm0; + int shift0 = (mm0 + KK[0]/2) * stride[1] * stride[2]; + for (int mm1 = -KK[1]/2; mm1 <= KK[1]/2; ++mm1){ + mr[1] = ir[1] * mm1; + int shift1 = (mm1 + KK[1]/2) * stride[2]; + for (int mm2 = -KK[2]/2; mm2 <= KK[2]/2; ++mm2){ + if (mm0 == 0 && mm1 == 0 && mm2 == 0) continue; + int mc = shift0 + shift1 + mm2 + KK[2]/2; + mr[2] = ir[2] * mm2; double mdotr = 2. * M_PI * (mr[0]+mr[1]+mr[2]); - sqr[mc] += charge[ii] * cos(mdotr); - sqi[mc] += charge[ii] * sin(mdotr); - ++mc; + thread_sqr[thread_id][mc] += charge[ii] * cos(mdotr); + thread_sqi[thread_id][mc] += charge[ii] * sin(mdotr); } } } } + VALUETYPE * sqr = new VALUETYPE[totK]; + VALUETYPE * sqi = new VALUETYPE[totK]; + for (int ii = 0; ii < totK; ++ii){ + sqr[ii] = static_cast(0); + sqi[ii] = static_cast(0); + for (int jj = 0; jj < nthreads; ++jj){ + sqr[ii] += thread_sqr[jj][ii]; + sqi[ii] += thread_sqi[jj][ii]; + } + } + + // get rbox VALUETYPE rec_box[9]; const double * rec_box_ = region.getRecBoxTensor(); for (int ii = 0; ii < 9; ++ii){ rec_box[ii] = static_cast(rec_box_[ii]); } + + vector thread_ener(nthreads, 0.); + vector > thread_force(nthreads); + vector > thread_virial(nthreads); + for (int ii = 0; ii < nthreads; ++ii){ + thread_force[ii].resize(natoms * 3, 0.); + thread_virial[ii].resize(9, 0.); + } // calculate ener, force and virial - // firstly loop over particles then loop over m - int mc = 0; - for (mm[0] = -KK[0]/2; mm[0] <= KK[0]/2; ++mm[0]){ - for (mm[1] = -KK[1]/2; mm[1] <= KK[1]/2; ++mm[1]){ - for (mm[2] = -KK[2]/2; mm[2] <= KK[2]/2; ++mm[2]){ - if (mm[0] == 0 && mm[1] == 0 && mm[2] == 0) continue; + // firstly loop over particles then loop over m +#pragma omp parallel for num_threads(nthreads) + for (int mm0 = -KK[0]/2; mm0 <= KK[0]/2; ++mm0){ + int thread_id = omp_get_thread_num(); + int shift0 = (mm0 + KK[0]/2) * stride[1] * stride[2]; + for (int mm1 = -KK[1]/2; mm1 <= KK[1]/2; ++mm1){ + int shift1 = (mm1 + KK[1]/2) * stride[2]; + for (int mm2 = -KK[2]/2; mm2 <= KK[2]/2; ++mm2){ + if (mm0 == 0 && mm1 == 0 && mm2 == 0) continue; + int mc = shift0 + shift1 + mm2 + KK[2]/2; // \bm m and \vert m \vert^2 VALUETYPE rm[3] = {0,0,0}; - for (int dd = 0; dd < 3; ++dd){ - rm[0] += mm[dd] * rec_box[0*3+dd]; - rm[1] += mm[dd] * rec_box[1*3+dd]; - rm[2] += mm[dd] * rec_box[2*3+dd]; - // rm[0] += mm[dd] * rec_box[dd*3+0]; - // rm[1] += mm[dd] * rec_box[dd*3+1]; - // rm[2] += mm[dd] * rec_box[dd*3+2]; - } - VALUETYPE mm2 = rm[0] * rm[0] + rm[1] * rm[1] + rm[2] * rm[2]; + rm[0] += mm0 * rec_box[0*3+0]; + rm[1] += mm0 * rec_box[1*3+0]; + rm[2] += mm0 * rec_box[2*3+0]; + rm[0] += mm1 * rec_box[0*3+1]; + rm[1] += mm1 * rec_box[1*3+1]; + rm[2] += mm1 * rec_box[2*3+1]; + rm[0] += mm2 * rec_box[0*3+2]; + rm[1] += mm2 * rec_box[1*3+2]; + rm[2] += mm2 * rec_box[2*3+2]; + VALUETYPE nmm2 = rm[0] * rm[0] + rm[1] * rm[1] + rm[2] * rm[2]; // energy - VALUETYPE expmm2 = exp(- M_PI * M_PI * mm2 / (param.beta * param.beta)) / mm2; - VALUETYPE eincr = expmm2 * (sqr[mc] * sqr[mc] + sqi[mc] * sqi[mc]); - ener += eincr; + VALUETYPE expnmm2 = exp(- M_PI * M_PI * nmm2 / (param.beta * param.beta)) / nmm2; + VALUETYPE eincr = expnmm2 * (sqr[mc] * sqr[mc] + sqi[mc] * sqi[mc]); + thread_ener[thread_id] += eincr; // virial - VALUETYPE vpref = -2. * (1. + M_PI * M_PI * mm2 / (param.beta * param.beta)) / mm2; + VALUETYPE vpref = -2. * (1. + M_PI * M_PI * nmm2 / (param.beta * param.beta)) / nmm2; for (int dd0 = 0; dd0 < 3; ++dd0){ for (int dd1 = 0; dd1 < 3; ++dd1){ VALUETYPE tmp = vpref * rm[dd0] * rm[dd1]; if (dd0 == dd1) tmp += 1; - virial[dd0*3+dd1] += eincr * tmp; + thread_virial[thread_id][dd0*3+dd1] += eincr * tmp; } } // force @@ -200,15 +239,29 @@ EwaldReciprocal(VALUETYPE & ener, VALUETYPE mdotr = - 2. * M_PI * (coord[ii*3+0]*rm[0] + coord[ii*3+1]*rm[1] + coord[ii*3+2]*rm[2]); VALUETYPE tmpr = charge[ii] * cos(mdotr); VALUETYPE tmpi = charge[ii] * sin(mdotr); - VALUETYPE cc = 4. * M_PI * (tmpr * sqi[mc] + tmpi * sqr[mc]) * expmm2; - force[ii*3+0] -= rm[0] * cc; - force[ii*3+1] -= rm[1] * cc; - force[ii*3+2] -= rm[2] * cc; + VALUETYPE cc = 4. * M_PI * (tmpr * sqi[mc] + tmpi * sqr[mc]) * expnmm2; + thread_force[thread_id][ii*3+0] -= rm[0] * cc; + thread_force[thread_id][ii*3+1] -= rm[1] * cc; + thread_force[thread_id][ii*3+2] -= rm[2] * cc; } - ++mc; } } } + // reduce thread results + for (int ii = 0; ii < nthreads; ++ii){ + ener += thread_ener[ii]; + } + for (int jj = 0; jj < 9; ++jj){ + for (int ii = 0; ii < nthreads; ++ii){ + virial[jj] += thread_virial[ii][jj]; + } + } + for (int jj = 0; jj < natoms * 3; ++jj){ + for (int ii = 0; ii < nthreads; ++ii){ + force[jj] += thread_force[ii][jj]; + } + } + VALUETYPE vol = static_cast(region.getVolume()); ener /= 2 * M_PI * vol; ener *= ElectrostaticConvertion; From d7134fdf9b5b3b569ad64fcd9fe141acab767a09 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sun, 10 Nov 2019 19:37:23 +0800 Subject: [PATCH 020/147] do not apply polar fitting bias, which does not have effect --- source/train/Fitting.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 506f8188b9..cd230d5012 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -410,7 +410,6 @@ def compute_input_stats(self, all_stat, protection = 1e-2): all_tmp = [] for ss in range(len(data)): tmp = np.concatenate(data[ss], axis = 0) - print(tmp.shape) tmp = np.reshape(tmp, [-1, 3, 3]) tmp,_ = np.linalg.eig(tmp) tmp = np.absolute(tmp) @@ -452,9 +451,9 @@ def build (self, layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) if self.fit_diag : bavg = np.zeros(self.dim_rot_mat_1) - bavg[0] = self.avgeig[0] - bavg[1] = self.avgeig[1] - bavg[2] = self.avgeig[2] + # bavg[0] = self.avgeig[0] + # bavg[1] = self.avgeig[1] + # bavg[2] = self.avgeig[2] # (nframes x natoms) x naxis final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, bavg = bavg) # (nframes x natoms) x naxis @@ -463,9 +462,9 @@ def build (self, final_layer = tf.matrix_diag(final_layer) else : bavg = np.zeros(self.dim_rot_mat_1*self.dim_rot_mat_1) - bavg[0*self.dim_rot_mat_1+0] = self.avgeig[0] - bavg[1*self.dim_rot_mat_1+1] = self.avgeig[1] - bavg[2*self.dim_rot_mat_1+2] = self.avgeig[2] + # bavg[0*self.dim_rot_mat_1+0] = self.avgeig[0] + # bavg[1*self.dim_rot_mat_1+1] = self.avgeig[1] + # bavg[2*self.dim_rot_mat_1+2] = self.avgeig[2] # (nframes x natoms) x (naxis x naxis) final_layer = one_layer(layer, self.dim_rot_mat_1*self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, bavg = bavg) # (nframes x natoms) x naxis x naxis From 11e0fd2224df10faf3df398b347f8a2e5fef3ec8 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sun, 10 Nov 2019 19:56:04 +0800 Subject: [PATCH 021/147] provide stop learning rate and set the decay rate automatically --- examples/water/train/polar.json | 4 +-- examples/water/train/polar_se_a.json | 8 +++--- examples/water/train/wannier.json | 4 +-- examples/water/train/water.json | 5 ++-- examples/water/train/water_se_a.json | 4 +-- examples/water/train/water_se_ar.json | 4 +-- examples/water/train/water_se_r.json | 5 ++-- examples/water/train/water_srtab_example.json | 4 +-- source/train/LearningRate.py | 26 +++++++++++++------ source/train/Trainer.py | 14 ++++++---- source/train/train.py | 4 +-- 11 files changed, 49 insertions(+), 33 deletions(-) diff --git a/examples/water/train/polar.json b/examples/water/train/polar.json index 6a1558b124..60e3fa3494 100644 --- a/examples/water/train/polar.json +++ b/examples/water/train/polar.json @@ -31,9 +31,9 @@ "learning_rate" :{ "type": "exp", - "start_lr": 0.001, "decay_steps": 5000, - "decay_rate": 0.95, + "start_lr": 0.001, + "stop_lr": 3.51e-8, "_comment": "that's all" }, diff --git a/examples/water/train/polar_se_a.json b/examples/water/train/polar_se_a.json index 55899e564d..dc90e481ce 100644 --- a/examples/water/train/polar_se_a.json +++ b/examples/water/train/polar_se_a.json @@ -3,7 +3,7 @@ "_comment": " model parameters", "model":{ "type_map": ["O", "H"], - "data_stat_nbatch": 1, + "data_stat_nbatch": 10, "descriptor" :{ "type": "se_a", "sel": [46, 92], @@ -18,7 +18,7 @@ "fitting_net": { "type": "polar", "sel_type": [0], - "fit_diag": true, + "fit_diag": false, "neuron": [100, 100, 100], "resnet_dt": true, "seed": 1, @@ -29,9 +29,9 @@ "learning_rate" :{ "type": "exp", - "start_lr": 0.01, "decay_steps": 5000, - "decay_rate": 0.95, + "start_lr": 0.01, + "stop_lr": 3.51e-7, "_comment": "that's all" }, diff --git a/examples/water/train/wannier.json b/examples/water/train/wannier.json index e969675989..f23f5e0d62 100644 --- a/examples/water/train/wannier.json +++ b/examples/water/train/wannier.json @@ -32,9 +32,9 @@ "learning_rate" :{ "type": "exp", - "start_lr": 0.001, "decay_steps": 5000, - "decay_rate": 0.95, + "start_lr": 0.001, + "stop_lr": 3.51e-8, "_comment": "that's all" }, diff --git a/examples/water/train/water.json b/examples/water/train/water.json index 8b1c6619f7..23ba559aed 100644 --- a/examples/water/train/water.json +++ b/examples/water/train/water.json @@ -3,6 +3,7 @@ "_comment": " model parameters", "model":{ "type_map": ["O", "H"], + "data_stat_nbatch": 10, "descriptor": { "type": "loc_frame", "sel_a": [16, 32], @@ -28,9 +29,9 @@ "learning_rate" :{ "type": "exp", - "start_lr": 0.001, "decay_steps": 5000, - "decay_rate": 0.95, + "start_lr": 0.001, + "stop_lr": 3.51e-8, "_comment": "that's all" }, diff --git a/examples/water/train/water_se_a.json b/examples/water/train/water_se_a.json index 4557e64fa5..cb005530c1 100644 --- a/examples/water/train/water_se_a.json +++ b/examples/water/train/water_se_a.json @@ -24,9 +24,9 @@ "learning_rate" :{ "type": "exp", - "start_lr": 0.001, "decay_steps": 5000, - "decay_rate": 0.95, + "start_lr": 0.001, + "stop_lr": 3.51e-8, "_comment": "that's all" }, diff --git a/examples/water/train/water_se_ar.json b/examples/water/train/water_se_ar.json index e3677f6205..2173f2e1d9 100644 --- a/examples/water/train/water_se_ar.json +++ b/examples/water/train/water_se_ar.json @@ -35,9 +35,9 @@ "learning_rate" :{ "type": "exp", - "start_lr": 0.005, "decay_steps": 5000, - "decay_rate": 0.95, + "start_lr": 0.005, + "stop_lr": 1.76e-7, "_comment": "that's all" }, diff --git a/examples/water/train/water_se_r.json b/examples/water/train/water_se_r.json index c577047189..7faf55a3c3 100644 --- a/examples/water/train/water_se_r.json +++ b/examples/water/train/water_se_r.json @@ -23,9 +23,10 @@ }, "learning_rate" : { - "start_lr": 0.005, + "type": "exp", "decay_steps": 5000, - "decay_rate": 0.95, + "start_lr": 0.005, + "stop_lr": 1.76e-7, "_comment": " that's all" }, diff --git a/examples/water/train/water_srtab_example.json b/examples/water/train/water_srtab_example.json index 846017a24c..f2a0a4a39c 100644 --- a/examples/water/train/water_srtab_example.json +++ b/examples/water/train/water_srtab_example.json @@ -32,9 +32,9 @@ "learning_rate" :{ "type": "exp", - "start_lr": 0.001, "decay_steps": 5000, - "decay_rate": 0.95, + "start_lr": 0.001, + "stop_lr": 3.51e-8, "_comment": "that's all" }, diff --git a/source/train/LearningRate.py b/source/train/LearningRate.py index a26882ef2b..3df4178f38 100644 --- a/source/train/LearningRate.py +++ b/source/train/LearningRate.py @@ -7,15 +7,25 @@ class LearningRateExp (object) : def __init__ (self, jdata) : args = ClassArg()\ - .add('decay_steps', int, must = True)\ - .add('decay_rate', float, must = True)\ - .add('start_lr', float, must = True) - class_data = args.parse(jdata) - self.decay_steps_ = class_data['decay_steps'] - self.decay_rate_ = class_data['decay_rate'] - self.start_lr_ = class_data['start_lr'] + .add('decay_steps', int, must = False)\ + .add('decay_rate', float, must = False)\ + .add('start_lr', float, must = True)\ + .add('stop_lr', float, must = False) + self.cd = args.parse(jdata) + self.start_lr_ = self.cd['start_lr'] - def build(self, global_step) : + def build(self, global_step, stop_batch = None) : + if stop_batch is None: + self.decay_steps_ = self.cd['decay_steps'] if self.cd['decay_steps'] is not None else 5000 + self.decay_rate_ = self.cd['decay_rate'] if self.cd['decay_rate'] is not None else 0.95 + else: + self.stop_lr_ = self.cd['stop_lr'] if self.cd['stop_lr'] is not None else 5e-8 + default_ds = 100 if stop_batch // 10 > 100 else stop_batch // 100 + 1 + self.decay_steps_ = self.cd['decay_steps'] if self.cd['decay_steps'] is not None else default_ds + if self.decay_steps_ >= stop_batch: + self.decay_steps_ = default_ds + self.decay_rate_ = np.exp(np.log(self.stop_lr_ / self.start_lr_) / (stop_batch / self.decay_steps_)) + return tf.train.exponential_decay(self.start_lr_, global_step, self.decay_steps_, diff --git a/source/train/Trainer.py b/source/train/Trainer.py index 2cc73e673e..a0aa95f108 100644 --- a/source/train/Trainer.py +++ b/source/train/Trainer.py @@ -212,9 +212,11 @@ def _message (self, msg) : self.run_opt.message(msg) def build (self, - data) : + data, + stop_batch = 0) : self.ntypes = self.model.get_ntypes() assert (self.ntypes == data.get_ntypes()), "ntypes should match that found in data" + self.stop_batch = stop_batch self.batch_size = data.get_batch_size() @@ -241,7 +243,7 @@ def build (self, def _build_lr(self): self._extra_train_ops = [] self.global_step = tf.train.get_or_create_global_step() - self.learning_rate = self.lr.build(self.global_step) + self.learning_rate = self.lr.build(self.global_step, self.stop_batch) self._message("built lr") def _build_network(self, data): @@ -373,8 +375,8 @@ def _init_sess_distrib(self): # save_checkpoint_steps = self.save_freq) def train (self, - data, - stop_batch) : + data) : + stop_batch = self.stop_batch if self.run_opt.is_distrib : self._init_sess_distrib() else : @@ -387,9 +389,11 @@ def train (self, cur_batch = self.sess.run(self.global_step) self.cur_batch = cur_batch - self.run_opt.message("start training at lr %.2e (== %.2e), final lr will be %.2e" % + self.run_opt.message("start training at lr %.2e (== %.2e), decay_step %d, decay_rate %f, final lr will be %.2e" % (self.sess.run(self.learning_rate), self.lr.value(cur_batch), + self.lr.decay_steps_, + self.lr.decay_rate_, self.lr.value(stop_batch)) ) diff --git a/source/train/train.py b/source/train/train.py index b41c471a3f..9fd4663057 100755 --- a/source/train/train.py +++ b/source/train/train.py @@ -131,11 +131,11 @@ def _do_work(jdata, run_opt): modifier = modifier) data.add_dict(data_requirement) # build the model with stats from the first system - model.build (data) + model.build (data, stop_batch) # train the model with the provided systems in a cyclic way start_time = time.time() cur_batch = 0 - model.train (data, stop_batch) + model.train (data) end_time = time.time() run_opt.message("finished training\nwall time: %.3f s" % (end_time-start_time)) From 02577971bad474a6082ec0e68d0bc5a3e974871a Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 11 Nov 2019 18:08:24 +0800 Subject: [PATCH 022/147] ewald reciprocal: build computational graph on initialization --- source/op/ewald_recp.cc | 33 ++++++++++++++++----------------- source/train/EwaldRecp.py | 35 ++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/source/op/ewald_recp.cc b/source/op/ewald_recp.cc index d2d04601a0..29daaa53c8 100644 --- a/source/op/ewald_recp.cc +++ b/source/op/ewald_recp.cc @@ -59,22 +59,18 @@ class EwaldRecpOp : public OpKernel { const Tensor& box_tensor = context->input(cc++); // set size of the sample - OP_REQUIRES (context, (coord_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of coord should be 2")); - OP_REQUIRES (context, (charge_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of type should be 2")); + OP_REQUIRES (context, (coord_tensor.shape().dims() == 1), errors::InvalidArgument ("Dim of coord should be 1")); + OP_REQUIRES (context, (charge_tensor.shape().dims() == 1), errors::InvalidArgument ("Dim of charge should be 1")); OP_REQUIRES (context, (natoms_tensor.shape().dim_size(0) == 1), errors::InvalidArgument ("size of natoms should be 1")); - OP_REQUIRES (context, (box_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of box should be 2")); + OP_REQUIRES (context, (box_tensor.shape().dims() == 1), errors::InvalidArgument ("Dim of box should be 1")); auto natoms = natoms_tensor.flat(); int nloc = natoms(0); - int nsamples = coord_tensor.shape().dim_size(0); + int nsamples = coord_tensor.shape().dim_size(0) / (nloc * 3); // check the sizes - OP_REQUIRES (context, (nsamples == coord_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (nsamples == charge_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (nsamples == box_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - - OP_REQUIRES (context, (nloc * 3 == coord_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of atoms should match")); - OP_REQUIRES (context, (nloc == charge_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of atoms should match")); - OP_REQUIRES (context, (9 == box_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of box should be 9")); + OP_REQUIRES (context, (nsamples * nloc * 3 == coord_tensor.shape().dim_size(0)), errors::InvalidArgument ("coord number of samples should match")); + OP_REQUIRES (context, (nsamples * nloc * 1 == charge_tensor.shape().dim_size(0)), errors::InvalidArgument ("charge number of samples should match")); + OP_REQUIRES (context, (nsamples * 9 == box_tensor.shape().dim_size(0)), errors::InvalidArgument ("box number of samples should match")); // Create an output tensor TensorShape energy_shape ; @@ -94,18 +90,21 @@ class EwaldRecpOp : public OpKernel { Tensor* virial_tensor = NULL; OP_REQUIRES_OK(context, context->allocate_output(cc++, virial_shape, &virial_tensor)); - auto coord = coord_tensor .matrix(); - auto charge = charge_tensor .matrix(); - auto box = box_tensor .matrix(); + auto coord = coord_tensor .flat(); + auto charge = charge_tensor .flat(); + auto box = box_tensor .flat(); auto energy = energy_tensor ->flat(); auto force = force_tensor ->matrix(); auto virial = virial_tensor ->matrix(); for (int kk = 0; kk < nsamples; ++kk){ + int box_iter = kk * 9; + int coord_iter = kk * nloc * 3; + int charge_iter = kk * nloc; // set region boxtensor_t boxt [9] = {0}; for (int dd = 0; dd < 9; ++dd) { - boxt[dd] = box(kk, dd); + boxt[dd] = box(box_iter + dd); } SimulationRegion region; region.reinitBox (boxt); @@ -114,7 +113,7 @@ class EwaldRecpOp : public OpKernel { vector d_coord3_ (nloc*3); for (int ii = 0; ii < nloc; ++ii){ for (int dd = 0; dd < 3; ++dd){ - d_coord3_[ii*3+dd] = coord(kk, ii*3+dd); + d_coord3_[ii*3+dd] = coord(coord_iter + ii*3+dd); } double inter[3]; region.phys2Inter (inter, &d_coord3_[3*ii]); @@ -130,7 +129,7 @@ class EwaldRecpOp : public OpKernel { // set charge vector d_charge (nloc); - for (int ii = 0; ii < nloc; ++ii) d_charge[ii] = charge(kk, ii); + for (int ii = 0; ii < nloc; ++ii) d_charge[ii] = charge(charge_iter + ii); // prepare outputs vectors VALUETYPE d_ener; diff --git a/source/train/EwaldRecp.py b/source/train/EwaldRecp.py index 20217d0428..619fd0d514 100644 --- a/source/train/EwaldRecp.py +++ b/source/train/EwaldRecp.py @@ -27,6 +27,16 @@ def __init__(self, self.hh = hh self.beta = beta self.sess = tf.Session() + # place holders + self.t_nloc = tf.placeholder(tf.int32, [1], name = "t_nloc") + self.t_coord = tf.placeholder(global_tf_float_precision, [None], name='t_coord') + self.t_charge = tf.placeholder(global_tf_float_precision, [None], name='t_charge') + self.t_box = tf.placeholder(global_tf_float_precision, [None], name='t_box') + + self.t_energy, self.t_force, self.t_virial \ + = op_module.ewald_recp(self.t_coord, self.t_charge, self.t_nloc, self.t_box, + ewald_h = self.hh, + ewald_beta = self.beta) def eval(self, coord, @@ -37,26 +47,17 @@ def eval(self, box = np.array(box) nframes = charge.shape[0] natoms = charge.shape[1] - coord = np.reshape(coord, [nframes, 3*natoms]) - box = np.reshape(box, [nframes, 9]) - # place holders - t_coord = tf.placeholder(global_tf_float_precision, [None, natoms * 3], name='t_coord') - t_charge = tf.placeholder(global_tf_float_precision, [None, natoms], name='t_charge') - t_box = tf.placeholder(global_tf_float_precision, [None, 9], name='t_box') - t_nloc = tf.placeholder(tf.int32, [1], name = "t_nloc") - - t_energy, t_force, t_virial \ - = op_module.ewald_recp(t_coord, t_charge, t_nloc, t_box, - ewald_h = self.hh, - ewald_beta = self.beta) + coord = np.reshape(coord, [nframes * 3 * natoms]) + charge = np.reshape(charge, [nframes * natoms]) + box = np.reshape(box, [nframes * 9]) [energy, force, virial] \ - = self.sess.run([t_energy, t_force, t_virial], + = self.sess.run([self.t_energy, self.t_force, self.t_virial], feed_dict = { - t_coord: coord, - t_charge: charge, - t_box: box, - t_nloc: [natoms], + self.t_coord: coord, + self.t_charge: charge, + self.t_box: box, + self.t_nloc: [natoms], }) return energy, force, virial From 4ebc65e2205f414d25331716020cf55697823d7e Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 11 Nov 2019 18:14:43 +0800 Subject: [PATCH 023/147] revise test_ewald according to new interface --- source/tests/test_ewald.py | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/source/tests/test_ewald.py b/source/tests/test_ewald.py index b6aee7d6b0..4131cfa4df 100644 --- a/source/tests/test_ewald.py +++ b/source/tests/test_ewald.py @@ -54,9 +54,9 @@ def setUp(self): self.dcoord = np.array(self.dcoord).reshape([self.nframes, 3*self.natoms]) self.dcharge = np.array(self.dcharge).reshape([self.nframes, self.natoms]) # place holders - self.coord = tf.placeholder(global_tf_float_precision, [None, self.natoms * 3], name='t_coord') - self.charge = tf.placeholder(global_tf_float_precision, [None, self.natoms], name='t_charge') - self.box = tf.placeholder(global_tf_float_precision, [None, 9], name='t_box') + self.coord = tf.placeholder(global_tf_float_precision, [None], name='t_coord') + self.charge = tf.placeholder(global_tf_float_precision, [None], name='t_charge') + self.box = tf.placeholder(global_tf_float_precision, [None], name='t_box') self.nloc = tf.placeholder(tf.int32, [1], name = "t_nloc") def test_py_interface(self): @@ -69,9 +69,9 @@ def test_py_interface(self): ewald_beta = self.ewald_beta) [e, f, v] = sess.run([t_energy, t_force, t_virial], feed_dict = { - self.coord: self.dcoord, - self.charge: self.dcharge, - self.box: self.dbox, + self.coord: self.dcoord.reshape([-1]), + self.charge: self.dcharge.reshape([-1]), + self.box: self.dbox.reshape([-1]), self.nloc: [self.natoms], }) er = EwaldRecp(self.ewald_h, self.ewald_beta) @@ -103,9 +103,9 @@ def test_force(self): ewald_beta = self.ewald_beta) [force] = sess.run([t_force], feed_dict = { - self.coord: self.dcoord, - self.charge: self.dcharge, - self.box: self.dbox, + self.coord: self.dcoord.reshape([-1]), + self.charge: self.dcharge.reshape([-1]), + self.box: self.dbox.reshape([-1]), self.nloc: [self.natoms], }) for idx in range(self.natoms): @@ -116,16 +116,16 @@ def test_force(self): dcoordm[:,idx*3+dd] = self.dcoord[:,idx*3+dd] - hh energyp = sess.run([t_energy], feed_dict = { - self.coord: dcoordp, - self.charge: self.dcharge, - self.box: self.dbox, + self.coord: dcoordp.reshape([-1]), + self.charge: self.dcharge.reshape([-1]), + self.box: self.dbox.reshape([-1]), self.nloc: [self.natoms], }) energym = sess.run([t_energy], feed_dict = { - self.coord: dcoordm, - self.charge: self.dcharge, - self.box: self.dbox, + self.coord: dcoordm.reshape([-1]), + self.charge: self.dcharge.reshape([-1]), + self.box: self.dbox.reshape([-1]), self.nloc: [self.natoms], }) c_force = -(energyp[0] - energym[0]) / (2*hh) @@ -145,9 +145,9 @@ def test_virial(self): ewald_beta = self.ewald_beta) [virial] = sess.run([t_virial], feed_dict = { - self.coord: self.dcoord, - self.charge: self.dcharge, - self.box: self.dbox, + self.coord: self.dcoord.reshape([-1]), + self.charge: self.dcharge.reshape([-1]), + self.box: self.dbox.reshape([-1]), self.nloc: [self.natoms], }) @@ -181,16 +181,16 @@ def test_virial(self): dcoordm = np.reshape(dcoord3m, [self.nframes,-1]) energyp = sess.run([t_energy], feed_dict = { - self.coord: dcoordp, - self.charge: self.dcharge, - self.box: dboxp, + self.coord: dcoordp.reshape([-1]), + self.charge: self.dcharge.reshape([-1]), + self.box: dboxp.reshape([-1]), self.nloc: [self.natoms], }) energym = sess.run([t_energy], feed_dict = { - self.coord: dcoordm, - self.charge: self.dcharge, - self.box: dboxm, + self.coord: dcoordm.reshape([-1]), + self.charge: self.dcharge.reshape([-1]), + self.box: dboxm.reshape([-1]), self.nloc: [self.natoms], }) num_deriv[:,ii,jj] = -(energyp[0] - energym[0]) / (2.*hh) From b5be8fecd50208dea438e12a37b31ace7165daf6 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 11 Nov 2019 18:32:20 +0800 Subject: [PATCH 024/147] expance three fold loop to enable better multi-thread parallelization --- source/lib/include/Ewald.h | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/source/lib/include/Ewald.h b/source/lib/include/Ewald.h index 9b96e9dcde..e115ec3e97 100644 --- a/source/lib/include/Ewald.h +++ b/source/lib/include/Ewald.h @@ -201,14 +201,22 @@ EwaldReciprocal(VALUETYPE & ener, // calculate ener, force and virial // firstly loop over particles then loop over m #pragma omp parallel for num_threads(nthreads) - for (int mm0 = -KK[0]/2; mm0 <= KK[0]/2; ++mm0){ + for (int mc = 0; mc < totK; ++mc){ int thread_id = omp_get_thread_num(); - int shift0 = (mm0 + KK[0]/2) * stride[1] * stride[2]; - for (int mm1 = -KK[1]/2; mm1 <= KK[1]/2; ++mm1){ - int shift1 = (mm1 + KK[1]/2) * stride[2]; - for (int mm2 = -KK[2]/2; mm2 <= KK[2]/2; ++mm2){ + int mm0 = mc / (stride[1] * stride[2]); + int left = mc - mm0 * stride[1] * stride[2]; + int mm1 = left / stride[2]; + int mm2 = left - mm1 * stride[2]; + mm0 -= KK[0]/2; + mm1 -= KK[1]/2; + mm2 -= KK[2]/2; + // for (int mm0 = -KK[0]/2; mm0 <= KK[0]/2; ++mm0){ + // int shift0 = (mm0 + KK[0]/2) * stride[1] * stride[2]; + // for (int mm1 = -KK[1]/2; mm1 <= KK[1]/2; ++mm1){ + // int shift1 = (mm1 + KK[1]/2) * stride[2]; + // for (int mm2 = -KK[2]/2; mm2 <= KK[2]/2; ++mm2){ + // int mc = shift0 + shift1 + mm2 + KK[2]/2; if (mm0 == 0 && mm1 == 0 && mm2 == 0) continue; - int mc = shift0 + shift1 + mm2 + KK[2]/2; // \bm m and \vert m \vert^2 VALUETYPE rm[3] = {0,0,0}; rm[0] += mm0 * rec_box[0*3+0]; @@ -243,9 +251,9 @@ EwaldReciprocal(VALUETYPE & ener, thread_force[thread_id][ii*3+0] -= rm[0] * cc; thread_force[thread_id][ii*3+1] -= rm[1] * cc; thread_force[thread_id][ii*3+2] -= rm[2] * cc; - } - } - } + } + // } + // } } // reduce thread results for (int ii = 0; ii < nthreads; ++ii){ From 151d07a4e223e1801115ffd34cd9b61c40bcfbdb Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sat, 16 Nov 2019 14:03:54 +0800 Subject: [PATCH 025/147] add c++ interface for DeepTensor, not tested --- source/lib/include/DeepTensor.h | 43 ++++ source/lib/include/NNPInter.h | 49 +---- source/lib/include/common.h | 109 +++++++++ source/lib/src/DeepTensor.cc | 116 ++++++++++ source/lib/src/NNPInter.cc | 379 +------------------------------- source/lib/src/common.cc | 348 +++++++++++++++++++++++++++++ source/train/Model.py | 3 + 7 files changed, 631 insertions(+), 416 deletions(-) create mode 100644 source/lib/include/DeepTensor.h create mode 100644 source/lib/include/common.h create mode 100644 source/lib/src/DeepTensor.cc create mode 100644 source/lib/src/common.cc diff --git a/source/lib/include/DeepTensor.h b/source/lib/include/DeepTensor.h new file mode 100644 index 0000000000..389177c6e7 --- /dev/null +++ b/source/lib/include/DeepTensor.h @@ -0,0 +1,43 @@ +#pragma once + +#include "NNPInter.h" + +class DeepTensor +{ +public: + DeepTensor () ; + DeepTensor (const string & model, const int & gpu_rank = 0); + void init (const string & model, const int & gpu_rank = 0); + void print_summary(const string &pre) const; +public: + void compute (vector & value, + const vector & coord, + const vector & atype, + const vector & box, + const int nghost = 0); + void compute (vector & value, + const vector & coord, + const vector & atype, + const vector & box, + const int nghost, + const LammpsNeighborList & lmp_list); + VALUETYPE cutoff () const {assert(inited); return rcut;}; + int numb_types () const {assert(inited); return ntypes;}; +private: + Session* session; + int num_intra_nthreads, num_inter_nthreads; + GraphDef graph_def; + bool inited; + VALUETYPE rcut; + VALUETYPE cell_size; + int ntypes; + string model_type; + int odim; + template VT get_scalar(const string & name) const; + void run_model (vector & d_tensor_, + Session * session, + const std::vector> & input_tensors, + const NNPAtomMap & nnpmap, + const int nghost = 0); +}; + diff --git a/source/lib/include/NNPInter.h b/source/lib/include/NNPInter.h index a06faaa3b9..7aa4c0ebe9 100644 --- a/source/lib/include/NNPInter.h +++ b/source/lib/include/NNPInter.h @@ -1,53 +1,6 @@ #pragma once -#include "tensorflow/core/public/session.h" -#include "tensorflow/core/platform/env.h" -#include "tensorflow/core/framework/op.h" -#include "tensorflow/core/framework/op_kernel.h" -#include "tensorflow/core/framework/shape_inference.h" - -#include -#include "version.h" - -using namespace tensorflow; -using namespace std; - -#ifdef HIGH_PREC -typedef double VALUETYPE; -typedef double ENERGYTYPE; -#else -typedef float VALUETYPE; -typedef double ENERGYTYPE; -#endif - -struct LammpsNeighborList -{ - int inum; - const int * ilist; - const int * numneigh; - const int *const* firstneigh; - LammpsNeighborList (int inum_, - const int * ilist_, - const int * numneigh_, - const int *const* firstneigh_) - : inum(inum_), ilist(ilist_), numneigh(numneigh_), firstneigh(firstneigh_) - { - } -}; - -struct InternalNeighborList -{ - int * pilist; - int * pjrange; - int * pjlist; - vector ilist; - vector jrange; - vector jlist; - void clear () {ilist.clear(); jrange.clear(); jlist.clear();} - void make_ptrs () { - pilist = &ilist[0]; pjrange = &jrange[0]; pjlist = &jlist[0]; - } -}; +#include "common.h" class NNPInter { diff --git a/source/lib/include/common.h b/source/lib/include/common.h new file mode 100644 index 0000000000..3e4ad3c521 --- /dev/null +++ b/source/lib/include/common.h @@ -0,0 +1,109 @@ +#pragma once + +#include "tensorflow/core/public/session.h" +#include "tensorflow/core/platform/env.h" +#include "tensorflow/core/framework/op.h" +#include "tensorflow/core/framework/op_kernel.h" +#include "tensorflow/core/framework/shape_inference.h" + +using namespace tensorflow; +using namespace std; + +#include "NNPAtomMap.h" +#include +#include "version.h" + +#ifdef HIGH_PREC +typedef double VALUETYPE; +typedef double ENERGYTYPE; +#else +typedef float VALUETYPE; +typedef double ENERGYTYPE; +#endif + +struct LammpsNeighborList +{ + int inum; + const int * ilist; + const int * numneigh; + const int *const* firstneigh; + LammpsNeighborList (int inum_, + const int * ilist_, + const int * numneigh_, + const int *const* firstneigh_) + : inum(inum_), ilist(ilist_), numneigh(numneigh_), firstneigh(firstneigh_) + { + } +}; + +struct InternalNeighborList +{ + int * pilist; + int * pjrange; + int * pjlist; + vector ilist; + vector jrange; + vector jlist; + void clear () {ilist.clear(); jrange.clear(); jlist.clear();} + void make_ptrs () { + pilist = &ilist[0]; pjrange = &jrange[0]; pjlist = &jlist[0]; + } +}; + +void +convert_nlist_lmp_internal (InternalNeighborList & list, + const LammpsNeighborList & lmp_list); + +void +shuffle_nlist (InternalNeighborList & list, + const NNPAtomMap & map); + +void +get_env_nthreads(int & num_intra_nthreads, + int & num_inter_nthreads); + +void +checkStatus(const tensorflow::Status& status); + +template +VT +session_get_scalar(Session* session, const string name); + +int +session_input_tensors (std::vector> & input_tensors, + const vector & dcoord_, + const int & ntypes, + const vector & datype_, + const vector & dbox, + const VALUETYPE & cell_size, + const vector & fparam_, + const vector & aparam_, + const NNPAtomMap& nnpmap, + const int nghost = 0); + +int +session_input_tensors (std::vector> & input_tensors, + const vector & dcoord_, + const int & ntypes, + const vector & datype_, + const vector & dbox, + InternalNeighborList & dlist, + const vector & fparam_, + const vector & aparam_, + const NNPAtomMap& nnpmap, + const int nghost); + + +template +VT +session_get_scalar(Session* session, const string name) +{ + std::vector output_tensors; + checkStatus (session->Run(std::vector> ({}), + {name.c_str()}, + {}, + &output_tensors)); + Tensor output_rc = output_tensors[0]; + auto orc = output_rc.flat (); + return orc(0); +} diff --git a/source/lib/src/DeepTensor.cc b/source/lib/src/DeepTensor.cc new file mode 100644 index 0000000000..00eab78f0f --- /dev/null +++ b/source/lib/src/DeepTensor.cc @@ -0,0 +1,116 @@ +#include "DeepTensor.h" + +DeepTensor:: +DeepTensor(const string & model, const int & gpu_rank) + : inited (false) +{ + get_env_nthreads(num_intra_nthreads, num_inter_nthreads); + init(model, gpu_rank); +} + +void +DeepTensor:: +init (const string & model, const int & gpu_rank) +{ + assert (!inited); + SessionOptions options; + options.config.set_inter_op_parallelism_threads(num_inter_nthreads); + options.config.set_intra_op_parallelism_threads(num_intra_nthreads); + checkStatus (NewSession(options, &session)); + checkStatus (ReadBinaryProto(Env::Default(), model, &graph_def)); + checkStatus (session->Create(graph_def)); + rcut = get_scalar("descrpt_attr/rcut"); + cell_size = rcut; + ntypes = get_scalar("descrpt_attr/ntypes"); + model_type = get_scalar("model_attr/model_type"); + odim = get_scalar("model_attr/output_dim"); + inited = true; +} + +template +VT +DeepTensor:: +get_scalar (const string & name) const +{ + return session_get_scalar(session, name); +} + +void +DeepTensor:: +run_model (vector & d_tensor_, + Session * session, + const std::vector> & input_tensors, + const NNPAtomMap &nnpmap, + const int nghost) +{ + unsigned nloc = nnpmap.get_type().size(); + unsigned nall = nloc + nghost; + if (nloc == 0) { + // no backward map needed + d_tensor_.resize(nall * odim); + fill(d_tensor_.begin(), d_tensor_.end(), 0.0); + return; + } + + std::vector output_tensors; + checkStatus (session->Run(input_tensors, + {"o_" + model_type}, + {}, + &output_tensors)); + + Tensor output_t = output_tensors[0]; + + auto ot = output_t.flat (); + + vector d_tensor (nall * odim); + for (unsigned ii = 0; ii < nall * odim; ++ii){ + d_tensor[ii] = ot(ii); + } + d_tensor_ = d_tensor; + nnpmap.backward (d_tensor_.begin(), d_tensor.begin(), odim); +} + +void +DeepTensor:: +compute (vector & dtensor_, + const vector & dcoord_, + const vector & datype_, + const vector & dbox, + const int nghost) +{ + int nall = dcoord_.size() / 3; + int nloc = nall - nghost; + NNPAtomMap nnpmap (datype_.begin(), datype_.begin() + nloc); + assert (nloc == nnpmap.get_type().size()); + + std::vector> input_tensors; + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, vector(), vector(), nnpmap, nghost); + assert (ret == nloc); + + run_model (dtensor_, session, input_tensors, nnpmap, nghost); +} + +void +DeepTensor:: +compute (vector & dtensor_, + const vector & dcoord_, + const vector & datype_, + const vector & dbox, + const int nghost, + const LammpsNeighborList & lmp_list) +{ + int nall = dcoord_.size() / 3; + int nloc = nall - nghost; + NNPAtomMap nnpmap (datype_.begin(), datype_.begin() + nloc); + assert (nloc == nnpmap.get_type().size()); + + InternalNeighborList nlist; + convert_nlist_lmp_internal (nlist, lmp_list); + shuffle_nlist (nlist, nnpmap); + + std::vector> input_tensors; + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, vector(), vector(), nnpmap, nghost); + assert (nloc == ret); + + run_model (dtensor_, session, input_tensors, nnpmap, nghost); +} diff --git a/source/lib/src/NNPInter.cc b/source/lib/src/NNPInter.cc index fa1f989b49..b01fe6dc1c 100644 --- a/source/lib/src/NNPInter.cc +++ b/source/lib/src/NNPInter.cc @@ -9,329 +9,7 @@ #include #endif -static -void -checkStatus(const tensorflow::Status& status) { - if (!status.ok()) { - std::cout << status.ToString() << std::endl; - exit(1); - } -} -static void -convert_nlist_lmp_internal (InternalNeighborList & list, - const LammpsNeighborList & lmp_list) -{ - list.clear(); - int total_num_nei = 0; - int inum = lmp_list.inum; - for (int ii = 0; ii < inum; ++ii){ - total_num_nei += lmp_list.numneigh[ii]; - } - list.ilist.resize(inum); - list.jrange.resize(inum+1); - list.jlist.resize(total_num_nei); - memcpy(&list.ilist[0], lmp_list.ilist, inum*sizeof(int)); - list.jrange[0] = 0; - for (int ii = 0; ii < inum; ++ii){ - int jnum = lmp_list.numneigh[ii]; - list.jrange[ii+1] = list.jrange[ii] + jnum; - const int * jlist = lmp_list.firstneigh[ii]; - memcpy(&(list.jlist[list.jrange[ii]]), jlist, jnum*sizeof(int)); - } -} - -static void -shuffle_nlist (InternalNeighborList & list, - const NNPAtomMap & map) -{ - const vector & fwd_map = map.get_fwd_map(); - int nloc = fwd_map.size(); - for (unsigned ii = 0; ii < list.ilist.size(); ++ii){ - if (list.ilist[ii] < nloc) { - list.ilist[ii] = fwd_map[list.ilist[ii]]; - } - } - for (unsigned ii = 0; ii < list.jlist.size(); ++ii){ - if (list.jlist[ii] < nloc) { - list.jlist[ii] = fwd_map[list.jlist[ii]]; - } - } -} - -static int -make_input_tensors (std::vector> & input_tensors, - const vector & dcoord_, - const int & ntypes, - const vector & datype_, - const vector & dbox, - const VALUETYPE & cell_size, - const vector & fparam_, - const vector & aparam_, - const NNPAtomMap&nnpmap, - const int nghost = 0) -{ - bool b_ghost = (nghost != 0); - - assert (dbox.size() == 9); - - int nframes = 1; - int nall = dcoord_.size() / 3; - int nloc = nall - nghost; - assert (nall == datype_.size()); - - vector datype = nnpmap.get_type(); - vector type_count (ntypes, 0); - for (unsigned ii = 0; ii < datype.size(); ++ii){ - type_count[datype[ii]] ++; - } - datype.insert (datype.end(), datype_.begin() + nloc, datype_.end()); - - SimulationRegion region; - vector dbox_(9); - for (int dd = 0; dd < 9; ++dd) dbox_[dd] = dbox[dd]; - region.reinitBox (&dbox_[0]); - double box_l[3]; - region.toFaceDistance (box_l); - - vector ncell (3, 2); - for (int dd = 0; dd < 3; ++dd){ - ncell[dd] = box_l[dd] / cell_size; - if (ncell[dd] < 2) ncell[dd] = 2; - } - vector next(3, 0); - for (int dd = 0; dd < 3; ++dd){ - double cellh = box_l[dd] / ncell[dd]; - next[dd] = cellh / cell_size; - if (next[dd] * cellh < cell_size) next[dd]++; - assert (next[dd] * cellh >= cell_size); - } - - TensorShape coord_shape ; - coord_shape.AddDim (nframes); - coord_shape.AddDim (nall * 3); - TensorShape type_shape ; - type_shape.AddDim (nframes); - type_shape.AddDim (nall); - TensorShape box_shape ; - box_shape.AddDim (nframes); - box_shape.AddDim (9); - TensorShape mesh_shape ; - if (!b_ghost){ - mesh_shape.AddDim (6); - } - else { - mesh_shape.AddDim (12); - } - TensorShape natoms_shape ; - natoms_shape.AddDim (2 + ntypes); - TensorShape fparam_shape ; - fparam_shape.AddDim (nframes); - fparam_shape.AddDim (fparam_.size()); - TensorShape aparam_shape ; - aparam_shape.AddDim (nframes); - aparam_shape.AddDim (aparam_.size()); - -#ifdef HIGH_PREC - Tensor coord_tensor (DT_DOUBLE, coord_shape); - Tensor box_tensor (DT_DOUBLE, box_shape); - Tensor fparam_tensor (DT_DOUBLE, fparam_shape); - Tensor aparam_tensor (DT_DOUBLE, aparam_shape); -#else - Tensor coord_tensor (DT_FLOAT, coord_shape); - Tensor box_tensor (DT_FLOAT, box_shape); - Tensor fparam_tensor (DT_FLOAT, fparam_shape); - Tensor aparam_tensor (DT_FLOAT, aparam_shape); -#endif - Tensor type_tensor (DT_INT32, type_shape); - Tensor mesh_tensor (DT_INT32, mesh_shape); - Tensor natoms_tensor (DT_INT32, natoms_shape); - - auto coord = coord_tensor.matrix (); - auto type = type_tensor.matrix (); - auto box = box_tensor.matrix (); - auto mesh = mesh_tensor.flat (); - auto natoms = natoms_tensor.flat (); - auto fparam = fparam_tensor.matrix (); - auto aparam = aparam_tensor.matrix (); - - vector dcoord (dcoord_); - nnpmap.forward (dcoord.begin(), dcoord_.begin(), 3); - - for (int ii = 0; ii < nframes; ++ii){ - for (int jj = 0; jj < nall * 3; ++jj){ - coord(ii, jj) = dcoord[jj]; - } - for (int jj = 0; jj < 9; ++jj){ - box(ii, jj) = dbox[jj]; - } - for (int jj = 0; jj < nall; ++jj){ - type(ii, jj) = datype[jj]; - } - for (int jj = 0; jj < fparam_.size(); ++jj){ - fparam(ii, jj) = fparam_[jj]; - } - for (int jj = 0; jj < aparam_.size(); ++jj){ - aparam(ii, jj) = aparam_[jj]; - } - } - mesh (1-1) = 0; - mesh (2-1) = 0; - mesh (3-1) = 0; - mesh (4-1) = ncell[0]; - mesh (5-1) = ncell[1]; - mesh (6-1) = ncell[2]; - if (b_ghost){ - mesh(7-1) = -next[0]; - mesh(8-1) = -next[1]; - mesh(9-1) = -next[2]; - mesh(10-1) = ncell[0] + next[0]; - mesh(11-1) = ncell[1] + next[1]; - mesh(12-1) = ncell[2] + next[2]; - } - natoms (0) = nloc; - natoms (1) = nall; - for (int ii = 0; ii < ntypes; ++ii) natoms(ii+2) = type_count[ii]; - - input_tensors = { - {"t_coord", coord_tensor}, - {"t_type", type_tensor}, - {"t_box", box_tensor}, - {"t_mesh", mesh_tensor}, - {"t_natoms",natoms_tensor}, - }; - if (fparam_.size() > 0) { - input_tensors.push_back({"t_fparam", fparam_tensor}); - } - if (aparam_.size() > 0) { - input_tensors.push_back({"t_aparam", aparam_tensor}); - } - return nloc; -} - -static int -make_input_tensors (std::vector> & input_tensors, - const vector & dcoord_, - const int & ntypes, - const vector & datype_, - const vector & dbox, - InternalNeighborList & dlist, - const vector & fparam_, - const vector & aparam_, - const NNPAtomMap&nnpmap, - const int nghost) -{ - assert (dbox.size() == 9); - - int nframes = 1; - int nall = dcoord_.size() / 3; - int nloc = nall - nghost; - assert (nall == datype_.size()); - - vector datype = nnpmap.get_type(); - vector type_count (ntypes, 0); - for (unsigned ii = 0; ii < datype.size(); ++ii){ - type_count[datype[ii]] ++; - } - datype.insert (datype.end(), datype_.begin() + nloc, datype_.end()); - - TensorShape coord_shape ; - coord_shape.AddDim (nframes); - coord_shape.AddDim (nall * 3); - TensorShape type_shape ; - type_shape.AddDim (nframes); - type_shape.AddDim (nall); - TensorShape box_shape ; - box_shape.AddDim (nframes); - box_shape.AddDim (9); - TensorShape mesh_shape ; - mesh_shape.AddDim (16); - TensorShape natoms_shape ; - natoms_shape.AddDim (2 + ntypes); - TensorShape fparam_shape ; - fparam_shape.AddDim (nframes); - fparam_shape.AddDim (fparam_.size()); - TensorShape aparam_shape ; - aparam_shape.AddDim (nframes); - aparam_shape.AddDim (aparam_.size()); - -#ifdef HIGH_PREC - Tensor coord_tensor (DT_DOUBLE, coord_shape); - Tensor box_tensor (DT_DOUBLE, box_shape); - Tensor fparam_tensor (DT_DOUBLE, fparam_shape); - Tensor aparam_tensor (DT_DOUBLE, aparam_shape); -#else - Tensor coord_tensor (DT_FLOAT, coord_shape); - Tensor box_tensor (DT_FLOAT, box_shape); - Tensor fparam_tensor (DT_FLOAT, fparam_shape); - Tensor aparam_tensor (DT_FLOAT, aparam_shape); -#endif - Tensor type_tensor (DT_INT32, type_shape); - Tensor mesh_tensor (DT_INT32, mesh_shape); - Tensor natoms_tensor (DT_INT32, natoms_shape); - - auto coord = coord_tensor.matrix (); - auto type = type_tensor.matrix (); - auto box = box_tensor.matrix (); - auto mesh = mesh_tensor.flat (); - auto natoms = natoms_tensor.flat (); - auto fparam = fparam_tensor.matrix (); - auto aparam = aparam_tensor.matrix (); - - vector dcoord (dcoord_); - nnpmap.forward (dcoord.begin(), dcoord_.begin(), 3); - - for (int ii = 0; ii < nframes; ++ii){ - for (int jj = 0; jj < nall * 3; ++jj){ - coord(ii, jj) = dcoord[jj]; - } - for (int jj = 0; jj < 9; ++jj){ - box(ii, jj) = dbox[jj]; - } - for (int jj = 0; jj < nall; ++jj){ - type(ii, jj) = datype[jj]; - } - for (int jj = 0; jj < fparam_.size(); ++jj){ - fparam(ii, jj) = fparam_[jj]; - } - for (int jj = 0; jj < aparam_.size(); ++jj){ - aparam(ii, jj) = aparam_[jj]; - } - } - - for (int ii = 0; ii < 16; ++ii) mesh(ii) = 0; - - mesh (0) = sizeof(int *) / sizeof(int); - assert (mesh(0) * sizeof(int) == sizeof(int *)); - const int & stride = mesh(0); - mesh (1) = dlist.ilist.size(); - assert (mesh(1) == nloc); - assert (stride <= 4); - dlist.make_ptrs(); - memcpy (&mesh(4), &(dlist.pilist), sizeof(int *)); - memcpy (&mesh(8), &(dlist.pjrange), sizeof(int *)); - memcpy (&mesh(12), &(dlist.pjlist), sizeof(int *)); - - natoms (0) = nloc; - natoms (1) = nall; - for (int ii = 0; ii < ntypes; ++ii) natoms(ii+2) = type_count[ii]; - - input_tensors = { - {"t_coord", coord_tensor}, - {"t_type", type_tensor}, - {"t_box", box_tensor}, - {"t_mesh", mesh_tensor}, - {"t_natoms", natoms_tensor}, - }; - if (fparam_.size() > 0) { - input_tensors.push_back({"t_fparam", fparam_tensor}); - } - if (aparam_.size() > 0) { - input_tensors.push_back({"t_aparam", aparam_tensor}); - } - - return nloc; -} static void run_model (ENERGYTYPE & dener, @@ -459,28 +137,6 @@ run_model (ENERGYTYPE & dener, nnpmap.backward (datom_virial_.begin(), datom_virial.begin(), 9); } -static void -get_env_nthreads(int & num_intra_nthreads, - int & num_inter_nthreads) -{ - num_intra_nthreads = 0; - num_inter_nthreads = 0; - const char* env_intra_nthreads = std::getenv("OMP_NUM_THREADS"); - const char* env_inter_nthreads = std::getenv("TF_INTER_OP_PARALLELISM_THREADS"); - if (env_intra_nthreads && - string(env_intra_nthreads) != string("") && - atoi(env_intra_nthreads) >= 0 - ) { - num_intra_nthreads = atoi(env_intra_nthreads); - } - if (env_inter_nthreads && - string(env_inter_nthreads) != string("") && - atoi(env_inter_nthreads) >= 0 - ) { - num_inter_nthreads = atoi(env_inter_nthreads); - } -} - NNPInter:: NNPInter () @@ -584,14 +240,7 @@ VT NNPInter:: get_scalar (const string & name) const { - std::vector output_tensors; - checkStatus (session->Run(std::vector> ({}), - {name.c_str()}, - {}, - &output_tensors)); - Tensor output_rc = output_tensors[0]; - auto orc = output_rc.flat (); - return orc(0); + return session_get_scalar(session, name); } void @@ -627,7 +276,7 @@ compute (ENERGYTYPE & dener, validate_fparam_aparam(nloc, fparam, aparam); std::vector> input_tensors; - int ret = make_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, nnpmap, nghost); + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, nnpmap, nghost); assert (ret == nloc); run_model (dener, dforce_, dvirial, session, input_tensors, nnpmap, nghost); @@ -657,7 +306,7 @@ compute (ENERGYTYPE & dener, shuffle_nlist (nlist, nnpmap); std::vector> input_tensors; - int ret = make_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, nnpmap, nghost); + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, nnpmap, nghost); assert (nloc == ret); run_model (dener, dforce_, dvirial, session, input_tensors, nnpmap, nghost); @@ -681,7 +330,7 @@ compute (ENERGYTYPE & dener, validate_fparam_aparam(nnpmap.get_type().size(), fparam, aparam); std::vector> input_tensors; - int nloc = make_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, nnpmap); + int nloc = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, nnpmap); run_model (dener, dforce_, dvirial, datom_energy_, datom_virial_, session, input_tensors, nnpmap); } @@ -714,7 +363,7 @@ compute (ENERGYTYPE & dener, shuffle_nlist (nlist, nnpmap); std::vector> input_tensors; - int ret = make_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, nnpmap, nghost); + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, nnpmap, nghost); assert (nloc == ret); run_model (dener, dforce_, dvirial, datom_energy_, datom_virial_, session, input_tensors, nnpmap, nghost); @@ -823,18 +472,12 @@ get_scalar(const string name) const { VT myrcut = 0; for (unsigned ii = 0; ii < numb_models; ++ii){ - std::vector output_tensors; - checkStatus (sessions[ii]->Run(std::vector> ({}), - {name.c_str()}, - {}, - &output_tensors)); - Tensor output_rc = output_tensors[0]; - auto orc = output_rc.flat (); + VT ret = session_get_scalar(sessions[ii], name); if (ii == 0){ - myrcut = orc(0); + myrcut = ret; } else { - assert (myrcut == orc(0)); + assert (myrcut == ret); } } return myrcut; @@ -872,7 +515,7 @@ compute (ENERGYTYPE & dener, validate_fparam_aparam(nnpmap.get_type().size(), fparam, aparam); std::vector> input_tensors; - int nloc = make_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, nnpmap); + int nloc = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, nnpmap); vector all_energy (numb_models); vector > all_force (numb_models); @@ -926,7 +569,7 @@ compute (vector & all_energy, shuffle_nlist (nlist, nnpmap); std::vector> input_tensors; - int ret = make_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, nnpmap, nghost); + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, nnpmap, nghost); assert (nloc == ret); all_energy.resize (numb_models); @@ -965,7 +608,7 @@ compute (vector & all_energy, shuffle_nlist (nlist, nnpmap); std::vector> input_tensors; - int ret = make_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, nnpmap, nghost); + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, nnpmap, nghost); assert (nloc == ret); all_energy.resize (numb_models); diff --git a/source/lib/src/common.cc b/source/lib/src/common.cc new file mode 100644 index 0000000000..2b78d4839a --- /dev/null +++ b/source/lib/src/common.cc @@ -0,0 +1,348 @@ +#include "common.h" +#include "NNPAtomMap.h" +#include "SimulationRegion.h" + +void +convert_nlist_lmp_internal (InternalNeighborList & list, + const LammpsNeighborList & lmp_list) +{ + list.clear(); + int total_num_nei = 0; + int inum = lmp_list.inum; + for (int ii = 0; ii < inum; ++ii){ + total_num_nei += lmp_list.numneigh[ii]; + } + list.ilist.resize(inum); + list.jrange.resize(inum+1); + list.jlist.resize(total_num_nei); + memcpy(&list.ilist[0], lmp_list.ilist, inum*sizeof(int)); + list.jrange[0] = 0; + for (int ii = 0; ii < inum; ++ii){ + int jnum = lmp_list.numneigh[ii]; + list.jrange[ii+1] = list.jrange[ii] + jnum; + const int * jlist = lmp_list.firstneigh[ii]; + memcpy(&(list.jlist[list.jrange[ii]]), jlist, jnum*sizeof(int)); + } +} + +void +shuffle_nlist (InternalNeighborList & list, + const NNPAtomMap & map) +{ + const vector & fwd_map = map.get_fwd_map(); + int nloc = fwd_map.size(); + for (unsigned ii = 0; ii < list.ilist.size(); ++ii){ + if (list.ilist[ii] < nloc) { + list.ilist[ii] = fwd_map[list.ilist[ii]]; + } + } + for (unsigned ii = 0; ii < list.jlist.size(); ++ii){ + if (list.jlist[ii] < nloc) { + list.jlist[ii] = fwd_map[list.jlist[ii]]; + } + } +} + +void +checkStatus(const tensorflow::Status& status) { + if (!status.ok()) { + std::cout << status.ToString() << std::endl; + exit(1); + } +} + +void +get_env_nthreads(int & num_intra_nthreads, + int & num_inter_nthreads) +{ + num_intra_nthreads = 0; + num_inter_nthreads = 0; + const char* env_intra_nthreads = std::getenv("OMP_NUM_THREADS"); + const char* env_inter_nthreads = std::getenv("TF_INTER_OP_PARALLELISM_THREADS"); + if (env_intra_nthreads && + string(env_intra_nthreads) != string("") && + atoi(env_intra_nthreads) >= 0 + ) { + num_intra_nthreads = atoi(env_intra_nthreads); + } + if (env_inter_nthreads && + string(env_inter_nthreads) != string("") && + atoi(env_inter_nthreads) >= 0 + ) { + num_inter_nthreads = atoi(env_inter_nthreads); + } +} + +int +session_input_tensors (std::vector> & input_tensors, + const vector & dcoord_, + const int & ntypes, + const vector & datype_, + const vector & dbox, + const VALUETYPE & cell_size, + const vector & fparam_, + const vector & aparam_, + const NNPAtomMap& nnpmap, + const int nghost) +{ + bool b_ghost = (nghost != 0); + + assert (dbox.size() == 9); + + int nframes = 1; + int nall = dcoord_.size() / 3; + int nloc = nall - nghost; + assert (nall == datype_.size()); + + vector datype = nnpmap.get_type(); + vector type_count (ntypes, 0); + for (unsigned ii = 0; ii < datype.size(); ++ii){ + type_count[datype[ii]] ++; + } + datype.insert (datype.end(), datype_.begin() + nloc, datype_.end()); + + SimulationRegion region; + vector dbox_(9); + for (int dd = 0; dd < 9; ++dd) dbox_[dd] = dbox[dd]; + region.reinitBox (&dbox_[0]); + double box_l[3]; + region.toFaceDistance (box_l); + + vector ncell (3, 2); + for (int dd = 0; dd < 3; ++dd){ + ncell[dd] = box_l[dd] / cell_size; + if (ncell[dd] < 2) ncell[dd] = 2; + } + vector next(3, 0); + for (int dd = 0; dd < 3; ++dd){ + double cellh = box_l[dd] / ncell[dd]; + next[dd] = cellh / cell_size; + if (next[dd] * cellh < cell_size) next[dd]++; + assert (next[dd] * cellh >= cell_size); + } + + TensorShape coord_shape ; + coord_shape.AddDim (nframes); + coord_shape.AddDim (nall * 3); + TensorShape type_shape ; + type_shape.AddDim (nframes); + type_shape.AddDim (nall); + TensorShape box_shape ; + box_shape.AddDim (nframes); + box_shape.AddDim (9); + TensorShape mesh_shape ; + if (!b_ghost){ + mesh_shape.AddDim (6); + } + else { + mesh_shape.AddDim (12); + } + TensorShape natoms_shape ; + natoms_shape.AddDim (2 + ntypes); + TensorShape fparam_shape ; + fparam_shape.AddDim (nframes); + fparam_shape.AddDim (fparam_.size()); + TensorShape aparam_shape ; + aparam_shape.AddDim (nframes); + aparam_shape.AddDim (aparam_.size()); + +#ifdef HIGH_PREC + Tensor coord_tensor (DT_DOUBLE, coord_shape); + Tensor box_tensor (DT_DOUBLE, box_shape); + Tensor fparam_tensor (DT_DOUBLE, fparam_shape); + Tensor aparam_tensor (DT_DOUBLE, aparam_shape); +#else + Tensor coord_tensor (DT_FLOAT, coord_shape); + Tensor box_tensor (DT_FLOAT, box_shape); + Tensor fparam_tensor (DT_FLOAT, fparam_shape); + Tensor aparam_tensor (DT_FLOAT, aparam_shape); +#endif + Tensor type_tensor (DT_INT32, type_shape); + Tensor mesh_tensor (DT_INT32, mesh_shape); + Tensor natoms_tensor (DT_INT32, natoms_shape); + + auto coord = coord_tensor.matrix (); + auto type = type_tensor.matrix (); + auto box = box_tensor.matrix (); + auto mesh = mesh_tensor.flat (); + auto natoms = natoms_tensor.flat (); + auto fparam = fparam_tensor.matrix (); + auto aparam = aparam_tensor.matrix (); + + vector dcoord (dcoord_); + nnpmap.forward (dcoord.begin(), dcoord_.begin(), 3); + + for (int ii = 0; ii < nframes; ++ii){ + for (int jj = 0; jj < nall * 3; ++jj){ + coord(ii, jj) = dcoord[jj]; + } + for (int jj = 0; jj < 9; ++jj){ + box(ii, jj) = dbox[jj]; + } + for (int jj = 0; jj < nall; ++jj){ + type(ii, jj) = datype[jj]; + } + for (int jj = 0; jj < fparam_.size(); ++jj){ + fparam(ii, jj) = fparam_[jj]; + } + for (int jj = 0; jj < aparam_.size(); ++jj){ + aparam(ii, jj) = aparam_[jj]; + } + } + mesh (1-1) = 0; + mesh (2-1) = 0; + mesh (3-1) = 0; + mesh (4-1) = ncell[0]; + mesh (5-1) = ncell[1]; + mesh (6-1) = ncell[2]; + if (b_ghost){ + mesh(7-1) = -next[0]; + mesh(8-1) = -next[1]; + mesh(9-1) = -next[2]; + mesh(10-1) = ncell[0] + next[0]; + mesh(11-1) = ncell[1] + next[1]; + mesh(12-1) = ncell[2] + next[2]; + } + natoms (0) = nloc; + natoms (1) = nall; + for (int ii = 0; ii < ntypes; ++ii) natoms(ii+2) = type_count[ii]; + + input_tensors = { + {"t_coord", coord_tensor}, + {"t_type", type_tensor}, + {"t_box", box_tensor}, + {"t_mesh", mesh_tensor}, + {"t_natoms",natoms_tensor}, + }; + if (fparam_.size() > 0) { + input_tensors.push_back({"t_fparam", fparam_tensor}); + } + if (aparam_.size() > 0) { + input_tensors.push_back({"t_aparam", aparam_tensor}); + } + return nloc; +} + +int +session_input_tensors (std::vector> & input_tensors, + const vector & dcoord_, + const int & ntypes, + const vector & datype_, + const vector & dbox, + InternalNeighborList & dlist, + const vector & fparam_, + const vector & aparam_, + const NNPAtomMap& nnpmap, + const int nghost) +{ + assert (dbox.size() == 9); + + int nframes = 1; + int nall = dcoord_.size() / 3; + int nloc = nall - nghost; + assert (nall == datype_.size()); + + vector datype = nnpmap.get_type(); + vector type_count (ntypes, 0); + for (unsigned ii = 0; ii < datype.size(); ++ii){ + type_count[datype[ii]] ++; + } + datype.insert (datype.end(), datype_.begin() + nloc, datype_.end()); + + TensorShape coord_shape ; + coord_shape.AddDim (nframes); + coord_shape.AddDim (nall * 3); + TensorShape type_shape ; + type_shape.AddDim (nframes); + type_shape.AddDim (nall); + TensorShape box_shape ; + box_shape.AddDim (nframes); + box_shape.AddDim (9); + TensorShape mesh_shape ; + mesh_shape.AddDim (16); + TensorShape natoms_shape ; + natoms_shape.AddDim (2 + ntypes); + TensorShape fparam_shape ; + fparam_shape.AddDim (nframes); + fparam_shape.AddDim (fparam_.size()); + TensorShape aparam_shape ; + aparam_shape.AddDim (nframes); + aparam_shape.AddDim (aparam_.size()); + +#ifdef HIGH_PREC + Tensor coord_tensor (DT_DOUBLE, coord_shape); + Tensor box_tensor (DT_DOUBLE, box_shape); + Tensor fparam_tensor (DT_DOUBLE, fparam_shape); + Tensor aparam_tensor (DT_DOUBLE, aparam_shape); +#else + Tensor coord_tensor (DT_FLOAT, coord_shape); + Tensor box_tensor (DT_FLOAT, box_shape); + Tensor fparam_tensor (DT_FLOAT, fparam_shape); + Tensor aparam_tensor (DT_FLOAT, aparam_shape); +#endif + Tensor type_tensor (DT_INT32, type_shape); + Tensor mesh_tensor (DT_INT32, mesh_shape); + Tensor natoms_tensor (DT_INT32, natoms_shape); + + auto coord = coord_tensor.matrix (); + auto type = type_tensor.matrix (); + auto box = box_tensor.matrix (); + auto mesh = mesh_tensor.flat (); + auto natoms = natoms_tensor.flat (); + auto fparam = fparam_tensor.matrix (); + auto aparam = aparam_tensor.matrix (); + + vector dcoord (dcoord_); + nnpmap.forward (dcoord.begin(), dcoord_.begin(), 3); + + for (int ii = 0; ii < nframes; ++ii){ + for (int jj = 0; jj < nall * 3; ++jj){ + coord(ii, jj) = dcoord[jj]; + } + for (int jj = 0; jj < 9; ++jj){ + box(ii, jj) = dbox[jj]; + } + for (int jj = 0; jj < nall; ++jj){ + type(ii, jj) = datype[jj]; + } + for (int jj = 0; jj < fparam_.size(); ++jj){ + fparam(ii, jj) = fparam_[jj]; + } + for (int jj = 0; jj < aparam_.size(); ++jj){ + aparam(ii, jj) = aparam_[jj]; + } + } + + for (int ii = 0; ii < 16; ++ii) mesh(ii) = 0; + + mesh (0) = sizeof(int *) / sizeof(int); + assert (mesh(0) * sizeof(int) == sizeof(int *)); + const int & stride = mesh(0); + mesh (1) = dlist.ilist.size(); + assert (mesh(1) == nloc); + assert (stride <= 4); + dlist.make_ptrs(); + memcpy (&mesh(4), &(dlist.pilist), sizeof(int *)); + memcpy (&mesh(8), &(dlist.pjrange), sizeof(int *)); + memcpy (&mesh(12), &(dlist.pjlist), sizeof(int *)); + + natoms (0) = nloc; + natoms (1) = nall; + for (int ii = 0; ii < ntypes; ++ii) natoms(ii+2) = type_count[ii]; + + input_tensors = { + {"t_coord", coord_tensor}, + {"t_type", type_tensor}, + {"t_box", box_tensor}, + {"t_mesh", mesh_tensor}, + {"t_natoms",natoms_tensor}, + }; + if (fparam_.size() > 0) { + input_tensors.push_back({"t_fparam", fparam_tensor}); + } + if (aparam_.size() > 0) { + input_tensors.push_back({"t_aparam", aparam_tensor}); + } + + return nloc; +} diff --git a/source/train/Model.py b/source/train/Model.py index c568dbe9ec..3615440612 100644 --- a/source/train/Model.py +++ b/source/train/Model.py @@ -345,6 +345,9 @@ def build (self, t_mt = tf.constant(self.model_type, name = 'model_type', dtype = tf.string) + t_od = tf.constant(self.get_out_size(), + name = 'output_dim', + dtype = tf.int32) coord = tf.reshape (coord_, [-1, natoms[1] * 3]) atype = tf.reshape (atype_, [-1, natoms[1]]) From d34c055a130e5229b6b3e050d9f432703c07a181 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Wed, 20 Nov 2019 17:57:03 +0800 Subject: [PATCH 026/147] fix bugs in DeepTensor. mv common methods of DeepPot and DeepTensor inference to common.h/.cc. fix bugs in DataModifier, EwaldRecp, DeepPot and DeepEval. --- source/lib/include/DeepTensor.h | 17 +++- source/lib/include/NNPInter.h | 18 +++- source/lib/include/common.h | 106 +++++++++++++++++++++-- source/lib/src/DeepTensor.cc | 91 ++++++++++++++++---- source/lib/src/NNPInter.cc | 52 ++++++++++-- source/lib/src/common.cc | 144 ++++++++++++++++++++++++++++---- source/scripts/freeze.py | 3 +- source/train/DataModifier.py | 4 + source/train/DeepEval.py | 34 +++++--- source/train/DeepPot.py | 10 ++- source/train/EwaldRecp.py | 23 ++--- source/train/Fitting.py | 4 + 12 files changed, 431 insertions(+), 75 deletions(-) diff --git a/source/lib/include/DeepTensor.h b/source/lib/include/DeepTensor.h index 389177c6e7..14f0f69997 100644 --- a/source/lib/include/DeepTensor.h +++ b/source/lib/include/DeepTensor.h @@ -5,7 +5,7 @@ class DeepTensor { public: - DeepTensor () ; + DeepTensor (); DeepTensor (const string & model, const int & gpu_rank = 0); void init (const string & model, const int & gpu_rank = 0); void print_summary(const string &pre) const; @@ -23,6 +23,8 @@ class DeepTensor const LammpsNeighborList & lmp_list); VALUETYPE cutoff () const {assert(inited); return rcut;}; int numb_types () const {assert(inited); return ntypes;}; + int output_dim () const {assert(inited); return odim;}; + vector sel_types () const {assert(inited); return sel_type;}; private: Session* session; int num_intra_nthreads, num_inter_nthreads; @@ -33,11 +35,24 @@ class DeepTensor int ntypes; string model_type; int odim; + vector sel_type; template VT get_scalar(const string & name) const; + template vector get_vector(const string & name) const; void run_model (vector & d_tensor_, Session * session, const std::vector> & input_tensors, const NNPAtomMap & nnpmap, const int nghost = 0); + void compute_inner (vector & value, + const vector & coord, + const vector & atype, + const vector & box, + const int nghost = 0); + void compute_inner (vector & value, + const vector & coord, + const vector & atype, + const vector & box, + const int nghost, + const InternalNeighborList&lmp_list); }; diff --git a/source/lib/include/NNPInter.h b/source/lib/include/NNPInter.h index 7aa4c0ebe9..113304a0b3 100644 --- a/source/lib/include/NNPInter.h +++ b/source/lib/include/NNPInter.h @@ -61,8 +61,8 @@ class NNPInter GraphDef graph_def; bool inited; template VT get_scalar(const string & name) const; - VALUETYPE get_rcut () const; - int get_ntypes () const; + // VALUETYPE get_rcut () const; + // int get_ntypes () const; VALUETYPE rcut; VALUETYPE cell_size; int ntypes; @@ -71,6 +71,16 @@ class NNPInter void validate_fparam_aparam(const int & nloc, const vector &fparam, const vector &aparam)const ; + void compute_inner (ENERGYTYPE & ener, + vector & force, + vector & virial, + const vector & coord, + const vector & atype, + const vector & box, + const int nghost, + const InternalNeighborList & lmp_list, + const vector & fparam = vector(), + const vector & aparam = vector()); }; class NNPInterModelDevi @@ -136,8 +146,8 @@ class NNPInterModelDevi vector graph_defs; bool inited; template VT get_scalar(const string name) const; - VALUETYPE get_rcut () const; - int get_ntypes () const; + // VALUETYPE get_rcut () const; + // int get_ntypes () const; VALUETYPE rcut; VALUETYPE cell_size; int ntypes; diff --git a/source/lib/include/common.h b/source/lib/include/common.h index 3e4ad3c521..8b92dba15f 100644 --- a/source/lib/include/common.h +++ b/source/lib/include/common.h @@ -54,10 +54,44 @@ void convert_nlist_lmp_internal (InternalNeighborList & list, const LammpsNeighborList & lmp_list); +void +shuffle_nlist (InternalNeighborList & list, + const vector & fwd_map); + void shuffle_nlist (InternalNeighborList & list, const NNPAtomMap & map); +void +shuffle_nlist_exclude_empty (InternalNeighborList & list, + const vector & fwd_map); + + +void +select_by_type(vector & fwd_map, + vector & bkw_map, + int & nghost_real, + const vector & dcoord_, + const vector & datype_, + const int & nghost, + const vector & sel_type_); + +void +select_real_atoms(vector & fwd_map, + vector & bkw_map, + int & nghost_real, + const vector & dcoord_, + const vector & datype_, + const int & nghost, + const int & ntypes); + +template +void +select_map(vector & out, + const vector & in, + const vector & fwd_map, + const int & stride); + void get_env_nthreads(int & num_intra_nthreads, int & num_inter_nthreads); @@ -65,9 +99,13 @@ get_env_nthreads(int & num_intra_nthreads, void checkStatus(const tensorflow::Status& status); -template +template VT -session_get_scalar(Session* session, const string name); +session_get_scalar(Session* session, const string name, const string scope = ""); + +template +vector +session_get_vector(Session* session, const string name, const string scope = ""); int session_input_tensors (std::vector> & input_tensors, @@ -79,7 +117,8 @@ session_input_tensors (std::vector> & input_tensors, const vector & fparam_, const vector & aparam_, const NNPAtomMap& nnpmap, - const int nghost = 0); + const int nghost = 0, + const string scope = ""); int session_input_tensors (std::vector> & input_tensors, @@ -91,13 +130,18 @@ session_input_tensors (std::vector> & input_tensors, const vector & fparam_, const vector & aparam_, const NNPAtomMap& nnpmap, - const int nghost); + const int nghost, + const string scope = ""); -template +template VT -session_get_scalar(Session* session, const string name) +session_get_scalar(Session* session, const string name_, const string scope) { + string name = name_; + if (scope != "") { + name = scope + "/" + name; + } std::vector output_tensors; checkStatus (session->Run(std::vector> ({}), {name.c_str()}, @@ -107,3 +151,53 @@ session_get_scalar(Session* session, const string name) auto orc = output_rc.flat (); return orc(0); } + +template +vector +session_get_vector(Session* session, const string name_, const string scope) +{ + string name = name_; + if (scope != "") { + name = scope + "/" + name; + } + std::vector output_tensors; + checkStatus (session->Run(std::vector> ({}), + {name.c_str()}, + {}, + &output_tensors)); + Tensor output_rc = output_tensors[0]; + assert(1 == output_rc.shape().dims()); + int dof = output_rc.shape().dim_size(0); + vector o_vec(dof); + auto orc = output_rc.flat (); + for (int ii = 0; ii < dof; ++ii){ + o_vec[ii] = orc(ii); + } + return o_vec; +} + + +template +void +select_map(vector & out, + const vector & in, + const vector & idx_map, + const int & stride) +{ +#ifdef DEBUG + assert(in.size() / stride * stride == in.size()), "in size should be multiples of stride" +#endif + for (int ii = 0; ii < in.size() / stride; ++ii){ +#ifdef DEBUG + assert(ii < idx_map.size()), "idx goes over the idx map size"; + assert(idx_map[ii] < out.size()), "mappped idx goes over the out size"; +#endif + if (idx_map[ii] >= 0) { + int to_ii = idx_map[ii]; + for (int dd = 0; dd < stride; ++dd){ + out[to_ii * stride + dd] = in[ii * stride + dd]; + } + } + } +} + diff --git a/source/lib/src/DeepTensor.cc b/source/lib/src/DeepTensor.cc index 00eab78f0f..ea0a7579a8 100644 --- a/source/lib/src/DeepTensor.cc +++ b/source/lib/src/DeepTensor.cc @@ -1,5 +1,11 @@ #include "DeepTensor.h" +DeepTensor:: +DeepTensor() + : inited (false) +{ +} + DeepTensor:: DeepTensor(const string & model, const int & gpu_rank) : inited (false) @@ -24,6 +30,7 @@ init (const string & model, const int & gpu_rank) ntypes = get_scalar("descrpt_attr/ntypes"); model_type = get_scalar("model_attr/model_type"); odim = get_scalar("model_attr/output_dim"); + sel_type = get_vector("model_attr/sel_type"); inited = true; } @@ -35,6 +42,14 @@ get_scalar (const string & name) const return session_get_scalar(session, name); } +template +vector +DeepTensor:: +get_vector (const string & name) const +{ + return session_get_vector(session, name); +} + void DeepTensor:: run_model (vector & d_tensor_, @@ -46,9 +61,8 @@ run_model (vector & d_tensor_, unsigned nloc = nnpmap.get_type().size(); unsigned nall = nloc + nghost; if (nloc == 0) { - // no backward map needed - d_tensor_.resize(nall * odim); - fill(d_tensor_.begin(), d_tensor_.end(), 0.0); + // return empty + d_tensor_.clear(); return; } @@ -59,17 +73,19 @@ run_model (vector & d_tensor_, &output_tensors)); Tensor output_t = output_tensors[0]; + assert (output_t.dims() == 1), "dim of output tensor should be 1"; + int o_size = output_t.dim_size(0); auto ot = output_t.flat (); - vector d_tensor (nall * odim); - for (unsigned ii = 0; ii < nall * odim; ++ii){ + vector d_tensor (o_size); + for (unsigned ii = 0; ii < o_size; ++ii){ d_tensor[ii] = ot(ii); } d_tensor_ = d_tensor; - nnpmap.backward (d_tensor_.begin(), d_tensor.begin(), odim); } + void DeepTensor:: compute (vector & dtensor_, @@ -77,6 +93,54 @@ compute (vector & dtensor_, const vector & datype_, const vector & dbox, const int nghost) +{ + vector dcoord; + vector datype, fwd_map, bkw_map; + int nghost_real; + select_real_atoms(fwd_map, bkw_map, nghost_real, dcoord_, datype_, nghost, ntypes); + // resize to nall_real + dcoord.resize(bkw_map.size() * 3); + datype.resize(bkw_map.size()); + // fwd map + select_map(dcoord, dcoord_, fwd_map, 3); + select_map(datype, datype_, fwd_map, 1); + compute_inner(dtensor_, dcoord, datype, dbox, nghost_real); +} + +void +DeepTensor:: +compute (vector & dtensor_, + const vector & dcoord_, + const vector & datype_, + const vector & dbox, + const int nghost, + const LammpsNeighborList & lmp_list) +{ + vector dcoord; + vector datype, fwd_map, bkw_map; + int nghost_real; + select_real_atoms(fwd_map, bkw_map, nghost_real, dcoord_, datype_, nghost, ntypes); + // resize to nall_real + dcoord.resize(bkw_map.size() * 3); + datype.resize(bkw_map.size()); + // fwd map + select_map(dcoord, dcoord_, fwd_map, 3); + select_map(datype, datype_, fwd_map, 1); + // internal nlist + InternalNeighborList nlist; + convert_nlist_lmp_internal(nlist, lmp_list); + shuffle_nlist_exclude_empty(nlist, fwd_map); + compute_inner(dtensor_, dcoord, datype, dbox, nghost_real, nlist); +} + + +void +DeepTensor:: +compute_inner (vector & dtensor_, + const vector & dcoord_, + const vector & datype_, + const vector & dbox, + const int nghost) { int nall = dcoord_.size() / 3; int nloc = nall - nghost; @@ -92,20 +156,19 @@ compute (vector & dtensor_, void DeepTensor:: -compute (vector & dtensor_, - const vector & dcoord_, - const vector & datype_, - const vector & dbox, - const int nghost, - const LammpsNeighborList & lmp_list) +compute_inner (vector & dtensor_, + const vector & dcoord_, + const vector & datype_, + const vector & dbox, + const int nghost, + const InternalNeighborList & nlist_) { int nall = dcoord_.size() / 3; int nloc = nall - nghost; NNPAtomMap nnpmap (datype_.begin(), datype_.begin() + nloc); assert (nloc == nnpmap.get_type().size()); - InternalNeighborList nlist; - convert_nlist_lmp_internal (nlist, lmp_list); + InternalNeighborList nlist(nlist_); shuffle_nlist (nlist, nnpmap); std::vector> input_tensors; diff --git a/source/lib/src/NNPInter.cc b/source/lib/src/NNPInter.cc index b01fe6dc1c..149ece4736 100644 --- a/source/lib/src/NNPInter.cc +++ b/source/lib/src/NNPInter.cc @@ -184,8 +184,8 @@ init (const string & model, const int & gpu_rank) ntypes = get_scalar("descrpt_attr/ntypes"); dfparam = get_scalar("fitting_attr/dfparam"); daparam = get_scalar("fitting_attr/daparam"); - assert(rcut == get_rcut()); - assert(ntypes == get_ntypes()); + // assert(rcut == get_rcut()); + // assert(ntypes == get_ntypes()); if (dfparam < 0) dfparam = 0; if (daparam < 0) daparam = 0; inited = true; @@ -207,8 +207,8 @@ init (const string & model, const int & gpu_rank) ntypes = get_scalar("descrpt_attr/ntypes"); dfparam = get_scalar("fitting_attr/dfparam"); daparam = get_scalar("fitting_attr/daparam"); - assert(rcut == get_rcut()); - assert(ntypes == get_ntypes()); + // assert(rcut == get_rcut()); + // assert(ntypes == get_ntypes()); if (dfparam < 0) dfparam = 0; if (daparam < 0) daparam = 0; // rcut = get_rcut(); @@ -293,7 +293,44 @@ compute (ENERGYTYPE & dener, const int nghost, const LammpsNeighborList & lmp_list, const vector & fparam, - const vector & aparam) + const vector & aparam_) +{ + vector dcoord, dforce, aparam; + vector datype, fwd_map, bkw_map; + int nghost_real; + select_real_atoms(fwd_map, bkw_map, nghost_real, dcoord_, datype_, nghost, ntypes); + // resize to nall_real + dcoord.resize(bkw_map.size() * 3); + datype.resize(bkw_map.size()); + // fwd map + select_map(dcoord, dcoord_, fwd_map, 3); + select_map(datype, datype_, fwd_map, 1); + // aparam + if (daparam > 0){ + aparam.resize(bkw_map.size()); + select_map(aparam, aparam_, fwd_map, daparam); + } + // internal nlist + InternalNeighborList nlist; + convert_nlist_lmp_internal(nlist, lmp_list); + shuffle_nlist_exclude_empty(nlist, fwd_map); + compute_inner(dener, dforce, dvirial, dcoord, datype, dbox, nghost_real, nlist, fparam, aparam); + // bkw map + select_map(dforce_, dforce, bkw_map, 3); +} + +void +NNPInter:: +compute_inner (ENERGYTYPE & dener, + vector & dforce_, + vector & dvirial, + const vector & dcoord_, + const vector & datype_, + const vector & dbox, + const int nghost, + const InternalNeighborList & nlist_, + const vector & fparam, + const vector & aparam) { int nall = dcoord_.size() / 3; int nloc = nall - nghost; @@ -301,9 +338,10 @@ compute (ENERGYTYPE & dener, assert (nloc == nnpmap.get_type().size()); validate_fparam_aparam(nloc, fparam, aparam); - InternalNeighborList nlist; - convert_nlist_lmp_internal (nlist, lmp_list); + InternalNeighborList nlist(nlist_); shuffle_nlist (nlist, nnpmap); + // convert_nlist_lmp_internal (nlist, lmp_list); + // shuffle_nlist (nlist, nnpmap); std::vector> input_tensors; int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, nnpmap, nghost); diff --git a/source/lib/src/common.cc b/source/lib/src/common.cc index 2b78d4839a..708de71b5d 100644 --- a/source/lib/src/common.cc +++ b/source/lib/src/common.cc @@ -2,6 +2,64 @@ #include "NNPAtomMap.h" #include "SimulationRegion.h" +void +select_by_type(vector & fwd_map, + vector & bkw_map, + int & nghost_real, + const vector & dcoord_, + const vector & datype_, + const int & nghost, + const vector & sel_type_) +{ + vector sel_type (sel_type_); + sort(sel_type.begin(), sel_type.end()); + int nall = dcoord_.size() / 3; + int nloc = nall - nghost; + int nloc_real = 0; + nghost_real = 0; + fwd_map.resize(nall); + bkw_map.clear(); + bkw_map.reserve(nall); + int cc = 0; + for (int ii = 0; ii < nall; ++ii){ + // exclude virtual sites + // select the type with id < ntypes + if (lower_bound(sel_type.begin(), sel_type.end(), datype_[ii]) != + sel_type.end()){ + bkw_map.push_back(ii); + if (ii < nloc) { + nloc_real += 1; + } + else{ + nghost_real += 1; + } + fwd_map[ii] = cc; + cc ++; + } + else{ + fwd_map[ii] = -1; + } + } + assert((nloc_real+nghost_real) == bkw_map.size()); +} + + +void +select_real_atoms(vector & fwd_map, + vector & bkw_map, + int & nghost_real, + const vector & dcoord_, + const vector & datype_, + const int & nghost, + const int & ntypes) +{ + vector sel_type; + for (int ii = 0; ii < ntypes; ++ii){ + sel_type.push_back(ii); + } + select_by_type(fwd_map, bkw_map, nghost_real, dcoord_, datype_, nghost, sel_type); +} + void convert_nlist_lmp_internal (InternalNeighborList & list, const LammpsNeighborList & lmp_list) @@ -30,6 +88,13 @@ shuffle_nlist (InternalNeighborList & list, const NNPAtomMap & map) { const vector & fwd_map = map.get_fwd_map(); + shuffle_nlist(list, fwd_map); +} + +void +shuffle_nlist (InternalNeighborList & list, + const vector & fwd_map) +{ int nloc = fwd_map.size(); for (unsigned ii = 0; ii < list.ilist.size(); ++ii){ if (list.ilist[ii] < nloc) { @@ -43,6 +108,41 @@ shuffle_nlist (InternalNeighborList & list, } } +void +shuffle_nlist_exclude_empty (InternalNeighborList & list, + const vector & fwd_map) +{ + int old_nloc = fwd_map.size(); + shuffle_nlist(list, fwd_map); + vector new_ilist, new_jrange, new_jlist, new_icount; + new_ilist.reserve(list.ilist.size()); + new_icount.reserve(list.ilist.size()); + new_jrange.reserve(list.jrange.size()); + new_jlist.reserve(list.jlist.size()); + for(int ii = 0; ii < list.ilist.size(); ++ii){ + if(list.ilist[ii] >= 0){ + new_ilist.push_back(list.ilist[ii]); + } + } + new_jrange.resize(new_ilist.size()+1); + new_jrange[0] = 0; + for(int ii = 0; ii < list.ilist.size(); ++ii){ + int js = list.jrange[ii]; + int je = list.jrange[ii+1]; + int cc = 0; + for (int jj = js; jj < je; ++jj){ + if (list.jlist[jj] >= 0) { + new_jlist.push_back(list.jlist[jj]); + cc++; + } + } + new_jrange[ii+1] = new_jrange[ii] + cc; + } + list.ilist = new_ilist; + list.jrange = new_jrange; + list.jlist = new_jlist; +} + void checkStatus(const tensorflow::Status& status) { if (!status.ok()) { @@ -83,7 +183,8 @@ session_input_tensors (std::vector> & input_tensors, const vector & fparam_, const vector & aparam_, const NNPAtomMap& nnpmap, - const int nghost) + const int nghost, + const string scope) { bool b_ghost = (nghost != 0); @@ -207,18 +308,22 @@ session_input_tensors (std::vector> & input_tensors, natoms (1) = nall; for (int ii = 0; ii < ntypes; ++ii) natoms(ii+2) = type_count[ii]; + string prefix = ""; + if (scope != ""){ + prefix = scope + "/"; + } input_tensors = { - {"t_coord", coord_tensor}, - {"t_type", type_tensor}, - {"t_box", box_tensor}, - {"t_mesh", mesh_tensor}, - {"t_natoms",natoms_tensor}, + {prefix+"t_coord", coord_tensor}, + {prefix+"t_type", type_tensor}, + {prefix+"t_box", box_tensor}, + {prefix+"t_mesh", mesh_tensor}, + {prefix+"t_natoms", natoms_tensor}, }; if (fparam_.size() > 0) { - input_tensors.push_back({"t_fparam", fparam_tensor}); + input_tensors.push_back({prefix+"t_fparam", fparam_tensor}); } if (aparam_.size() > 0) { - input_tensors.push_back({"t_aparam", aparam_tensor}); + input_tensors.push_back({prefix+"t_aparam", aparam_tensor}); } return nloc; } @@ -233,14 +338,15 @@ session_input_tensors (std::vector> & input_tensors, const vector & fparam_, const vector & aparam_, const NNPAtomMap& nnpmap, - const int nghost) + const int nghost, + const string scope) { assert (dbox.size() == 9); int nframes = 1; int nall = dcoord_.size() / 3; int nloc = nall - nghost; - assert (nall == datype_.size()); + assert (nall == datype_.size()); vector datype = nnpmap.get_type(); vector type_count (ntypes, 0); @@ -330,18 +436,22 @@ session_input_tensors (std::vector> & input_tensors, natoms (1) = nall; for (int ii = 0; ii < ntypes; ++ii) natoms(ii+2) = type_count[ii]; + string prefix = ""; + if (scope != ""){ + prefix = scope + "/"; + } input_tensors = { - {"t_coord", coord_tensor}, - {"t_type", type_tensor}, - {"t_box", box_tensor}, - {"t_mesh", mesh_tensor}, - {"t_natoms",natoms_tensor}, + {prefix+"t_coord", coord_tensor}, + {prefix+"t_type", type_tensor}, + {prefix+"t_box", box_tensor}, + {prefix+"t_mesh", mesh_tensor}, + {prefix+"t_natoms",natoms_tensor}, }; if (fparam_.size() > 0) { - input_tensors.push_back({"t_fparam", fparam_tensor}); + input_tensors.push_back({prefix+"t_fparam", fparam_tensor}); } if (aparam_.size() > 0) { - input_tensors.push_back({"t_aparam", aparam_tensor}); + input_tensors.push_back({prefix+"t_aparam", aparam_tensor}); } return nloc; diff --git a/source/scripts/freeze.py b/source/scripts/freeze.py index 4dd51492a4..a7bb8ca11a 100755 --- a/source/scripts/freeze.py +++ b/source/scripts/freeze.py @@ -41,7 +41,7 @@ def _make_node_names(model_type = None) : elif model_type == 'wfc': nodes = "o_wfc,descrpt_attr/rcut,descrpt_attr/ntypes,model_attr/tmap,model_attr/sel_type,model_attr/model_type" elif model_type == 'dipole': - nodes = "o_dipole,o_rmat,o_rmat_deriv,o_nlist,o_rij,descrpt_attr/rcut,descrpt_attr/ntypes,descrpt_attr/sel,descrpt_attr/ndescrpt,model_attr/tmap,model_attr/sel_type,model_attr/model_type" + nodes = "o_dipole,o_rmat,o_rmat_deriv,o_nlist,o_rij,descrpt_attr/rcut,descrpt_attr/ntypes,descrpt_attr/sel,descrpt_attr/ndescrpt,model_attr/tmap,model_attr/sel_type,model_attr/model_type,model_attr/output_dim" elif model_type == 'polar': nodes = "o_polar,descrpt_attr/rcut,descrpt_attr/ntypes,model_attr/tmap,model_attr/sel_type,model_attr/model_type" elif model_type == 'global_polar': @@ -75,6 +75,7 @@ def freeze_graph(model_folder, # We retrieve the protobuf graph definition graph = tf.get_default_graph() input_graph_def = graph.as_graph_def() + # nodes = [n.name for n in input_graph_def.node] # We start a session and restore the graph weights with tf.Session() as sess: diff --git a/source/train/DataModifier.py b/source/train/DataModifier.py index 029e64219f..ee2ff0d3cb 100644 --- a/source/train/DataModifier.py +++ b/source/train/DataModifier.py @@ -129,8 +129,12 @@ def _build_fv_graph_inner(self): self.t_natoms, n_a_sel = self.nnei_a, n_r_sel = self.nnei_r) + force = tf.identity(force, name='o_dm_force') + virial = tf.identity(virial, name='o_dm_virial') + atom_virial = tf.identity(atom_virial, name='o_dm_av') return force, virial, atom_virial + def _enrich(self, dipole, dof = 3): coll = [] sel_start_idx = 0 diff --git a/source/train/DeepEval.py b/source/train/DeepEval.py index 2c0f613c27..e1156eefa7 100644 --- a/source/train/DeepEval.py +++ b/source/train/DeepEval.py @@ -25,24 +25,23 @@ class DeepEval(): def __init__(self, model_file) : model_file = model_file - graph = self.load_graph (model_file) - t_mt = graph.get_tensor_by_name('load/model_attr/model_type:0') - sess = tf.Session (graph = graph) + self.graph = self._load_graph (model_file) + t_mt = self.graph.get_tensor_by_name('load/model_attr/model_type:0') + sess = tf.Session (graph = self.graph) [mt] = sess.run([t_mt], feed_dict = {}) self.model_type = mt.decode('utf-8') - def load_graph(self, + def _load_graph(self, frozen_graph_filename, - prefix = 'load'): + prefix = 'load', + default_tf_graph = True): # We load the protobuf file from the disk and parse it to retrieve the # unserialized graph_def with tf.gfile.GFile(frozen_graph_filename, "rb") as f: graph_def = tf.GraphDef() graph_def.ParseFromString(f.read()) - # Then, we can use again a convenient built-in function to import a graph_def into the - # current default Graph - with tf.Graph().as_default() as graph: + if default_tf_graph: tf.import_graph_def( graph_def, input_map=None, @@ -50,6 +49,21 @@ def load_graph(self, name=prefix, producer_op_list=None ) + graph = tf.get_default_graph() + else : + # Then, we can use again a convenient built-in function to import a graph_def into the + # current default Graph + with tf.Graph().as_default() as graph: + tf.import_graph_def( + graph_def, + input_map=None, + return_elements=None, + name=prefix, + producer_op_list=None + ) + # for ii in graph.as_graph_def().node: + # print(ii.name) + return graph @@ -100,8 +114,8 @@ def __init__(self, variable_name, variable_dof) : DeepEval.__init__(self, model_file) - self.model_file = model_file - self.graph = self.load_graph (self.model_file) + # self.model_file = model_file + # self.graph = self.load_graph (self.model_file) self.variable_name = variable_name self.variable_dof = variable_dof # checkout input/output tensors from graph diff --git a/source/train/DeepPot.py b/source/train/DeepPot.py index dc62e56d8e..92c931377a 100644 --- a/source/train/DeepPot.py +++ b/source/train/DeepPot.py @@ -3,13 +3,15 @@ import os,sys import numpy as np from deepmd.env import tf +from deepmd.common import make_default_mesh from deepmd.DeepEval import DeepEval class DeepPot (DeepEval) : def __init__(self, model_file) : - self.model_file = model_file - self.graph = self.load_graph (self.model_file) + DeepEval.__init__(self, model_file) + # self.model_file = model_file + # self.graph = self.load_graph (self.model_file) # checkout input/output tensors from graph self.t_ntypes = self.graph.get_tensor_by_name ('load/descrpt_attr/ntypes:0') self.t_rcut = self.graph.get_tensor_by_name ('load/descrpt_attr/rcut:0') @@ -110,7 +112,7 @@ def eval(self, # make natoms_vec and default_mesh natoms_vec = self.make_natoms_vec(atom_types) assert(natoms_vec[0] == natoms) - default_mesh = self.make_default_mesh(cells) + default_mesh = make_default_mesh(cells) # evaluate energy = [] @@ -120,7 +122,7 @@ def eval(self, av = [] feed_dict_test = {} feed_dict_test[self.t_natoms] = natoms_vec - feed_dict_test[self.t_mesh ] = default_mesh + feed_dict_test[self.t_mesh ] = default_mesh[0] feed_dict_test[self.t_type ] = atom_types t_out = [self.t_energy, self.t_force, diff --git a/source/train/EwaldRecp.py b/source/train/EwaldRecp.py index 619fd0d514..4e48e5a0cf 100644 --- a/source/train/EwaldRecp.py +++ b/source/train/EwaldRecp.py @@ -26,17 +26,18 @@ def __init__(self, beta): self.hh = hh self.beta = beta - self.sess = tf.Session() - # place holders - self.t_nloc = tf.placeholder(tf.int32, [1], name = "t_nloc") - self.t_coord = tf.placeholder(global_tf_float_precision, [None], name='t_coord') - self.t_charge = tf.placeholder(global_tf_float_precision, [None], name='t_charge') - self.t_box = tf.placeholder(global_tf_float_precision, [None], name='t_box') - - self.t_energy, self.t_force, self.t_virial \ - = op_module.ewald_recp(self.t_coord, self.t_charge, self.t_nloc, self.t_box, - ewald_h = self.hh, - ewald_beta = self.beta) + with tf.Graph().as_default() as graph: + # place holders + self.t_nloc = tf.placeholder(tf.int32, [1], name = "t_nloc") + self.t_coord = tf.placeholder(global_tf_float_precision, [None], name='t_coord') + self.t_charge = tf.placeholder(global_tf_float_precision, [None], name='t_charge') + self.t_box = tf.placeholder(global_tf_float_precision, [None], name='t_box') + # output + self.t_energy, self.t_force, self.t_virial \ + = op_module.ewald_recp(self.t_coord, self.t_charge, self.t_nloc, self.t_box, + ewald_h = self.hh, + ewald_beta = self.beta) + self.sess = tf.Session(graph=graph) def eval(self, coord, diff --git a/source/train/Fitting.py b/source/train/Fitting.py index cd230d5012..8ee8c80f32 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -539,6 +539,9 @@ def __init__ (self, jdata, descrpt) : def get_sel_type(self): return self.sel_type + def get_out_size(self): + return 3 + def build (self, input_d, rot_mat, @@ -587,3 +590,4 @@ def build (self, count += 1 return tf.reshape(outs, [-1]) + # return tf.reshape(outs, [tf.shape(inputs)[0] * natoms[0] * 3 // 3]) From 72e9933455398312fa26f9d6d3e505d28f52fa21 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 21 Nov 2019 18:09:46 +0800 Subject: [PATCH 027/147] fix bug in data modifier: order of fcorr should be mapped back --- source/train/DataModifier.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/train/DataModifier.py b/source/train/DataModifier.py index ee2ff0d3cb..b55a0af53a 100644 --- a/source/train/DataModifier.py +++ b/source/train/DataModifier.py @@ -259,6 +259,8 @@ def eval_fv(self, coords, cells, atom_types, ext_f) : = self.sess.run([self.force, self.virial, self.av], feed_dict = feed_dict_test) # print('fout: ', fout.shape, fout) + fout = self.reverse_map(np.reshape(fout, [nframes,-1,3]), imap) + fout = np.reshape(fout, [nframes, -1]) return fout, vout, avout From 44bb07ac587ef7881e38c0deba9ba28590131216 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 22 Nov 2019 18:16:29 +0800 Subject: [PATCH 028/147] first working version of force modification --- source/lib/include/DataModifier.h | 46 ++++++ source/lib/include/DeepTensor.h | 2 +- source/lib/include/NNPAtomMap.h | 1 + source/lib/include/common.h | 11 +- source/lib/src/DataModifier.cc | 234 ++++++++++++++++++++++++++++++ source/lib/src/DeepTensor.cc | 8 +- source/lib/src/common.cc | 1 + 7 files changed, 292 insertions(+), 11 deletions(-) create mode 100644 source/lib/include/DataModifier.h create mode 100644 source/lib/src/DataModifier.cc diff --git a/source/lib/include/DataModifier.h b/source/lib/include/DataModifier.h new file mode 100644 index 0000000000..bfa4f31fac --- /dev/null +++ b/source/lib/include/DataModifier.h @@ -0,0 +1,46 @@ +#pragma once + +#include "NNPInter.h" + +class DataModifier +{ +public: + DataModifier (); + DataModifier (const string & model, const int & gpu_rank = 0); + ~DataModifier () {}; + void init (const string & model, const int & gpu_rank = 0); + void print_summary(const string &pre) const; +public: + void compute (vector & dfcorr_, + vector & dvcorr_, + const vector & dcoord_, + const vector & datype_, + const vector & dbox, + const vector> & pairs, + const vector & delef_, + const int nghost, + const LammpsNeighborList & lmp_list); + VALUETYPE cutoff () const {assert(inited); return rcut;}; + int numb_types () const {assert(inited); return ntypes;}; + vector sel_types () const {assert(inited); return sel_type;}; +private: + Session* session; + string name_scope, name_prefix; + int num_intra_nthreads, num_inter_nthreads; + GraphDef graph_def; + bool inited; + VALUETYPE rcut; + VALUETYPE cell_size; + int ntypes; + string model_type; + vector sel_type; + template VT get_scalar(const string & name) const; + template void get_vector(vector & vec, const string & name) const; + void run_model (vector & dforce, + vector & dvirial, + Session * session, + const std::vector> & input_tensors, + const NNPAtomMap & nnpmap, + const int nghost); +}; + diff --git a/source/lib/include/DeepTensor.h b/source/lib/include/DeepTensor.h index 14f0f69997..e0c0392692 100644 --- a/source/lib/include/DeepTensor.h +++ b/source/lib/include/DeepTensor.h @@ -37,7 +37,7 @@ class DeepTensor int odim; vector sel_type; template VT get_scalar(const string & name) const; - template vector get_vector(const string & name) const; + template void get_vector (vector & vec, const string & name) const; void run_model (vector & d_tensor_, Session * session, const std::vector> & input_tensors, diff --git a/source/lib/include/NNPAtomMap.h b/source/lib/include/NNPAtomMap.h index e09b3186b6..e07f7e7e6e 100644 --- a/source/lib/include/NNPAtomMap.h +++ b/source/lib/include/NNPAtomMap.h @@ -18,6 +18,7 @@ class NNPAtomMap const int stride = 1) const ; const vector & get_type () const {return atype;} const vector & get_fwd_map () const {return fwd_idx_map;} + const vector & get_bkw_map () const {return idx_map;} private: vector idx_map; vector fwd_idx_map; diff --git a/source/lib/include/common.h b/source/lib/include/common.h index 8b92dba15f..837f4b0e49 100644 --- a/source/lib/include/common.h +++ b/source/lib/include/common.h @@ -104,8 +104,8 @@ VT session_get_scalar(Session* session, const string name, const string scope = ""); template -vector -session_get_vector(Session* session, const string name, const string scope = ""); +void +session_get_vector(vector & o_vec, Session* session, const string name_, const string scope = ""); int session_input_tensors (std::vector> & input_tensors, @@ -153,8 +153,8 @@ session_get_scalar(Session* session, const string name_, const string scope) } template -vector -session_get_vector(Session* session, const string name_, const string scope) +void +session_get_vector(vector & o_vec, Session* session, const string name_, const string scope) { string name = name_; if (scope != "") { @@ -168,12 +168,11 @@ session_get_vector(Session* session, const string name_, const string scope) Tensor output_rc = output_tensors[0]; assert(1 == output_rc.shape().dims()); int dof = output_rc.shape().dim_size(0); - vector o_vec(dof); + o_vec.resize(dof); auto orc = output_rc.flat (); for (int ii = 0; ii < dof; ++ii){ o_vec[ii] = orc(ii); } - return o_vec; } diff --git a/source/lib/src/DataModifier.cc b/source/lib/src/DataModifier.cc new file mode 100644 index 0000000000..09d370a915 --- /dev/null +++ b/source/lib/src/DataModifier.cc @@ -0,0 +1,234 @@ +#include "DataModifier.h" + +DataModifier:: +DataModifier() + : inited (false) +{ + name_scope = "load"; +} + +DataModifier:: +DataModifier(const string & model, const int & gpu_rank) + : inited (false) +{ + get_env_nthreads(num_intra_nthreads, num_inter_nthreads); + init(model, gpu_rank); +} + +void +DataModifier:: +init (const string & model, const int & gpu_rank) +{ + assert (!inited); + SessionOptions options; + options.config.set_inter_op_parallelism_threads(num_inter_nthreads); + options.config.set_intra_op_parallelism_threads(num_intra_nthreads); + checkStatus(NewSession(options, &session)); + checkStatus(ReadBinaryProto(Env::Default(), model, &graph_def)); + checkStatus(session->Create(graph_def)); + // int nnodes = graph_def.node_size(); + // for (int ii = 0; ii < nnodes; ++ii){ + // cout << ii << " \t " << graph_def.node(ii).name() << endl; + // } + rcut = get_scalar("descrpt_attr/rcut"); + cell_size = rcut; + ntypes = get_scalar("descrpt_attr/ntypes"); + model_type = get_scalar("model_attr/model_type"); + get_vector(sel_type, "model_attr/sel_type"); + sort(sel_type.begin(), sel_type.end()); + inited = true; +} + +template +VT +DataModifier:: +get_scalar (const string & name) const +{ + return session_get_scalar(session, name, name_scope); +} + +template +void +DataModifier:: +get_vector (vector & vec, const string & name) const +{ + session_get_vector(vec, session, name, name_scope); +} + +void +DataModifier:: +run_model (vector & dforce, + vector & dvirial, + Session * session, + const std::vector> & input_tensors, + const NNPAtomMap &nnpmap, + const int nghost) +{ + unsigned nloc = nnpmap.get_type().size(); + unsigned nall = nloc + nghost; + if (nloc == 0) { + dforce.clear(); + dvirial.clear(); + return; + } + + std::vector output_tensors; + checkStatus (session->Run(input_tensors, + {"o_dm_force", "o_dm_virial", "o_dm_av"}, + {}, + &output_tensors)); + int cc = 0; + Tensor output_f = output_tensors[cc++]; + Tensor output_v = output_tensors[cc++]; + Tensor output_av = output_tensors[cc++]; + assert (output_f.dims() == 2), "dim of output tensor should be 2"; + assert (output_v.dims() == 2), "dim of output tensor should be 2"; + assert (output_av.dims() == 2), "dim of output tensor should be 2"; + int nframes = output_f.dim_size(0); + int natoms = output_f.dim_size(1) / 3; + assert (output_f.dim_size(0) == 1), "nframes should match"; + assert (natoms == nall), "natoms should be nall"; + assert (output_v.dim_size(0) == nframes), "nframes should match"; + assert (output_v.dim_size(1) == 9), "dof of virial should be 9"; + assert (output_av.dim_size(0) == nframes), "nframes should match"; + assert (output_av.dim_size(1) == natoms * 9), "dof of atom virial should be 9 * natoms"; + + auto of = output_f.flat (); + auto ov = output_v.flat (); + + dforce.resize(nall*3); + dvirial.resize(9); + for (int ii = 0; ii < nall * 3; ++ii){ + dforce[ii] = of(ii); + } + for (int ii = 0; ii < 9; ++ii){ + dvirial[ii] = ov(ii); + } +} + + + +void +DataModifier:: +compute (vector & dfcorr_, + vector & dvcorr_, + const vector & dcoord_, + const vector & datype_, + const vector & dbox, + const vector> & pairs, + const vector & delef_, + const int nghost, + const LammpsNeighborList & lmp_list) +{ + // firstly do selection + int nall = datype_.size(); + int nloc = nall - nghost; + int nghost_real; + vector real_fwd_map, real_bkw_map; + select_real_atoms(real_fwd_map, real_bkw_map, nghost_real, dcoord_, datype_, nghost, ntypes); + int nall_real = real_bkw_map.size(); + int nloc_real = nall_real - nghost_real; + // resize to nall_real + vector dcoord_real; + vector delef_real; + vector datype_real; + dcoord_real.resize(nall_real * 3); + delef_real.resize(nall_real * 3); + datype_real.resize(nall_real); + // fwd map + select_map(dcoord_real, dcoord_, real_fwd_map, 3); + select_map(delef_real, delef_, real_fwd_map, 3); + select_map(datype_real, datype_, real_fwd_map, 1); + // internal nlist + InternalNeighborList nlist_; + convert_nlist_lmp_internal(nlist_, lmp_list); + shuffle_nlist_exclude_empty(nlist_, real_fwd_map); + // sort atoms + NNPAtomMap nnpmap (datype_real.begin(), datype_real.begin() + nloc_real); + assert (nloc_real == nnpmap.get_type().size()); + const vector & sort_fwd_map(nnpmap.get_fwd_map()); + const vector & sort_bkw_map(nnpmap.get_bkw_map()); + // shuffle nlist + InternalNeighborList nlist(nlist_); + shuffle_nlist (nlist, nnpmap); + // make input tensors + std::vector> input_tensors; + int ret = session_input_tensors (input_tensors, dcoord_real, ntypes, datype_real, dbox, nlist, vector(), vector(), nnpmap, nghost_real, name_scope); + assert (nloc_real == ret); + // make bond idx map + vector bd_idx(nall, -1); + for (int ii = 0; ii < pairs.size(); ++ii){ + bd_idx[pairs[ii].first] = pairs[ii].second; + } + // make extf by bond idx map + vector dtype_sort_loc = nnpmap.get_type(); + vector dextf; + for(int ii = 0; ii < dtype_sort_loc.size(); ++ii){ + if (lower_bound(sel_type.begin(), sel_type.end(), dtype_sort_loc[ii]) != sel_type.end()){ + // selected atom + int first_idx = real_bkw_map[sort_bkw_map[ii]]; + int second_idx = bd_idx[first_idx]; + assert(second_idx >= 0); + dextf.push_back(delef_[second_idx*3+0]); + dextf.push_back(delef_[second_idx*3+1]); + dextf.push_back(delef_[second_idx*3+2]); + } + } + // dextf should be loc and virtual + assert(dextf.size() == (nloc - nloc_real)*3); + // make tensor for extf + int nframes = 1; + TensorShape extf_shape ; + extf_shape.AddDim (nframes); + extf_shape.AddDim (dextf.size()); +#ifdef HIGH_PREC + Tensor extf_tensor (DT_DOUBLE, extf_shape); +#else + Tensor extf_tensor (DT_FLOAT, extf_shape); +#endif + auto extf = extf_tensor.matrix (); + for (int ii = 0; ii < nframes; ++ii){ + for (int jj = 0; jj < extf.size(); ++jj){ + extf(ii,jj) = dextf[jj]; + } + } + // append extf to input tensor + input_tensors.push_back({"t_ef", extf_tensor}); + // run model + vector dfcorr, dvcorr; + run_model (dfcorr, dvcorr, session, input_tensors, nnpmap, nghost_real); + assert(dfcorr.size() == nall_real * 3); + // back map force + vector dfcorr_1 = dfcorr; + nnpmap.backward (dfcorr_1.begin(), dfcorr.begin(), 3); + assert(dfcorr_1.size() == nall_real * 3); + // resize to all and clear + vector dfcorr_2(nall*3); + fill(dfcorr_2.begin(), dfcorr_2.end(), 0.0); + // back map to original position + for (int ii = 0; ii < nall_real; ++ii){ + for (int dd = 0; dd < 3; ++dd){ + dfcorr_2[real_bkw_map[ii]*3+dd] += dfcorr_1[ii*3+dd]; + } + } + // self correction of bonded force + for (int ii = 0; ii < pairs.size(); ++ii){ + for (int dd = 0; dd < 3; ++dd){ + dfcorr_2[pairs[ii].first*3+dd] += delef_[pairs[ii].second*3+dd]; + } + } + // add ele contrinution + dfcorr_ = dfcorr_2; + // for (int ii = 0; ii < nloc; ++ii){ + // for (int dd = 0; dd < 3; ++dd){ + // dfcorr_[ii*3+dd] += delef_[ii*3+dd]; + // } + // } + for (int ii = 0; ii < real_bkw_map.size(); ++ii){ + int oii = real_bkw_map[ii]; + for (int dd = 0; dd < 3; ++dd){ + dfcorr_[oii*3+dd] += delef_[oii*3+dd]; + } + } + dvcorr_ = dvcorr; +} diff --git a/source/lib/src/DeepTensor.cc b/source/lib/src/DeepTensor.cc index ea0a7579a8..4e6172a25f 100644 --- a/source/lib/src/DeepTensor.cc +++ b/source/lib/src/DeepTensor.cc @@ -30,7 +30,7 @@ init (const string & model, const int & gpu_rank) ntypes = get_scalar("descrpt_attr/ntypes"); model_type = get_scalar("model_attr/model_type"); odim = get_scalar("model_attr/output_dim"); - sel_type = get_vector("model_attr/sel_type"); + get_vector(sel_type, "model_attr/sel_type"); inited = true; } @@ -43,11 +43,11 @@ get_scalar (const string & name) const } template -vector +void DeepTensor:: -get_vector (const string & name) const +get_vector (vector & vec, const string & name) const { - return session_get_vector(session, name); + session_get_vector(vec, session, name); } void diff --git a/source/lib/src/common.cc b/source/lib/src/common.cc index 708de71b5d..9d1f1f0ff7 100644 --- a/source/lib/src/common.cc +++ b/source/lib/src/common.cc @@ -127,6 +127,7 @@ shuffle_nlist_exclude_empty (InternalNeighborList & list, new_jrange.resize(new_ilist.size()+1); new_jrange[0] = 0; for(int ii = 0; ii < list.ilist.size(); ++ii){ + if (list.ilist[ii] < 0) continue; int js = list.jrange[ii]; int je = list.jrange[ii+1]; int cc = 0; From 06ea446aa9a39c1622b752437dcac3d406004ff0 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 22 Nov 2019 19:27:21 +0800 Subject: [PATCH 029/147] fix bug of over-boundary back map --- source/lib/src/DataModifier.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/lib/src/DataModifier.cc b/source/lib/src/DataModifier.cc index 09d370a915..8eb3dd26f9 100644 --- a/source/lib/src/DataModifier.cc +++ b/source/lib/src/DataModifier.cc @@ -224,7 +224,7 @@ compute (vector & dfcorr_, // dfcorr_[ii*3+dd] += delef_[ii*3+dd]; // } // } - for (int ii = 0; ii < real_bkw_map.size(); ++ii){ + for (int ii = 0; ii < nloc_real; ++ii){ int oii = real_bkw_map[ii]; for (int dd = 0; dd < 3; ++dd){ dfcorr_[oii*3+dd] += delef_[oii*3+dd]; From 98eef651005f861339297d30d138ec82a27e2d24 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 25 Nov 2019 14:51:48 +0800 Subject: [PATCH 030/147] handel the case of nloc_real == 0 --- source/lib/src/DataModifier.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/lib/src/DataModifier.cc b/source/lib/src/DataModifier.cc index 8eb3dd26f9..bf53e2a7c8 100644 --- a/source/lib/src/DataModifier.cc +++ b/source/lib/src/DataModifier.cc @@ -128,6 +128,13 @@ compute (vector & dfcorr_, select_real_atoms(real_fwd_map, real_bkw_map, nghost_real, dcoord_, datype_, nghost, ntypes); int nall_real = real_bkw_map.size(); int nloc_real = nall_real - nghost_real; + if (nloc_real == 0){ + dfcorr_.resize(nall * 3); + dvcorr_.resize(9); + fill(dfcorr_.begin(), dfcorr_.end(), 0.0); + fill(dvcorr_.begin(), dvcorr_.end(), 0.0); + return; + } // resize to nall_real vector dcoord_real; vector delef_real; From 68f740d8ff1ae6549b164e82f2e0f8cec14a03ad Mon Sep 17 00:00:00 2001 From: Han Wang Date: Tue, 26 Nov 2019 00:22:38 +0800 Subject: [PATCH 031/147] fix bug of excluding empty from nlist --- source/lib/src/common.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/lib/src/common.cc b/source/lib/src/common.cc index 9d1f1f0ff7..4c20869f1e 100644 --- a/source/lib/src/common.cc +++ b/source/lib/src/common.cc @@ -126,6 +126,7 @@ shuffle_nlist_exclude_empty (InternalNeighborList & list, } new_jrange.resize(new_ilist.size()+1); new_jrange[0] = 0; + int ci = 0; for(int ii = 0; ii < list.ilist.size(); ++ii){ if (list.ilist[ii] < 0) continue; int js = list.jrange[ii]; @@ -137,7 +138,8 @@ shuffle_nlist_exclude_empty (InternalNeighborList & list, cc++; } } - new_jrange[ii+1] = new_jrange[ii] + cc; + new_jrange[ci+1] = new_jrange[ci] + cc; + ci ++; } list.ilist = new_ilist; list.jrange = new_jrange; From c655b6e58637a34bd94e56ba46a61164868e485a Mon Sep 17 00:00:00 2001 From: Han Wang Date: Tue, 26 Nov 2019 13:03:00 +0800 Subject: [PATCH 032/147] pass name_scope at the interface of DeepTensor and DataModifier --- source/lib/include/DataModifier.h | 10 +++++++--- source/lib/include/DeepTensor.h | 11 ++++++++--- source/lib/include/common.h | 2 ++ source/lib/src/DataModifier.cc | 14 +++++++++----- source/lib/src/DeepTensor.cc | 21 +++++++++++++-------- source/lib/src/common.cc | 10 ++++++++++ 6 files changed, 49 insertions(+), 19 deletions(-) diff --git a/source/lib/include/DataModifier.h b/source/lib/include/DataModifier.h index bfa4f31fac..838b1463ec 100644 --- a/source/lib/include/DataModifier.h +++ b/source/lib/include/DataModifier.h @@ -5,10 +5,14 @@ class DataModifier { public: - DataModifier (); - DataModifier (const string & model, const int & gpu_rank = 0); + DataModifier(); + DataModifier(const string & model, + const int & gpu_rank = 0, + const string & name_scope = ""); ~DataModifier () {}; - void init (const string & model, const int & gpu_rank = 0); + void init (const string & model, + const int & gpu_rank = 0, + const string & name_scope = ""); void print_summary(const string &pre) const; public: void compute (vector & dfcorr_, diff --git a/source/lib/include/DeepTensor.h b/source/lib/include/DeepTensor.h index e0c0392692..bfc969d7eb 100644 --- a/source/lib/include/DeepTensor.h +++ b/source/lib/include/DeepTensor.h @@ -5,9 +5,13 @@ class DeepTensor { public: - DeepTensor (); - DeepTensor (const string & model, const int & gpu_rank = 0); - void init (const string & model, const int & gpu_rank = 0); + DeepTensor(); + DeepTensor(const string & model, + const int & gpu_rank = 0, + const string &name_scope = ""); + void init (const string & model, + const int & gpu_rank = 0, + const string &name_scope = ""); void print_summary(const string &pre) const; public: void compute (vector & value, @@ -27,6 +31,7 @@ class DeepTensor vector sel_types () const {assert(inited); return sel_type;}; private: Session* session; + string name_scope; int num_intra_nthreads, num_inter_nthreads; GraphDef graph_def; bool inited; diff --git a/source/lib/include/common.h b/source/lib/include/common.h index 837f4b0e49..2f8e4ba949 100644 --- a/source/lib/include/common.h +++ b/source/lib/include/common.h @@ -99,6 +99,8 @@ get_env_nthreads(int & num_intra_nthreads, void checkStatus(const tensorflow::Status& status); +string name_prefix(const string & name_scope); + template VT session_get_scalar(Session* session, const string name, const string scope = ""); diff --git a/source/lib/src/DataModifier.cc b/source/lib/src/DataModifier.cc index bf53e2a7c8..ff15486281 100644 --- a/source/lib/src/DataModifier.cc +++ b/source/lib/src/DataModifier.cc @@ -4,12 +4,13 @@ DataModifier:: DataModifier() : inited (false) { - name_scope = "load"; } DataModifier:: -DataModifier(const string & model, const int & gpu_rank) - : inited (false) +DataModifier(const string & model, + const int & gpu_rank, + const string &name_scope_) + : inited (false), name_scope(name_scope_) { get_env_nthreads(num_intra_nthreads, num_inter_nthreads); init(model, gpu_rank); @@ -17,9 +18,12 @@ DataModifier(const string & model, const int & gpu_rank) void DataModifier:: -init (const string & model, const int & gpu_rank) -{ +init (const string & model, + const int & gpu_rank, + const string &name_scope_) +{ assert (!inited); + name_scope = name_scope_; SessionOptions options; options.config.set_inter_op_parallelism_threads(num_inter_nthreads); options.config.set_intra_op_parallelism_threads(num_intra_nthreads); diff --git a/source/lib/src/DeepTensor.cc b/source/lib/src/DeepTensor.cc index 4e6172a25f..bd3a0ea138 100644 --- a/source/lib/src/DeepTensor.cc +++ b/source/lib/src/DeepTensor.cc @@ -7,8 +7,10 @@ DeepTensor() } DeepTensor:: -DeepTensor(const string & model, const int & gpu_rank) - : inited (false) +DeepTensor(const string & model, + const int & gpu_rank, + const string &name_scope_) + : inited (false), name_scope(name_scope_) { get_env_nthreads(num_intra_nthreads, num_inter_nthreads); init(model, gpu_rank); @@ -16,9 +18,12 @@ DeepTensor(const string & model, const int & gpu_rank) void DeepTensor:: -init (const string & model, const int & gpu_rank) +init (const string & model, + const int & gpu_rank, + const string &name_scope_) { assert (!inited); + name_scope = name_scope_; SessionOptions options; options.config.set_inter_op_parallelism_threads(num_inter_nthreads); options.config.set_intra_op_parallelism_threads(num_intra_nthreads); @@ -39,7 +44,7 @@ VT DeepTensor:: get_scalar (const string & name) const { - return session_get_scalar(session, name); + return session_get_scalar(session, name, name_scope); } template @@ -47,7 +52,7 @@ void DeepTensor:: get_vector (vector & vec, const string & name) const { - session_get_vector(vec, session, name); + session_get_vector(vec, session, name, name_scope); } void @@ -68,7 +73,7 @@ run_model (vector & d_tensor_, std::vector output_tensors; checkStatus (session->Run(input_tensors, - {"o_" + model_type}, + {name_prefix(name_scope) + "o_" + model_type}, {}, &output_tensors)); @@ -148,7 +153,7 @@ compute_inner (vector & dtensor_, assert (nloc == nnpmap.get_type().size()); std::vector> input_tensors; - int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, vector(), vector(), nnpmap, nghost); + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, vector(), vector(), nnpmap, nghost, name_scope); assert (ret == nloc); run_model (dtensor_, session, input_tensors, nnpmap, nghost); @@ -172,7 +177,7 @@ compute_inner (vector & dtensor_, shuffle_nlist (nlist, nnpmap); std::vector> input_tensors; - int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, vector(), vector(), nnpmap, nghost); + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, vector(), vector(), nnpmap, nghost, name_scope); assert (nloc == ret); run_model (dtensor_, session, input_tensors, nnpmap, nghost); diff --git a/source/lib/src/common.cc b/source/lib/src/common.cc index 4c20869f1e..97d3c7fa9a 100644 --- a/source/lib/src/common.cc +++ b/source/lib/src/common.cc @@ -176,6 +176,16 @@ get_env_nthreads(int & num_intra_nthreads, } } +string +name_prefix(const string & scope) +{ + string prefix = ""; + if (scope != ""){ + prefix = scope + "/"; + } + return prefix; +} + int session_input_tensors (std::vector> & input_tensors, const vector & dcoord_, From 2a47c3ee5df356cea872515935098f1fd14e83d0 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 2 Dec 2019 21:05:37 +0800 Subject: [PATCH 033/147] fix bug of make_default_mesh --- source/train/DeepEval.py | 3 +-- source/train/DeepPot.py | 3 +-- source/train/common.py | 30 +++++++++++++++++++----------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/source/train/DeepEval.py b/source/train/DeepEval.py index e1156eefa7..ba383f245f 100644 --- a/source/train/DeepEval.py +++ b/source/train/DeepEval.py @@ -170,7 +170,6 @@ def eval(self, # make natoms_vec and default_mesh natoms_vec = self.make_natoms_vec(atom_types) assert(natoms_vec[0] == natoms) - default_mesh = make_default_mesh(cells) # evaluate tensor = [] @@ -181,7 +180,7 @@ def eval(self, for ii in range(nframes) : feed_dict_test[self.t_coord] = np.reshape(coords[ii:ii+1, :], [-1]) feed_dict_test[self.t_box ] = np.reshape(cells [ii:ii+1, :], [-1]) - feed_dict_test[self.t_mesh ] = default_mesh[ii] + feed_dict_test[self.t_mesh ] = make_default_mesh(cells[ii:ii+1, :]) v_out = self.sess.run (t_out, feed_dict = feed_dict_test) tensor.append(v_out[0]) diff --git a/source/train/DeepPot.py b/source/train/DeepPot.py index 92c931377a..9430216c02 100644 --- a/source/train/DeepPot.py +++ b/source/train/DeepPot.py @@ -112,7 +112,6 @@ def eval(self, # make natoms_vec and default_mesh natoms_vec = self.make_natoms_vec(atom_types) assert(natoms_vec[0] == natoms) - default_mesh = make_default_mesh(cells) # evaluate energy = [] @@ -122,7 +121,6 @@ def eval(self, av = [] feed_dict_test = {} feed_dict_test[self.t_natoms] = natoms_vec - feed_dict_test[self.t_mesh ] = default_mesh[0] feed_dict_test[self.t_type ] = atom_types t_out = [self.t_energy, self.t_force, @@ -133,6 +131,7 @@ def eval(self, for ii in range(nframes) : feed_dict_test[self.t_coord] = np.reshape(coords[ii:ii+1, :], [-1]) feed_dict_test[self.t_box ] = np.reshape(cells [ii:ii+1, :], [-1]) + feed_dict_test[self.t_mesh ] = make_default_mesh(cells[ii:ii+1, :]) if self.has_fparam: feed_dict_test[self.t_fparam] = np.reshape(fparam[ii:ii+1, :], [-1]) if self.has_aparam: diff --git a/source/train/common.py b/source/train/common.py index c322f0e9c4..7eb6e19381 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -27,18 +27,26 @@ def select_idx_map(atom_type, return idx_map -def make_default_mesh(test_box, cell_size = 3) : +def make_default_mesh(test_box, cell_size = 3.0) : + # nframes = test_box.shape[0] + # default_mesh = np.zeros([nframes, 6], dtype = np.int32) + # for ff in range(nframes): + # ncell = np.ones (3, dtype=np.int32) + # for ii in range(3) : + # ncell[ii] = int ( np.linalg.norm(test_box[ff][ii]) / cell_size ) + # if (ncell[ii] < 2) : ncell[ii] = 2 + # default_mesh[ff][3] = ncell[0] + # default_mesh[ff][4] = ncell[1] + # default_mesh[ff][5] = ncell[2] + # return default_mesh nframes = test_box.shape[0] - default_mesh = np.zeros([nframes, 6], dtype = np.int32) - for ff in range(nframes): - ncell = np.ones (3, dtype=np.int32) - for ii in range(3) : - ncell[ii] = int ( np.linalg.norm(test_box[ff][ii]) / cell_size ) - if (ncell[ii] < 2) : ncell[ii] = 2 - default_mesh[ff][3] = ncell[0] - default_mesh[ff][4] = ncell[1] - default_mesh[ff][5] = ncell[2] - return default_mesh + lboxv = np.linalg.norm(test_box.reshape([-1, 3, 3]), axis = 2) + avg_lboxv = np.average(lboxv, axis = 0) + ncell = (avg_lboxv / cell_size).astype(np.int32) + ncell[ncell < 2] = 2 + default_mesh = np.zeros (6, dtype = np.int32) + default_mesh[3:6] = ncell + return default_mesh class ClassArg () : From 33f9e13380f85623266197d8728b492dd175c5df Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 2 Dec 2019 22:32:55 +0800 Subject: [PATCH 034/147] simplify atype for eval_modify. sort in eval_modify --- source/tests/test_data_modifier.py | 3 ++- source/train/DataModifier.py | 17 ++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/source/tests/test_data_modifier.py b/source/tests/test_data_modifier.py index dd41a27863..cdf9828a4d 100644 --- a/source/tests/test_data_modifier.py +++ b/source/tests/test_data_modifier.py @@ -99,7 +99,7 @@ def _test_fv (self): 0.25) data = Data() coord, box, atype = data.get_data() - + atype = atype[0] ve, vf, vv = dcm.eval_modify(coord, box, atype) hh = global_default_fv_hh @@ -109,6 +109,7 @@ def _test_fv (self): nframes = coord.shape[0] ndof = coord.shape[1] natoms = ndof // 3 + vf = np.reshape(vf, [nframes, -1]) for ii in range(ndof): coordp = np.copy(coord) coordm = np.copy(coord) diff --git a/source/train/DataModifier.py b/source/train/DataModifier.py index b55a0af53a..4adf3928c1 100644 --- a/source/train/DataModifier.py +++ b/source/train/DataModifier.py @@ -164,16 +164,17 @@ def _slice_descrpt_deriv(self, deriv): def eval_modify(self, coord, box, atype, eval_fv = True): + coord, atype, imap = self.sort_input(coord, atype) natoms = coord.shape[1] // 3 nframes = coord.shape[0] box = np.reshape(box, [nframes, 9]) - atype = np.reshape(atype, [nframes, natoms]) - sel_idx_map = select_idx_map(atype[0], self.sel_type) + atype = np.reshape(atype, [natoms]) + sel_idx_map = select_idx_map(atype, self.sel_type) nsel = len(sel_idx_map) # setup charge charge = np.zeros([natoms]) for ii in range(natoms): - charge[ii] = self.sys_charge_map[atype[0][ii]] + charge[ii] = self.sys_charge_map[atype[ii]] charge = np.tile(charge, [nframes, 1]) # add wfcc @@ -205,7 +206,7 @@ def eval_modify(self, coord, box, atype, eval_fv = True): corr_v = [] corr_av = [] for ii in range(0,nframes,batch_size): - f, v, av = self.eval_fv(coord[ii:ii+batch_size], box[ii:ii+batch_size], atype[0], ext_f[ii:ii+batch_size]) + f, v, av = self.eval_fv(coord[ii:ii+batch_size], box[ii:ii+batch_size], atype, ext_f[ii:ii+batch_size]) corr_f.append(f) corr_v.append(v) corr_av.append(av) @@ -216,6 +217,7 @@ def eval_modify(self, coord, box, atype, eval_fv = True): for ii in range(nsel): orig_idx = sel_idx_map[ii] tot_f[:,orig_idx*3:orig_idx*3+3] += ext_f[:,ii*3:ii*3+3] + tot_f = self.reverse_map(np.reshape(tot_f, [nframes,-1,3]), imap) # compute v dipole3 = np.reshape(dipole, [nframes, nsel, 3]) ext_f3 = np.reshape(ext_f, [nframes, nsel, 3]) @@ -268,20 +270,20 @@ def _extend_system(self, coord, box, atype, charge): natoms = coord.shape[1] // 3 nframes = coord.shape[0] # sel atoms and setup ref coord - sel_idx_map = select_idx_map(atype[0], self.sel_type) + sel_idx_map = select_idx_map(atype, self.sel_type) nsel = len(sel_idx_map) coord3 = coord.reshape([nframes, natoms, 3]) ref_coord = coord3[:,sel_idx_map,:] ref_coord = np.reshape(ref_coord, [nframes, nsel * 3]) - dipole = self.eval(coord, box, atype[0]) + dipole = self.eval(coord, box, atype) dipole = np.reshape(dipole, [nframes, nsel * 3]) wfcc_coord = ref_coord + dipole # wfcc_coord = dipole wfcc_charge = np.zeros([nsel]) for ii in range(nsel): - orig_idx = self.sel_type.index(atype[0][sel_idx_map[ii]]) + orig_idx = self.sel_type.index(atype[sel_idx_map[ii]]) wfcc_charge[ii] = self.model_charge_map[orig_idx] wfcc_charge = np.tile(wfcc_charge, [nframes, 1]) @@ -303,6 +305,7 @@ def modify(self, coord = data['coord'][:get_nframes,:] box = data['box'][:get_nframes,:] atype = data['type'][:get_nframes,:] + atype = atype[0] nframes = coord.shape[0] tot_e, tot_f, tot_v = self.eval_modify(coord, box, atype) From 76a4f855519bd2f339f81aecfb67c2348854c1d8 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Tue, 3 Dec 2019 17:33:45 +0800 Subject: [PATCH 035/147] fix bug of DataModifier: increase start index of descriptor slicing. add unit test for shuffled data modifier --- source/tests/test_data_modifier_shuffle.py | 209 +++++++++++++++++++++ source/train/DataModifier.py | 4 +- 2 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 source/tests/test_data_modifier_shuffle.py diff --git a/source/tests/test_data_modifier_shuffle.py b/source/tests/test_data_modifier_shuffle.py new file mode 100644 index 0000000000..d70bd94b3b --- /dev/null +++ b/source/tests/test_data_modifier_shuffle.py @@ -0,0 +1,209 @@ +import os,sys,platform,json +import numpy as np +import unittest +import dpdata +from deepmd.env import tf + +from deepmd.common import j_must_have, data_requirement +from deepmd.RunOptions import RunOptions +from deepmd.Trainer import NNPTrainer +from deepmd.DataSystem import DeepmdDataSystem +from deepmd.RunOptions import global_tf_float_precision +from deepmd.RunOptions import global_np_float_precision +from deepmd.RunOptions import global_ener_float_precision +from deepmd.EwaldRecp import EwaldRecp +from deepmd.DataModifier import DipoleChargeModifier +from deepmd.DeepDipole import DeepDipole + +from common import Data + +if global_np_float_precision == np.float32 : + global_default_fv_hh = 1e-2 + global_default_dw_hh = 1e-2 + global_default_places = 3 +else : + global_default_fv_hh = 1e-6 + global_default_dw_hh = 1e-4 + global_default_places = 5 + +modifier_datapath = 'data_modifier' + +class Args() : + # INPUT = os.path.join(modifier_datapath, 'dipole.json') + restart = None + init_model = None + inter_threads = 0 + +class TestDataModifier (unittest.TestCase) : + + def setUp(self): + # with tf.variable_scope('load', reuse = False) : + tf.reset_default_graph() + self._setUp() + + def tearDown(self): + tf.reset_default_graph() + + def _setUp(self): + args = Args() + run_opt = RunOptions(args, False) + jdata = self._setUp_jdata() + self._setUp_data() + + # init model + model = NNPTrainer (jdata, run_opt = run_opt) + rcut = model.model.get_rcut() + + # init data system + systems = j_must_have(jdata['training'], 'systems') + set_pfx = j_must_have(jdata['training'], 'set_prefix') + batch_size = j_must_have(jdata['training'], 'batch_size') + test_size = j_must_have(jdata['training'], 'numb_test') + data = DeepmdDataSystem(systems, + batch_size, + test_size, + rcut, + set_prefix=set_pfx, + run_opt=run_opt) + data.add_dict(data_requirement) + + # clear the default graph + tf.reset_default_graph() + + # build the model with stats from the first system + model.build (data) + + # freeze the graph + with tf.Session() as sess: + init_op = tf.global_variables_initializer() + sess.run(init_op) + graph = tf.get_default_graph() + input_graph_def = graph.as_graph_def() + nodes = "o_dipole,o_rmat,o_rmat_deriv,o_nlist,o_rij,descrpt_attr/rcut,descrpt_attr/ntypes,descrpt_attr/sel,descrpt_attr/ndescrpt,model_attr/tmap,model_attr/sel_type,model_attr/model_type" + output_graph_def = tf.graph_util.convert_variables_to_constants( + sess, + input_graph_def, + nodes.split(",") + ) + output_graph = os.path.join(modifier_datapath, 'dipole.pb') + with tf.gfile.GFile(output_graph, "wb") as f: + f.write(output_graph_def.SerializeToString()) + + def _setUp_data(self): + jdata = self._setUp_jdata() + # sys0 + self.atom_types0 = np.array([0, 3, 2, 1, 3, 4, 1, 4], dtype = int) + self.natoms = len(self.atom_types0) + self.nframes = 1 + scale = 10.0 + self.sel_type = jdata['model']['fitting_net']['dipole_type'] + self.nsel = 0 + for ii in self.sel_type: + self.nsel += np.sum(self.atom_types0 == ii) + self.coords0 = np.random.random([self.nframes, self.natoms * 3]) * scale + self.dipoles0 = np.random.random([self.nframes, self.nsel * 3]) + self.box0 = np.reshape(np.eye(3) * scale, [-1, 9]) + self.box0 = np.tile(self.box0, [self.nframes, 1]) + self._write_sys_data('data_modifier/sys_test_0', + self.atom_types0, self.coords0, self.dipoles0, self.box0) + # sys1 + self.idx_map = np.array([6, 7, 1, 0, 5, 2, 4, 3], dtype = int) + self.sel_idx_map = np.array([3, 0, 2, 1], dtype = int) + self.atom_types1 = self.atom_types0[self.idx_map] + self.coords1 = np.reshape(self.coords0, [self.nframes, -1, 3]) + self.coords1 = self.coords1[:,self.idx_map,:] + self.coords1 = np.reshape(self.coords1, [self.nframes, self.natoms*3]) + self.dipoles1 = self.dipoles0[:,self.sel_idx_map] + self.box1 = self.box0 + + def _write_sys_data(self, dirname, atom_types, coords, dipoles, box): + os.makedirs(dirname, exist_ok = True) + os.makedirs(dirname+'/set.0', exist_ok = True) + np.savetxt(os.path.join(dirname, 'type.raw'), atom_types, fmt = '%d') + np.save(os.path.join(dirname, 'set.0', 'coord.npy'), coords) + np.save(os.path.join(dirname, 'set.0', 'dipole.npy'), dipoles) + np.save(os.path.join(dirname, 'set.0', 'box.npy'), box) + + def _setUp_jdata(self): + aa = {"a":[1,2,3]} + jdata = { + "model":{ + "type_map": ["A", "B", "C", "D", "E"], + "descriptor" :{ + "type": "se_a", + "sel": [50, 50, 50, 50, 50], + "rcut_smth": 3.80, + "rcut": 4.00, + "neuron": [2, 4], + "resnet_dt": False, + "axis_neuron": 4, + "seed": 1, + }, + "fitting_net": { + "type": "dipole", + "dipole_type": [1, 3], + "neuron": [10], + "resnet_dt": True, + "seed": 1, + }, + }, + "learning_rate" :{ + "type": "exp", + "start_lr": 0.01, + "decay_steps": 5000, + "decay_rate": 0.95, + }, + "training": { + "systems": ["data_modifier/sys_test_0"], + "set_prefix": "set", + "stop_batch": 1000000, + "batch_size": 1, + "numb_test": 2, + }, + } + return jdata + + + def test_z_dipole(self): + dd = DeepDipole(os.path.join(modifier_datapath, "dipole.pb")) + + dv0 = dd.eval(self.coords0, self.box0, self.atom_types0) + dv1 = dd.eval(self.coords1, self.box1, self.atom_types1) + + dv01 = dv0.reshape([self.nframes, -1, 3]) + dv01 = dv01[:,self.sel_idx_map, :] + dv01 = dv01.reshape([self.nframes, -1]) + dv1 = dv1.reshape([self.nframes, -1]) + + for ii in range(self.nframes): + for jj in range(self.nsel): + self.assertAlmostEqual( + dv01[ii][jj], dv1[ii][jj], + msg = "dipole [%d,%d] dose not match" % (ii, jj)) + + + def test_modify(self): + dcm = DipoleChargeModifier(os.path.join(modifier_datapath, "dipole.pb"), + [-1, -3], + [1, 1, 1, 1, 1], + 1, + 0.25) + ve0, vf0, vv0 = dcm.eval_modify(self.coords0, self.box0, self.atom_types0) + ve1, vf1, vv1 = dcm.eval_modify(self.coords1, self.box1, self.atom_types1) + vf01 = vf0[:,self.idx_map, :] + + for ii in range(self.nframes): + self.assertAlmostEqual(ve0[ii], ve1[ii], + msg = 'energy %d should match' % ii) + for ii in range(self.nframes): + for jj in range(9): + self.assertAlmostEqual(vv0[ii][jj], vv1[ii][jj], + msg = 'virial [%d,%d] should match' % (ii,jj)) + for ii in range(self.nframes): + for jj in range(self.natoms): + for dd in range(3): + self.assertAlmostEqual( + vf01[ii][jj][dd], vf1[ii][jj][dd], + msg = "force [%d,%d,%d] dose not match" % (ii,jj,dd)) + + diff --git a/source/train/DataModifier.py b/source/train/DataModifier.py index 4adf3928c1..4fa57d9d86 100644 --- a/source/train/DataModifier.py +++ b/source/train/DataModifier.py @@ -152,14 +152,14 @@ def _enrich(self, dipole, dof = 3): def _slice_descrpt_deriv(self, deriv): coll = [] - start_idx = 0 + start_idx = 0 for type_i in range(self.ntypes): if type_i in self.sel_type: di = tf.slice(deriv, [ 0, start_idx * self.ndescrpt], [-1, self.t_natoms[2+type_i] * self.ndescrpt]) coll.append(di) - start_idx += self.t_natoms[2+type_i] + start_idx += self.t_natoms[2+type_i] return tf.concat(coll, axis = 1) From 9ec7cf49c5a8c3267a7967cd33635af74af105b5 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 6 Dec 2019 12:23:45 +0800 Subject: [PATCH 036/147] fix bug of binary search. add source files pppm_dplr, fix_dplr --- source/lib/include/DeepTensor.h | 2 +- source/lib/src/DataModifier.cc | 2 +- source/lib/src/common.cc | 3 +- source/lmp/fix_dplr.cpp | 470 ++++++++++++++++++++++++++++++++ source/lmp/fix_dplr.h | 53 ++++ source/lmp/pppm_dplr.cpp | 401 +++++++++++++++++++++++++++ source/lmp/pppm_dplr.h | 54 ++++ 7 files changed, 981 insertions(+), 4 deletions(-) create mode 100644 source/lmp/fix_dplr.cpp create mode 100644 source/lmp/fix_dplr.h create mode 100644 source/lmp/pppm_dplr.cpp create mode 100644 source/lmp/pppm_dplr.h diff --git a/source/lib/include/DeepTensor.h b/source/lib/include/DeepTensor.h index bfc969d7eb..867cff37cc 100644 --- a/source/lib/include/DeepTensor.h +++ b/source/lib/include/DeepTensor.h @@ -28,7 +28,7 @@ class DeepTensor VALUETYPE cutoff () const {assert(inited); return rcut;}; int numb_types () const {assert(inited); return ntypes;}; int output_dim () const {assert(inited); return odim;}; - vector sel_types () const {assert(inited); return sel_type;}; + const vector & sel_types () const {assert(inited); return sel_type;}; private: Session* session; string name_scope; diff --git a/source/lib/src/DataModifier.cc b/source/lib/src/DataModifier.cc index ff15486281..65b3f85dd4 100644 --- a/source/lib/src/DataModifier.cc +++ b/source/lib/src/DataModifier.cc @@ -175,7 +175,7 @@ compute (vector & dfcorr_, vector dtype_sort_loc = nnpmap.get_type(); vector dextf; for(int ii = 0; ii < dtype_sort_loc.size(); ++ii){ - if (lower_bound(sel_type.begin(), sel_type.end(), dtype_sort_loc[ii]) != sel_type.end()){ + if (binary_search(sel_type.begin(), sel_type.end(), dtype_sort_loc[ii])){ // selected atom int first_idx = real_bkw_map[sort_bkw_map[ii]]; int second_idx = bd_idx[first_idx]; diff --git a/source/lib/src/common.cc b/source/lib/src/common.cc index 97d3c7fa9a..2f739ea196 100644 --- a/source/lib/src/common.cc +++ b/source/lib/src/common.cc @@ -24,8 +24,7 @@ select_by_type(vector & fwd_map, for (int ii = 0; ii < nall; ++ii){ // exclude virtual sites // select the type with id < ntypes - if (lower_bound(sel_type.begin(), sel_type.end(), datype_[ii]) != - sel_type.end()){ + if (binary_search(sel_type.begin(), sel_type.end(), datype_[ii])){ bkw_map.push_back(ii); if (ii < nloc) { nloc_real += 1; diff --git a/source/lmp/fix_dplr.cpp b/source/lmp/fix_dplr.cpp new file mode 100644 index 0000000000..481da66840 --- /dev/null +++ b/source/lmp/fix_dplr.cpp @@ -0,0 +1,470 @@ +#include +#include +#include +#include "atom.h" +#include "domain.h" +#include "comm.h" +#include "force.h" +#include "update.h" +#include "error.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "fix.h" +#include "fix_dplr.h" +#include "pppm_dplr.h" + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace std; + +static bool +is_key (const string& input) +{ + vector keys ; + keys.push_back("model"); + keys.push_back("type_associate"); + keys.push_back("bond_type"); + for (int ii = 0; ii < keys.size(); ++ii){ + if (input == keys[ii]) { + return true; + } + } + return false; +} + + +FixDPLR::FixDPLR(LAMMPS *lmp, int narg, char **arg) + :Fix(lmp, narg, arg) +{ + virial_flag = 1; + + if (strcmp(update->unit_style,"metal") != 0) { + error->all(FLERR,"Pair deepmd requires metal unit, please set it by \"units metal\""); + } + + int iarg = 3; + vector map_vec; + bond_type.clear(); + while (iarg < narg) { + if (! is_key(arg[iarg])) { + error->all(FLERR,"Illegal pair_style command\nwrong number of parameters\n"); + } + if (string(arg[iarg]) == string("model")) { + if (iarg+1 > narg) error->all(FLERR,"Illegal fix adapt command"); + model = string(arg[iarg+1]); + iarg += 2; + } + if (string(arg[iarg]) == string("type_associate")) { + int iend = iarg+1; + while (iend < narg && (! is_key(arg[iend]) )) { + map_vec.push_back(atoi(arg[iend])-1); + iend ++; + } + iarg = iend; + } + if (string(arg[iarg]) == string("bond_type")) { + int iend = iarg+1; + while (iend < narg && (! is_key(arg[iend]) )) { + bond_type.push_back(atoi(arg[iend])-1); + iend ++; + } + sort(bond_type.begin(), bond_type.end()); + iarg = iend; + } + else { + break; + } + } + assert(map_vec.size() % 2 == 0), "number of ints provided by type_associate should be even"; + for (int ii = 0; ii < map_vec.size()/2; ++ii){ + type_asso[map_vec[ii*2+0]] = map_vec[ii*2+1]; + bk_type_asso[map_vec[ii*2+1]] = map_vec[ii*2+0]; + } + + // dpt.init(model); + // dtm.init("frozen_model.pb"); + dpt.init(model, 0, "load"); + dtm.init(model, 0, "load"); + + sel_type = dpt.sel_types(); + sort(sel_type.begin(), sel_type.end()); + dpl_type.clear(); + for (int ii = 0; ii < sel_type.size(); ++ii){ + dpl_type.push_back(type_asso[sel_type[ii]]); + } + + pair_nnp = (PairNNP *) force->pair_match("deepmd",1); + if (!pair_nnp) { + error->all(FLERR,"pair_style deepmd should be set before this fix\n"); + } + + // set comm size needed by this fix + comm_reverse = 3; +} + +int FixDPLR::setmask() +{ + int mask = 0; + mask |= POST_INTEGRATE; + mask |= PRE_FORCE; + mask |= POST_FORCE; + return mask; +} + +void FixDPLR::init() +{ + // double **xx = atom->x; + // double **vv = atom->v; + // int nlocal = atom->nlocal; + // for (int ii = 0; ii < nlocal; ++ii){ + // cout << xx[ii][0] << " " + // << xx[ii][1] << " " + // << xx[ii][2] << " " + // << vv[ii][0] << " " + // << vv[ii][1] << " " + // << vv[ii][2] << " " + // << endl; + // } +} + +void FixDPLR::setup(int vflag) +{ + // if (strstr(update->integrate_style,"verlet")) + // post_force(vflag); + // else { + // error->all(FLERR, "respa is not supported by this fix"); + // } + if (vflag) { + v_setup(vflag); + } + else { + evflag = 0; + } +} + + +void +FixDPLR::get_valid_pairs(vector >& pairs) +{ + pairs.clear(); + + int nlocal = atom->nlocal; + int nghost = atom->nghost; + int nall = nlocal + nghost; + vector dtype (nall); + // get type + { + int *type = atom->type; + for (int ii = 0; ii < nall; ++ii){ + dtype[ii] = type[ii] - 1; + } + } + + int **bondlist = neighbor->bondlist; + int nbondlist = neighbor->nbondlist; + for (int ii = 0; ii < nbondlist; ++ii){ + int idx0=-1, idx1=-1; + int bd_type = bondlist[ii][2] - 1; + if ( ! binary_search(bond_type.begin(), bond_type.end(), bd_type) ){ + continue; + } + if (binary_search(sel_type.begin(), sel_type.end(), dtype[bondlist[ii][0]]) + && + binary_search(dpl_type.begin(), dpl_type.end(), dtype[bondlist[ii][1]]) + ){ + idx0 = bondlist[ii][0]; + idx1 = bondlist[ii][1]; + } + else if (binary_search(sel_type.begin(), sel_type.end(), dtype[bondlist[ii][1]]) + && + binary_search(dpl_type.begin(), dpl_type.end(), dtype[bondlist[ii][0]]) + ){ + idx0 = bondlist[ii][1]; + idx1 = bondlist[ii][0]; + } + else { + error->all(FLERR, "find a bonded pair the types of which are not associated"); + } + if ( ! (idx0 < nlocal && idx1 < nlocal) ){ + error->all(FLERR, "find a bonded pair that is not on the same processor, something should not happen"); + } + pairs.push_back(pair(idx0, idx1)); + } +} + +void FixDPLR::post_integrate() +{ + double **x = atom->x; + double **v = atom->v; + int *type = atom->type; + int nlocal = atom->nlocal; + int nghost = atom->nghost; + int nall = nlocal + nghost; + + vector > valid_pairs; + get_valid_pairs(valid_pairs); + + for (int ii = 0; ii < valid_pairs.size(); ++ii){ + int idx0 = valid_pairs[ii].first; + int idx1 = valid_pairs[ii].second; + for (int dd = 0; dd < 3; ++dd){ + x[idx1][dd] = x[idx0][dd] ; + v[idx1][dd] = v[idx0][dd] ; + // v[idx1][dd] = 0.0; + } + } +} + +void FixDPLR::pre_force(int vflag) +{ + double **x = atom->x; + int *type = atom->type; + int nlocal = atom->nlocal; + int nghost = atom->nghost; + int nall = nlocal + nghost; + + // if (eflag_atom) { + // error->all(FLERR,"atomic energy calculation is not supported by this fix\n"); + // } + + // declear inputs + vector dtype (nall); + vector dbox (9, 0) ; + vector dcoord (nall * 3, 0.); + // get type + for (int ii = 0; ii < nall; ++ii){ + dtype[ii] = type[ii] - 1; + } + // get box + dbox[0] = domain->h[0]; // xx + dbox[4] = domain->h[1]; // yy + dbox[8] = domain->h[2]; // zz + dbox[7] = domain->h[3]; // zy + dbox[6] = domain->h[4]; // zx + dbox[3] = domain->h[5]; // yx + // get coord + for (int ii = 0; ii < nall; ++ii){ + for (int dd = 0; dd < 3; ++dd){ + dcoord[ii*3+dd] = x[ii][dd] - domain->boxlo[dd]; + } + } + // get lammps nlist + NeighList * list = pair_nnp->list; + LammpsNeighborList lmp_list (list->inum, list->ilist, list->numneigh, list->firstneigh); + // declear output + vector tensor; + // compute + dpt.compute(tensor, dcoord, dtype, dbox, nghost, lmp_list); + // cout << "tensor of size " << tensor.size() << endl; + // cout << "nghost " << nghost << endl; + // cout << "nall " << dtype.size() << endl; + // cout << "nloc " << nlocal << endl; + // for (int ii = 0; ii < tensor.size(); ++ii){ + // if (ii%3 == 0){ + // cout << endl; + // } + // cout << tensor[ii] << "\t"; + // } + // cout << endl; + // for (int ii = 0; ii < nlocal * 3; ++ii){ + // if (ii%3 == 0){ + // cout << endl; + // } + // cout << dcoord[ii] << "\t"; + // } + // int max_type = 0; + // for (int ii = 0; ii < dtype.size(); ++ii){ + // if (dtype[ii] > max_type) { + // max_type = dtype[ii]; + // } + // } + + // selected type + vector dpl_type; + for (int ii = 0; ii < sel_type.size(); ++ii){ + dpl_type.push_back(type_asso[sel_type[ii]]); + } + vector sel_fwd, sel_bwd; + int sel_nghost; + select_by_type(sel_fwd, sel_bwd, sel_nghost, dcoord, dtype, nghost, sel_type); + int sel_nall = sel_bwd.size(); + int sel_nloc = sel_nall - sel_nghost; + vector sel_type(sel_bwd.size()); + select_map(sel_type, dtype, sel_fwd, 1); + + NNPAtomMap nnp_map(sel_type.begin(), sel_type.begin() + sel_nloc); + const vector & sort_fwd_map(nnp_map.get_fwd_map()); + + vector > valid_pairs; + get_valid_pairs(valid_pairs); + + int odim = dpt.output_dim(); + assert(odim == 3); + dipole_recd.resize(nall * 3); + fill(dipole_recd.begin(), dipole_recd.end(), 0.0); + for (int ii = 0; ii < valid_pairs.size(); ++ii){ + int idx0 = valid_pairs[ii].first; + int idx1 = valid_pairs[ii].second; + assert(idx0 < sel_fwd.size() && sel_fwd[idx0] < sort_fwd_map.size()); + int res_idx = sort_fwd_map[sel_fwd[idx0]]; + // int ret_idx = dpl_bwd[res_idx]; + for (int dd = 0; dd < 3; ++dd){ + x[idx1][dd] = x[idx0][dd] + tensor[res_idx * 3 + dd]; + // res_buff[idx1 * odim + dd] = tensor[res_idx * odim + dd]; + dipole_recd[idx0*3+dd] = tensor[res_idx * 3 + dd]; + } + } + // cout << "-------------------- fix/dplr: pre force " << endl; + // for (int ii = 0; ii < nlocal; ++ii){ + // cout << ii << " "; + // for (int dd = 0; dd < 3; ++dd){ + // cout << x[ii][dd] << " " ; + // } + // cout << endl; + // } +} + + +void FixDPLR::post_force(int vflag) +{ + if (vflag) { + v_setup(vflag); + } + else { + evflag = 0; + } + if (vflag_atom) { + error->all(FLERR,"atomic virial calculation is not supported by this fix\n"); + } + + PPPMDPLR * pppm_dplr = (PPPMDPLR*) force->kspace_match("pppm/dplr", 1); + if (!pppm_dplr) { + error->all(FLERR,"kspace_style pppm/dplr should be set before this fix\n"); + } + const vector & dfele_(pppm_dplr->get_fele()); + int nlocal = atom->nlocal; + int nghost = atom->nghost; + int nall = nlocal + nghost; + vector dcoord(nall*3, 0.0), dbox(9, 0.0), dfele(nlocal*3, 0.0); + vector dtype(nall, 0); + { + int *type = atom->type; + for (int ii = 0; ii < nall; ++ii){ + dtype[ii] = type[ii] - 1; + } + dbox[0] = domain->h[0]; // xx + dbox[4] = domain->h[1]; // yy + dbox[8] = domain->h[2]; // zz + dbox[7] = domain->h[3]; // zy + dbox[6] = domain->h[4]; // zx + dbox[3] = domain->h[5]; // yx + // get coord + double ** x = atom->x; + for (int ii = 0; ii < nall; ++ii){ + for (int dd = 0; dd < 3; ++dd){ + dcoord[ii*3+dd] = x[ii][dd] - domain->boxlo[dd]; + } + } + assert(dfele_.size() == nlocal * 3); + for (int ii = 0; ii < nlocal*3; ++ii){ + dfele[ii] = dfele_[ii]; + } + } + // lmp nlist + NeighList * list = pair_nnp->list; + LammpsNeighborList lmp_list (list->inum, list->ilist, list->numneigh, list->firstneigh); + // bonded pairs + vector > valid_pairs; + get_valid_pairs(valid_pairs); + // output vects + vector dfcorr, dvcorr; + // compute + dtm.compute(dfcorr, dvcorr, dcoord, dtype, dbox, valid_pairs, dfele, nghost, lmp_list); + assert(dfcorr.size() == dcoord.size()); + assert(dfcorr.size() == nall * 3); + // backward communication of fcorr + dfcorr_buff.resize(dfcorr.size()); + copy(dfcorr.begin(), dfcorr.end(), dfcorr_buff.begin()); + comm->reverse_comm_fix(this,3); + copy(dfcorr_buff.begin(), dfcorr_buff.end(), dfcorr.begin()); + // // check and print + // cout << "-------------------- fix/dplr: post force " << endl; + // cout << "dfcorr.size() " << dfcorr.size() << endl; + // cout << "dcoord.size() " << dcoord.size() << endl; + // for (int ii = 0; ii < nlocal; ++ii){ + // cout << ii << "\t x: "; + // for (int dd = 0; dd < 3; ++dd){ + // cout << dcoord[ii*3+dd] << " \t " ; + // } + // cout << ii << "\t f: "; + // for (int dd = 0; dd < 3; ++dd){ + // cout << dfcorr[ii*3+dd] << " \t " ; + // } + // cout << endl; + // } + // apply the force correction + double ** f = atom->f; + for (int ii = 0; ii < nlocal; ++ii){ + for(int dd = 0; dd < 3; ++dd){ + f[ii][dd] += dfcorr[ii*3+dd]; + } + } + // cout << "virial corr1 "; + // for (int ii = 0; ii < 9; ++ii){ + // cout << dvcorr[ii] << " " ; + // } + // cout << endl; + for (int ii = 0; ii < valid_pairs.size(); ++ii){ + int idx0 = valid_pairs[ii].first; + int idx1 = valid_pairs[ii].second; + for (int dd0 = 0; dd0 < 3; ++dd0){ + for (int dd1 = 0; dd1 < 3; ++dd1){ + dvcorr[dd0*3+dd1] -= dfele[idx1*3+dd0] * dipole_recd[idx0*3+dd1]; + } + } + } + // cout << "virial corr2 "; + // for (int ii = 0; ii < 9; ++ii){ + // cout << dvcorr[ii] << " " ; + // } + // cout << endl; + if (evflag){ + double vv[6] = {0.0}; + vv[0] += dvcorr[0]; + vv[1] += dvcorr[4]; + vv[2] += dvcorr[8]; + vv[3] += dvcorr[3]; + vv[4] += dvcorr[6]; + vv[5] += dvcorr[7]; + v_tally(0, vv); + } +} + + +int FixDPLR::pack_reverse_comm(int n, int first, double *buf) +{ + int m = 0; + int last = first + n; + for (int i = first; i < last; i++) { + buf[m++] = dfcorr_buff[3*i+0]; + buf[m++] = dfcorr_buff[3*i+1]; + buf[m++] = dfcorr_buff[3*i+2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void FixDPLR::unpack_reverse_comm(int n, int *list, double *buf) +{ + int m = 0; + for (int i = 0; i < n; i++) { + int j = list[i]; + dfcorr_buff[3*j+0] += buf[m++]; + dfcorr_buff[3*j+1] += buf[m++]; + dfcorr_buff[3*j+2] += buf[m++]; + } +} + + + diff --git a/source/lmp/fix_dplr.h b/source/lmp/fix_dplr.h new file mode 100644 index 0000000000..edc9204874 --- /dev/null +++ b/source/lmp/fix_dplr.h @@ -0,0 +1,53 @@ +#ifdef FIX_CLASS + +FixStyle(dplr,FixDPLR) + +#else + +#ifndef LMP_FIX_DPLR_H +#define LMP_FIX_DPLR_H + +#include +#include "fix.h" +#include "pair_nnp.h" +#include "DeepTensor.h" +#include "DataModifier.h" + +#ifdef HIGH_PREC +#define FLOAT_PREC double +#else +#define FLOAT_PREC float +#endif + +namespace LAMMPS_NS { + class FixDPLR : public Fix { +public: + FixDPLR(class LAMMPS *, int, char **); + virtual ~FixDPLR() {}; + int setmask(); + void init(); + void setup(int); + void post_integrate(); + void pre_force(int); + void post_force(int); + int pack_reverse_comm(int, int, double *); + void unpack_reverse_comm(int, int *, double *); +private: + PairNNP * pair_nnp; + DeepTensor dpt; + DataModifier dtm; + string model; + int ntypes; + vector sel_type; + vector dpl_type; + vector bond_type; + map type_asso; + map bk_type_asso; + vector dipole_recd; + vector dfcorr_buff; + void get_valid_pairs(vector >& pairs); + }; +} + +#endif // LMP_FIX_DPLR_H +#endif // FIX_CLASS diff --git a/source/lmp/pppm_dplr.cpp b/source/lmp/pppm_dplr.cpp new file mode 100644 index 0000000000..f706320f79 --- /dev/null +++ b/source/lmp/pppm_dplr.cpp @@ -0,0 +1,401 @@ +/* ---------------------------------------------------------------------- + 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 "pppm_dplr.h" +#include "atom.h" +#include "domain.h" +#include "force.h" +#include "memory.h" +#include "error.h" +#include "math_const.h" +#include "pppm.h" +#include "gridcomm.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +enum{REVERSE_RHO}; +enum{FORWARD_IK,FORWARD_AD,FORWARD_IK_PERATOM,FORWARD_AD_PERATOM}; + +#define OFFSET 16384 + +#ifdef FFT_SINGLE +#define ZEROF 0.0f +#define ONEF 1.0f +#else +#define ZEROF 0.0 +#define ONEF 1.0 +#endif + +/* ---------------------------------------------------------------------- */ + +PPPMDPLR::PPPMDPLR(LAMMPS *lmp, int narg, char **arg) : + PPPM(lmp, narg, arg) +{ + triclinic_support = 1; +} + +/* ---------------------------------------------------------------------- */ + +void PPPMDPLR::init() +{ + // DPLR PPPM requires newton on, b/c it computes forces on ghost atoms + + if (force->newton == 0) + error->all(FLERR,"Kspace style pppm/dplr requires newton on"); + + PPPM::init(); + + int nlocal = atom->nlocal; + // cout << " ninit pppm/dplr ---------------------- " << nlocal << endl; + fele.resize(nlocal*3); + fill(fele.begin(), fele.end(), 0.0); +} + + +/* ---------------------------------------------------------------------- + compute the PPPM long-range force, energy, virial +------------------------------------------------------------------------- */ + +void PPPMDPLR::compute(int eflag, int vflag) +{ + int i,j; + + // set energy/virial flags + // invoke allocate_peratom() if needed for first time + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = evflag_atom = eflag_global = vflag_global = + eflag_atom = vflag_atom = 0; + + if (evflag_atom && !peratom_allocate_flag) { + allocate_peratom(); + cg_peratom->ghost_notify(); + cg_peratom->setup(); + } + + // if atom count has changed, update qsum and qsqsum + + if (atom->natoms != natoms_original) { + qsum_qsq(); + natoms_original = atom->natoms; + } + + // return if there are no charges + + if (qsqsum == 0.0) return; + + // convert atoms from box to lamda coords + + if (triclinic == 0) boxlo = domain->boxlo; + else { + boxlo = domain->boxlo_lamda; + domain->x2lamda(atom->nlocal); + } + + // extend size of per-atom arrays if necessary + + if (atom->nmax > nmax) { + memory->destroy(part2grid); + nmax = atom->nmax; + memory->create(part2grid,nmax,3,"pppm:part2grid"); + } + + // find grid points for all my particles + // map my particle charge onto my local 3d density grid + + particle_map(); + make_rho(); + + // all procs communicate density values from their ghost cells + // to fully sum contribution in their 3d bricks + // remap from 3d decomposition to FFT decomposition + + cg->reverse_comm(this,REVERSE_RHO); + brick2fft(); + + // compute potential gradient on my FFT grid and + // portion of e_long on this proc's FFT grid + // return gradients (electric fields) in 3d brick decomposition + // also performs per-atom calculations via poisson_peratom() + + poisson(); + + // all procs communicate E-field values + // to fill ghost cells surrounding their 3d bricks + + if (differentiation_flag == 1) cg->forward_comm(this,FORWARD_AD); + else cg->forward_comm(this,FORWARD_IK); + + // extra per-atom energy/virial communication + + if (evflag_atom) { + if (differentiation_flag == 1 && vflag_atom) + cg_peratom->forward_comm(this,FORWARD_AD_PERATOM); + else if (differentiation_flag == 0) + cg_peratom->forward_comm(this,FORWARD_IK_PERATOM); + } + + // calculate the force on my particles + + fieldforce(); + + // extra per-atom energy/virial communication + + if (evflag_atom) fieldforce_peratom(); + + // sum global energy across procs and add in volume-dependent term + + const double qscale = qqrd2e * scale; + + if (eflag_global) { + double energy_all; + MPI_Allreduce(&energy,&energy_all,1,MPI_DOUBLE,MPI_SUM,world); + energy = energy_all; + + energy *= 0.5*volume; + // do not add self-term, for neutral systems qsum == 0 + // energy -= g_ewald*qsqsum/MY_PIS + + // MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); + energy *= qscale; + } + + // sum global virial across procs + + if (vflag_global) { + double virial_all[6]; + MPI_Allreduce(virial,virial_all,6,MPI_DOUBLE,MPI_SUM,world); + for (i = 0; i < 6; i++) virial[i] = 0.5*qscale*volume*virial_all[i]; + } + // std::cout<< "energy in pppm -------------------" << std::endl; + // std::cout << energy << " " + // << std::endl; + // std::cout<< "virial in pppm -------------------" << std::endl; + // for (int ii = 0; ii < 6; ++ii){ + // std::cout << virial[ii] << " " ; + // } + // std::cout << std::endl; + + // per-atom energy/virial + // energy includes self-energy correction + // ntotal accounts for TIP4P tallying eatom/vatom for ghost atoms + + if (evflag_atom) { + double *q = atom->q; + int nlocal = atom->nlocal; + int ntotal = nlocal; + if (tip4pflag) ntotal += atom->nghost; + + if (eflag_atom) { + for (i = 0; i < nlocal; i++) { + eatom[i] *= 0.5; + eatom[i] -= g_ewald*q[i]*q[i]/MY_PIS + MY_PI2*q[i]*qsum / + (g_ewald*g_ewald*volume); + eatom[i] *= qscale; + } + for (i = nlocal; i < ntotal; i++) eatom[i] *= 0.5*qscale; + } + + if (vflag_atom) { + for (i = 0; i < ntotal; i++) + for (j = 0; j < 6; j++) vatom[i][j] *= 0.5*qscale; + } + } + + // 2d slab correction + + if (slabflag == 1) slabcorr(); + + // convert atoms back from lamda to box coords + + if (triclinic) domain->lamda2x(atom->nlocal); +} + + +/* ---------------------------------------------------------------------- + interpolate from grid to get electric field & force on my particles for ik +------------------------------------------------------------------------- */ +void PPPMDPLR::fieldforce_ik() +{ + int i,l,m,n,nx,ny,nz,mx,my,mz; + FFT_SCALAR dx,dy,dz,x0,y0,z0; + FFT_SCALAR ekx,eky,ekz; + + // loop over my charges, interpolate electric field from nearby grid points + // (nx,ny,nz) = global coords of grid pt to "lower left" of charge + // (dx,dy,dz) = distance to "lower left" grid pt + // (mx,my,mz) = global coords of moving stencil pt + // ek = 3 components of E-field on particle + + double *q = atom->q; + double **x = atom->x; + // double **f = atom->f; + + int nlocal = atom->nlocal; + int nghost = atom->nghost; + int nall = nlocal + nghost; + + fele.resize(nlocal*3); + fill(fele.begin(), fele.end(), 0.0); + + for (i = 0; i < nlocal; i++) { + nx = part2grid[i][0]; + ny = part2grid[i][1]; + nz = part2grid[i][2]; + dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv; + dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv; + dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv; + + compute_rho1d(dx,dy,dz); + + ekx = eky = ekz = ZEROF; + for (n = nlower; n <= nupper; n++) { + mz = n+nz; + z0 = rho1d[2][n]; + for (m = nlower; m <= nupper; m++) { + my = m+ny; + y0 = z0*rho1d[1][m]; + for (l = nlower; l <= nupper; l++) { + mx = l+nx; + x0 = y0*rho1d[0][l]; + ekx -= x0*vdx_brick[mz][my][mx]; + eky -= x0*vdy_brick[mz][my][mx]; + ekz -= x0*vdz_brick[mz][my][mx]; + } + } + } + + // convert E-field to force + + const double qfactor = qqrd2e * scale * q[i]; + fele[i*3+0] += qfactor*ekx; + fele[i*3+1] += qfactor*eky; + if (slabflag != 2) fele[i*3+2] += qfactor*ekz; + } + + // vector dcoord(nall*3), dbox(9); + // vector dtype(nall); + // { + // double ** xx = atom->x; + // for(int ii = 0; ii < nall; ++ii){ + // for (int dd = 0; dd < 3; +=dd){ + // dcoord[ii*3+dd] = xx[ii][dd]; + // } + // } + // int *type = atom->type; + // for (int ii = 0; ii < nall; ++ii){ + // dtype[ii] = type[ii] - 1; + // } + // } +} + +/* ---------------------------------------------------------------------- + interpolate from grid to get electric field & force on my particles for ad +------------------------------------------------------------------------- */ + +void PPPMDPLR::fieldforce_ad() +{ + int i,l,m,n,nx,ny,nz,mx,my,mz; + FFT_SCALAR dx,dy,dz; + FFT_SCALAR ekx,eky,ekz; + double s1,s2,s3; + double sf = 0.0; + double *prd; + + prd = domain->prd; + double xprd = prd[0]; + double yprd = prd[1]; + double zprd = prd[2]; + + double hx_inv = nx_pppm/xprd; + double hy_inv = ny_pppm/yprd; + double hz_inv = nz_pppm/zprd; + + // loop over my charges, interpolate electric field from nearby grid points + // (nx,ny,nz) = global coords of grid pt to "lower left" of charge + // (dx,dy,dz) = distance to "lower left" grid pt + // (mx,my,mz) = global coords of moving stencil pt + // ek = 3 components of E-field on particle + + double *q = atom->q; + double **x = atom->x; + double **f = atom->f; + + int nlocal = atom->nlocal; + + vector fele(nlocal, 0.0); + + for (i = 0; i < nlocal; i++) { + nx = part2grid[i][0]; + ny = part2grid[i][1]; + nz = part2grid[i][2]; + dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv; + dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv; + dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv; + + compute_rho1d(dx,dy,dz); + compute_drho1d(dx,dy,dz); + + ekx = eky = ekz = ZEROF; + for (n = nlower; n <= nupper; n++) { + mz = n+nz; + for (m = nlower; m <= nupper; m++) { + my = m+ny; + for (l = nlower; l <= nupper; l++) { + mx = l+nx; + ekx += drho1d[0][l]*rho1d[1][m]*rho1d[2][n]*u_brick[mz][my][mx]; + eky += rho1d[0][l]*drho1d[1][m]*rho1d[2][n]*u_brick[mz][my][mx]; + ekz += rho1d[0][l]*rho1d[1][m]*drho1d[2][n]*u_brick[mz][my][mx]; + } + } + } + ekx *= hx_inv; + eky *= hy_inv; + ekz *= hz_inv; + + // convert E-field to force and substract self forces + + const double qfactor = qqrd2e * scale; + + s1 = x[i][0]*hx_inv; + s2 = x[i][1]*hy_inv; + s3 = x[i][2]*hz_inv; + sf = sf_coeff[0]*sin(2*MY_PI*s1); + sf += sf_coeff[1]*sin(4*MY_PI*s1); + sf *= 2*q[i]*q[i]; + fele[i*3+0] += qfactor*(ekx*q[i] - sf); + + sf = sf_coeff[2]*sin(2*MY_PI*s2); + sf += sf_coeff[3]*sin(4*MY_PI*s2); + sf *= 2*q[i]*q[i]; + fele[i*3+1] += qfactor*(eky*q[i] - sf); + + + sf = sf_coeff[4]*sin(2*MY_PI*s3); + sf += sf_coeff[5]*sin(4*MY_PI*s3); + sf *= 2*q[i]*q[i]; + if (slabflag != 2) fele[i*3+2] += qfactor*(ekz*q[i] - sf); + } + + // for (int ii = 0; ii < nlocal; ++ii){ + // cout << ii << "\t "; + // for (int dd = 0; dd < 3; ++dd){ + // cout << fele[ii*3+dd] << " " ; + // } + // cout << endl; + // } +} + + + diff --git a/source/lmp/pppm_dplr.h b/source/lmp/pppm_dplr.h new file mode 100644 index 0000000000..884d41bce2 --- /dev/null +++ b/source/lmp/pppm_dplr.h @@ -0,0 +1,54 @@ +/* -*- 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. +------------------------------------------------------------------------- */ + +#ifdef KSPACE_CLASS + +KSpaceStyle(pppm/dplr,PPPMDPLR) + +#else + +#ifndef LMP_PPPM_DPLR_H +#define LMP_PPPM_DPLR_H + +#ifdef HIGH_PREC +#define FLOAT_PREC double +#else +#define FLOAT_PREC float +#endif + +#include "pppm.h" +#include +#include +using namespace std; + +namespace LAMMPS_NS { + + class PPPMDPLR : public PPPM { +public: + PPPMDPLR(class LAMMPS *, int, char **); + virtual ~PPPMDPLR () {}; + void init(); + const vector & get_fele() const {return fele;}; +protected: + virtual void compute(int, int); + virtual void fieldforce_ik(); + virtual void fieldforce_ad(); +private: + vector fele; + }; + +} + +#endif +#endif + From cd7bc372abe83a935748c785d4eaaba8f6b460dc Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 6 Dec 2019 13:10:40 +0800 Subject: [PATCH 037/147] remove tmp files after test --- source/tests/test_data_modifier_shuffle.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/tests/test_data_modifier_shuffle.py b/source/tests/test_data_modifier_shuffle.py index d70bd94b3b..5148a251b9 100644 --- a/source/tests/test_data_modifier_shuffle.py +++ b/source/tests/test_data_modifier_shuffle.py @@ -1,4 +1,4 @@ -import os,sys,platform,json +import os,sys,platform,json,shutil import numpy as np import unittest import dpdata @@ -43,6 +43,10 @@ def setUp(self): def tearDown(self): tf.reset_default_graph() + if os.path.isdir(os.path.join(modifier_datapath, 'sys_test_0')): + shutil.rmtree(os.path.join(modifier_datapath, 'sys_test_0')) + if os.path.isfile(os.path.join(modifier_datapath, 'dipole.pb')): + os.remove(os.path.join(modifier_datapath, 'dipole.pb')) def _setUp(self): args = Args() @@ -104,7 +108,7 @@ def _setUp_data(self): self.dipoles0 = np.random.random([self.nframes, self.nsel * 3]) self.box0 = np.reshape(np.eye(3) * scale, [-1, 9]) self.box0 = np.tile(self.box0, [self.nframes, 1]) - self._write_sys_data('data_modifier/sys_test_0', + self._write_sys_data(os.path.join(modifier_datapath, 'sys_test_0'), self.atom_types0, self.coords0, self.dipoles0, self.box0) # sys1 self.idx_map = np.array([6, 7, 1, 0, 5, 2, 4, 3], dtype = int) From 188c918e5167b66e5a5b2c65d9b16a6f2db9110d Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sun, 8 Dec 2019 18:52:52 +0800 Subject: [PATCH 038/147] change the DataModification: freeze dipole part with name dipole_charge. make the freeze and test work --- source/lmp/fix_dplr.cpp | 4 +- source/scripts/freeze.py | 12 +++- source/tests/test_data_modifier.py | 10 ++-- source/tests/test_data_modifier_shuffle.py | 4 +- source/train/Data.py | 4 +- source/train/DataModifier.py | 65 ++++++++++++++++------ source/train/DeepDipole.py | 5 +- source/train/DeepEval.py | 32 ++++++----- source/train/DeepPot.py | 39 ++++++++++++- source/train/test.py | 19 +++++-- source/train/train.py | 2 +- 11 files changed, 142 insertions(+), 54 deletions(-) diff --git a/source/lmp/fix_dplr.cpp b/source/lmp/fix_dplr.cpp index 481da66840..c0f0bb930c 100644 --- a/source/lmp/fix_dplr.cpp +++ b/source/lmp/fix_dplr.cpp @@ -83,8 +83,8 @@ FixDPLR::FixDPLR(LAMMPS *lmp, int narg, char **arg) // dpt.init(model); // dtm.init("frozen_model.pb"); - dpt.init(model, 0, "load"); - dtm.init(model, 0, "load"); + dpt.init(model, 0, "dipole_charge"); + dtm.init(model, 0, "dipole_charge"); sel_type = dpt.sel_types(); sort(sel_type.begin(), sel_type.end()); diff --git a/source/scripts/freeze.py b/source/scripts/freeze.py index a7bb8ca11a..c83e7e569c 100755 --- a/source/scripts/freeze.py +++ b/source/scripts/freeze.py @@ -35,7 +35,7 @@ import deepmd._soft_min_force_grad import deepmd._soft_min_virial_grad -def _make_node_names(model_type = None) : +def _make_node_names(model_type, modifier_type = None) : if model_type == 'ener': nodes = "o_energy,o_force,o_virial,o_atom_energy,o_atom_virial,descrpt_attr/rcut,descrpt_attr/ntypes,fitting_attr/dfparam,fitting_attr/daparam,model_attr/tmap,model_attr/model_type" elif model_type == 'wfc': @@ -48,6 +48,8 @@ def _make_node_names(model_type = None) : nodes = "o_global_polar,descrpt_attr/rcut,descrpt_attr/ntypes,model_attr/tmap,model_attr/sel_type,model_attr/model_type" else: raise RuntimeError('unknow model type ' + model_type) + if modifier_type == 'dipole_charge': + nodes += ",modifier_attr/type,modifier_attr/mdl_name,modifier_attr/mdl_charge_map,modifier_attr/sys_charge_map,modifier_attr/ewald_h,modifier_attr/ewald_beta,dipole_charge/descrpt_attr/rcut,dipole_charge/descrpt_attr/ntypes,dipole_charge/model_attr/tmap,dipole_charge/model_attr/model_type,o_dm_force,dipole_charge/model_attr/sel_type,dipole_charge/o_dipole,dipole_charge/model_attr/output_dim,o_dm_virial,o_dm_av" return nodes def freeze_graph(model_folder, @@ -75,14 +77,18 @@ def freeze_graph(model_folder, # We retrieve the protobuf graph definition graph = tf.get_default_graph() input_graph_def = graph.as_graph_def() - # nodes = [n.name for n in input_graph_def.node] + nodes = [n.name for n in input_graph_def.node] # We start a session and restore the graph weights with tf.Session() as sess: saver.restore(sess, input_checkpoint) model_type = sess.run('model_attr/model_type:0', feed_dict = {}).decode('utf-8') + if 'modifier_attr/type' in nodes: + modifier_type = sess.run('modifier_attr/type:0', feed_dict = {}).decode('utf-8') + else: + modifier_type = None if output_node_names is None : - output_node_names = _make_node_names(model_type) + output_node_names = _make_node_names(model_type, modifier_type) print('The following nodes will be frozen: %s' % output_node_names) # We use a built-in TF helper to export variables to constants diff --git a/source/tests/test_data_modifier.py b/source/tests/test_data_modifier.py index cdf9828a4d..134e31095e 100644 --- a/source/tests/test_data_modifier.py +++ b/source/tests/test_data_modifier.py @@ -100,7 +100,7 @@ def _test_fv (self): data = Data() coord, box, atype = data.get_data() atype = atype[0] - ve, vf, vv = dcm.eval_modify(coord, box, atype) + ve, vf, vv = dcm.eval(coord, box, atype) hh = global_default_fv_hh hh=1e-4 @@ -115,8 +115,8 @@ def _test_fv (self): coordm = np.copy(coord) coordp[:,ii] += hh coordm[:,ii] -= hh - ep, _, __ = dcm.eval_modify(coordp, box, atype, eval_fv = False) - em, _, __ = dcm.eval_modify(coordm, box, atype, eval_fv = False) + ep, _, __ = dcm.eval(coordp, box, atype, eval_fv = False) + em, _, __ = dcm.eval(coordm, box, atype, eval_fv = False) num_f = -(ep - em) / (2.*hh) for ff in range(nframes): self.assertAlmostEqual(vf[ff,ii], num_f[ff], @@ -140,8 +140,8 @@ def _test_fv (self): coord3m = np.matmul(rcoord3, box3m) coordp = np.reshape(coord3p, [nframes,-1]) coordm = np.reshape(coord3m, [nframes,-1]) - ep, _, __ = dcm.eval_modify(coordp, boxp, atype, eval_fv = False) - em, _, __ = dcm.eval_modify(coordm, boxm, atype, eval_fv = False) + ep, _, __ = dcm.eval(coordp, boxp, atype, eval_fv = False) + em, _, __ = dcm.eval(coordm, boxm, atype, eval_fv = False) num_deriv[:,ii,jj] = -(ep - em) / (2.*hh) # box3t = np.transpose(box3, [0,2,1]) # t_esti = np.matmul(num_deriv, box3t) diff --git a/source/tests/test_data_modifier_shuffle.py b/source/tests/test_data_modifier_shuffle.py index 5148a251b9..81d36ed8ab 100644 --- a/source/tests/test_data_modifier_shuffle.py +++ b/source/tests/test_data_modifier_shuffle.py @@ -192,8 +192,8 @@ def test_modify(self): [1, 1, 1, 1, 1], 1, 0.25) - ve0, vf0, vv0 = dcm.eval_modify(self.coords0, self.box0, self.atom_types0) - ve1, vf1, vv1 = dcm.eval_modify(self.coords1, self.box1, self.atom_types1) + ve0, vf0, vv0 = dcm.eval(self.coords0, self.box0, self.atom_types0) + ve1, vf1, vv1 = dcm.eval(self.coords1, self.box1, self.atom_types1) vf01 = vf0[:,self.idx_map, :] for ii in range(self.nframes): diff --git a/source/train/Data.py b/source/train/Data.py index 6c0672afc2..d5a91f6b7b 100644 --- a/source/train/Data.py +++ b/source/train/Data.py @@ -121,7 +121,7 @@ def get_batch(self, batch_size) : self.set_count += 1 set_size = self.batch_set["coord"].shape[0] if self.modifier is not None: - self.modifier.modify(self.batch_set) + self.modifier.modify_data(self.batch_set) iterator_1 = self.iterator + batch_size if iterator_1 >= set_size : iterator_1 = set_size @@ -141,7 +141,7 @@ def get_test (self, ntests = -1) : idx = np.arange(ntests_) ret = self._get_subdata(self.test_set, idx = idx) if self.modifier is not None: - self.modifier.modify(ret) + self.modifier.modify_data(ret) return ret def get_type_map(self) : diff --git a/source/train/DataModifier.py b/source/train/DataModifier.py index 4fa57d9d86..27f3f93b60 100644 --- a/source/train/DataModifier.py +++ b/source/train/DataModifier.py @@ -1,6 +1,6 @@ import os,platform import numpy as np -from deepmd import DeepDipole +from deepmd.DeepDipole import DeepDipole from deepmd.env import tf from deepmd.common import select_idx_map, make_default_mesh from deepmd.EwaldRecp import EwaldRecp @@ -29,15 +29,22 @@ def __init__(self, sys_charge_map, ewald_h = 1, ewald_beta = 1): - DeepDipole.__init__(self, model_name) - self.er = EwaldRecp(ewald_h, ewald_beta) + # the dipole model is loaded with prefix 'dipole_charge' + self.modifier_prefix = 'dipole_charge' + # init dipole model + DeepDipole.__init__(self, model_name, load_prefix = self.modifier_prefix) + self.model_name = model_name self.model_charge_map = model_charge_map self.sys_charge_map = sys_charge_map self.sel_type = list(self.get_sel_type()) + # init ewald recp + self.ewald_h = ewald_h + self.ewald_beta = ewald_beta + self.er = EwaldRecp(self.ewald_h, self.ewald_beta) # dimension of dipole self.ext_dim = 3 - self.t_ndesc = self.graph.get_tensor_by_name ('load/descrpt_attr/ndescrpt:0') - self.t_sela = self.graph.get_tensor_by_name ('load/descrpt_attr/sel:0') + self.t_ndesc = self.graph.get_tensor_by_name(os.path.join(self.modifier_prefix, 'descrpt_attr/ndescrpt:0')) + self.t_sela = self.graph.get_tensor_by_name(os.path.join(self.modifier_prefix, 'descrpt_attr/sel:0')) [self.ndescrpt, self.sel_a] = self.sess.run([self.t_ndesc, self.t_sela]) self.sel_r = [ 0 for ii in range(len(self.sel_a)) ] self.nnei_a = np.cumsum(self.sel_a)[-1] @@ -50,6 +57,25 @@ def __init__(self, self.ntypes = len(self.sel_a) def build_fv_graph(self): + with tf.variable_scope('modifier_attr') : + t_mdl_name = tf.constant(self.model_name, + name = 'mdl_name', + dtype = tf.string) + t_modi_type = tf.constant(self.modifier_prefix, + name = 'type', + dtype = tf.string) + t_mdl_charge_map = tf.constant(' '.join([str(ii) for ii in self.model_charge_map]), + name = 'mdl_charge_map', + dtype = tf.string) + t_sys_charge_map = tf.constant(' '.join([str(ii) for ii in self.sys_charge_map]), + name = 'sys_charge_map', + dtype = tf.string) + t_ewald_h = tf.constant(self.ewald_h, + name = 'ewald_h', + dtype = tf.float64) + t_ewald_b = tf.constant(self.ewald_beta, + name = 'ewald_beta', + dtype = tf.float64) with self.graph.as_default(): return self._build_fv_graph_inner() @@ -66,10 +92,10 @@ def _build_fv_graph_inner(self): # (nframes x natoms_sel) x 1 x 3 self.t_ef_reshape = tf.reshape(self.t_ef, [nfxnas, 1, 3]) # (nframes x natoms) x ndescrpt - self.descrpt = self.graph.get_tensor_by_name('load/o_rmat:0') - self.descrpt_deriv = self.graph.get_tensor_by_name('load/o_rmat_deriv:0') - self.nlist = self.graph.get_tensor_by_name('load/o_nlist:0') - self.rij = self.graph.get_tensor_by_name('load/o_rij:0') + self.descrpt = self.graph.get_tensor_by_name(os.path.join(self.modifier_prefix, 'o_rmat:0')) + self.descrpt_deriv = self.graph.get_tensor_by_name(os.path.join(self.modifier_prefix, 'o_rmat_deriv:0')) + self.nlist = self.graph.get_tensor_by_name(os.path.join(self.modifier_prefix, 'o_nlist:0')) + self.rij = self.graph.get_tensor_by_name(os.path.join(self.modifier_prefix, 'o_rij:0')) # self.descrpt_reshape = tf.reshape(self.descrpt, [nf, 192 * self.ndescrpt]) # self.descrpt_deriv = tf.reshape(self.descrpt_deriv, [nf, 192 * self.ndescrpt * 3]) @@ -163,7 +189,7 @@ def _slice_descrpt_deriv(self, deriv): return tf.concat(coll, axis = 1) - def eval_modify(self, coord, box, atype, eval_fv = True): + def eval(self, coord, box, atype, eval_fv = True): coord, atype, imap = self.sort_input(coord, atype) natoms = coord.shape[1] // 3 nframes = coord.shape[0] @@ -194,6 +220,8 @@ def eval_modify(self, coord, box, atype, eval_fv = True): all_f = np.concatenate(all_f, axis = 0) all_v = np.concatenate(all_v, axis = 0) # print('finish er') + # reshape + tot_e.reshape([nframes,1]) tot_f = None tot_v = None @@ -218,6 +246,8 @@ def eval_modify(self, coord, box, atype, eval_fv = True): orig_idx = sel_idx_map[ii] tot_f[:,orig_idx*3:orig_idx*3+3] += ext_f[:,ii*3:ii*3+3] tot_f = self.reverse_map(np.reshape(tot_f, [nframes,-1,3]), imap) + # reshape + tot_f = tot_f.reshape([nframes,natoms,3]) # compute v dipole3 = np.reshape(dipole, [nframes, nsel, 3]) ext_f3 = np.reshape(ext_f, [nframes, nsel, 3]) @@ -228,6 +258,8 @@ def eval_modify(self, coord, box, atype, eval_fv = True): fd_corr_v = -np.matmul(ext_f3, dipole3).reshape([nframes, 9]) # print(all_v, '\n', corr_v, '\n', fd_corr_v) tot_v = all_v + corr_v + fd_corr_v + # reshape + tot_v = tot_v.reshape([nframes,9]) return tot_e, tot_f, tot_v @@ -276,7 +308,7 @@ def _extend_system(self, coord, box, atype, charge): ref_coord = coord3[:,sel_idx_map,:] ref_coord = np.reshape(ref_coord, [nframes, nsel * 3]) - dipole = self.eval(coord, box, atype) + dipole = DeepDipole.eval(self, coord, box, atype) dipole = np.reshape(dipole, [nframes, nsel * 3]) wfcc_coord = ref_coord + dipole @@ -296,8 +328,7 @@ def _extend_system(self, coord, box, atype, charge): return all_coord, all_charge, dipole - def modify(self, - data): + def modify_data(self, data): if 'find_energy' not in data and 'find_force' not in data and 'find_virial' not in data: return @@ -308,16 +339,16 @@ def modify(self, atype = atype[0] nframes = coord.shape[0] - tot_e, tot_f, tot_v = self.eval_modify(coord, box, atype) + tot_e, tot_f, tot_v = self.eval(coord, box, atype) # print(tot_f[:,0]) if 'find_energy' in data and data['find_energy'] == 1.0 : - data['energy'] -= tot_e.reshape([nframes, 1]) + data['energy'] -= tot_e.reshape(data['energy'].shape) if 'find_force' in data and data['find_force'] == 1.0 : - data['force'] -= tot_f + data['force'] -= tot_f.reshape(data['force'].shape) if 'find_virial' in data and data['find_virial'] == 1.0 : - data['virial'] -= tot_v.reshape([nframes, 9]) + data['virial'] -= tot_v.reshape(data['virial'].shape) diff --git a/source/train/DeepDipole.py b/source/train/DeepDipole.py index 3ef107b4a2..31b166284e 100644 --- a/source/train/DeepDipole.py +++ b/source/train/DeepDipole.py @@ -6,6 +6,7 @@ class DeepDipole (DeepTensor) : def __init__(self, - model_file) : - DeepTensor.__init__(self, model_file, 'dipole', 3) + model_file, + load_prefix = 'load') : + DeepTensor.__init__(self, model_file, 'dipole', 3, load_prefix = load_prefix) diff --git a/source/train/DeepEval.py b/source/train/DeepEval.py index ba383f245f..386d68a4e2 100644 --- a/source/train/DeepEval.py +++ b/source/train/DeepEval.py @@ -23,10 +23,11 @@ class DeepEval(): common methods for DeepPot, DeepWFC, DeepPolar, ... """ def __init__(self, - model_file) : + model_file, + load_prefix = 'load') : model_file = model_file - self.graph = self._load_graph (model_file) - t_mt = self.graph.get_tensor_by_name('load/model_attr/model_type:0') + self.graph = self._load_graph (model_file, prefix = load_prefix) + t_mt = self.graph.get_tensor_by_name(os.path.join(load_prefix, 'model_attr/model_type:0')) sess = tf.Session (graph = self.graph) [mt] = sess.run([t_mt], feed_dict = {}) self.model_type = mt.decode('utf-8') @@ -112,25 +113,26 @@ class DeepTensor(DeepEval) : def __init__(self, model_file, variable_name, - variable_dof) : - DeepEval.__init__(self, model_file) + variable_dof, + load_prefix = 'load') : + DeepEval.__init__(self, model_file, load_prefix = load_prefix) # self.model_file = model_file # self.graph = self.load_graph (self.model_file) self.variable_name = variable_name self.variable_dof = variable_dof # checkout input/output tensors from graph - self.t_ntypes = self.graph.get_tensor_by_name ('load/descrpt_attr/ntypes:0') - self.t_rcut = self.graph.get_tensor_by_name ('load/descrpt_attr/rcut:0') - self.t_tmap = self.graph.get_tensor_by_name ('load/model_attr/tmap:0') - self.t_sel_type= self.graph.get_tensor_by_name ('load/model_attr/sel_type:0') + self.t_ntypes = self.graph.get_tensor_by_name (os.path.join(load_prefix, 'descrpt_attr/ntypes:0')) + self.t_rcut = self.graph.get_tensor_by_name (os.path.join(load_prefix, 'descrpt_attr/rcut:0')) + self.t_tmap = self.graph.get_tensor_by_name (os.path.join(load_prefix, 'model_attr/tmap:0')) + self.t_sel_type= self.graph.get_tensor_by_name (os.path.join(load_prefix, 'model_attr/sel_type:0')) # inputs - self.t_coord = self.graph.get_tensor_by_name ('load/t_coord:0') - self.t_type = self.graph.get_tensor_by_name ('load/t_type:0') - self.t_natoms = self.graph.get_tensor_by_name ('load/t_natoms:0') - self.t_box = self.graph.get_tensor_by_name ('load/t_box:0') - self.t_mesh = self.graph.get_tensor_by_name ('load/t_mesh:0') + self.t_coord = self.graph.get_tensor_by_name (os.path.join(load_prefix, 't_coord:0')) + self.t_type = self.graph.get_tensor_by_name (os.path.join(load_prefix, 't_type:0')) + self.t_natoms = self.graph.get_tensor_by_name (os.path.join(load_prefix, 't_natoms:0')) + self.t_box = self.graph.get_tensor_by_name (os.path.join(load_prefix, 't_box:0')) + self.t_mesh = self.graph.get_tensor_by_name (os.path.join(load_prefix, 't_mesh:0')) # outputs - self.t_tensor = self.graph.get_tensor_by_name ('load/o_%s:0' % self.variable_name) + self.t_tensor = self.graph.get_tensor_by_name (os.path.join(load_prefix, 'o_%s:0' % self.variable_name)) # start a tf session associated to the graph self.sess = tf.Session (graph = self.graph) [self.ntypes, self.rcut, self.tmap, self.tselt] = self.sess.run([self.t_ntypes, self.t_rcut, self.t_tmap, self.t_sel_type]) diff --git a/source/train/DeepPot.py b/source/train/DeepPot.py index 9430216c02..88bf92f63d 100644 --- a/source/train/DeepPot.py +++ b/source/train/DeepPot.py @@ -5,6 +5,7 @@ from deepmd.env import tf from deepmd.common import make_default_mesh from deepmd.DeepEval import DeepEval +from deepmd.DataModifier import DipoleChargeModifier class DeepPot (DeepEval) : def __init__(self, @@ -46,6 +47,22 @@ def __init__(self, self.sess = tf.Session (graph = self.graph) [self.ntypes, self.rcut, self.dfparam, self.daparam, self.tmap] = self.sess.run([self.t_ntypes, self.t_rcut, self.t_dfparam, self.t_daparam, self.t_tmap]) self.tmap = self.tmap.decode('UTF-8').split() + # setup modifier + try: + t_modifier_type = self.graph.get_tensor_by_name('load/modifier_attr/type:0') + self.modifier_type = self.sess.run(t_modifier_type).decode('UTF-8') + except ValueError: + self.modifier_type = None + if self.modifier_type == 'dipole_charge': + t_mdl_name = self.graph.get_tensor_by_name('load/modifier_attr/mdl_name:0') + t_mdl_charge_map = self.graph.get_tensor_by_name('load/modifier_attr/mdl_charge_map:0') + t_sys_charge_map = self.graph.get_tensor_by_name('load/modifier_attr/sys_charge_map:0') + t_ewald_h = self.graph.get_tensor_by_name('load/modifier_attr/ewald_h:0') + t_ewald_beta = self.graph.get_tensor_by_name('load/modifier_attr/ewald_beta:0') + [mdl_name, mdl_charge_map, sys_charge_map, ewald_h, ewald_beta] = self.sess.run([t_mdl_name, t_mdl_charge_map, t_sys_charge_map, t_ewald_h, t_ewald_beta]) + mdl_charge_map = [int(ii) for ii in mdl_charge_map.decode('UTF-8').split()] + sys_charge_map = [int(ii) for ii in sys_charge_map.decode('UTF-8').split()] + self.dm = DipoleChargeModifier(mdl_name, mdl_charge_map, sys_charge_map, ewald_h = ewald_h, ewald_beta = ewald_beta) def get_ntypes(self) : @@ -63,8 +80,27 @@ def get_dim_aparam(self) : def get_type_map(self): return self.tmap - def eval(self, + coords, + cells, + atom_types, + fparam = None, + aparam = None, + atomic = False) : + if atomic : + if self.modifier_type is not None: + raise RuntimeError('modifier does not support atomic modification') + return self.eval_inner(coords, cells, atom_types, fparam = fparam, aparam = aparam, atomic = atomic) + else : + e, f, v = self.eval_inner(coords, cells, atom_types, fparam = fparam, aparam = aparam, atomic = atomic) + if self.modifier_type is not None: + me, mf, mv = self.dm.eval(coords, cells, atom_types) + e += me.reshape(e.shape) + f += mf.reshape(f.shape) + v += mv.reshape(v.shape) + return e, f, v + + def eval_inner(self, coords, cells, atom_types, @@ -160,3 +196,4 @@ def eval(self, else : return energy, force, virial + diff --git a/source/train/test.py b/source/train/test.py index 83f882e32b..29b66932dd 100755 --- a/source/train/test.py +++ b/source/train/test.py @@ -53,12 +53,24 @@ def test_ener (args) : aparam = test_data["aparam"][:numb_test] else : aparam = None - energy, force, virial, ae, av = dp.eval(coord, box, atype, fparam = fparam, aparam = aparam, atomic = True) + detail_file = args.detail_file + if detail_file is not None: + atomic = True + else: + atomic = False + + ret = dp.eval(coord, box, atype, fparam = fparam, aparam = aparam, atomic = atomic) + energy = ret[0] + force = ret[1] + virial = ret[2] energy = energy.reshape([numb_test,1]) force = force.reshape([numb_test,-1]) virial = virial.reshape([numb_test,9]) - ae = ae.reshape([numb_test,-1]) - av = av.reshape([numb_test,-1]) + if atomic: + ae = ret[3] + av = ret[4] + ae = ae.reshape([numb_test,-1]) + av = av.reshape([numb_test,-1]) l2e = (l2err (energy - test_data["energy"][:numb_test].reshape([-1,1]))) l2f = (l2err (force - test_data["force"] [:numb_test])) @@ -74,7 +86,6 @@ def test_ener (args) : print ("Virial L2err : %e eV" % l2v) print ("Virial L2err/Natoms : %e eV" % l2va) - detail_file = args.detail_file if detail_file is not None : pe = np.concatenate((np.reshape(test_data["energy"][:numb_test], [-1,1]), np.reshape(energy, [-1,1])), diff --git a/source/train/train.py b/source/train/train.py index 9fd4663057..874d66fb6a 100755 --- a/source/train/train.py +++ b/source/train/train.py @@ -110,7 +110,7 @@ def _do_work(jdata, run_opt): ipt_type_map = type_map # data modifier modifier = None - modi_data = jdata['training'].get("data_modifier", None) + modi_data = jdata['model'].get("modifier", None) if modi_data is not None: if modi_data['type'] == 'dipole_charge': modifier = DipoleChargeModifier(modi_data['model_name'], From 25f1ea0aa823b852419c5d4592e492fe95557fd4 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 20 Dec 2019 16:04:03 +0800 Subject: [PATCH 039/147] support no pbc --- source/lib/include/NeighborList.h | 18 +++++ source/lib/src/NeighborList.cpp | 52 +++++++++++++++ source/op/descrpt.cc | 74 +++++++-------------- source/op/descrpt_se_a.cc | 74 +++++++-------------- source/op/descrpt_se_r.cc | 74 +++++++-------------- source/tests/common.py | 5 +- source/tests/test_descrpt_nonsmth.py | 97 +++++++++++++++++++++++++-- source/tests/test_descrpt_se_r.py | 98 ++++++++++++++++++++++++++-- source/tests/test_descrpt_smooth.py | 97 +++++++++++++++++++++++++-- 9 files changed, 422 insertions(+), 167 deletions(-) diff --git a/source/lib/include/NeighborList.h b/source/lib/include/NeighborList.h index b919d15476..8e9f51b8e7 100644 --- a/source/lib/include/NeighborList.h +++ b/source/lib/include/NeighborList.h @@ -7,6 +7,7 @@ #include "MathUtilities.h" #include "SimulationRegion.h" +// build nlist by an extended grid void build_nlist (vector > & nlist0, vector > & nlist1, @@ -20,6 +21,8 @@ build_nlist (vector > & nlist0, const vector & ext_end_, const SimulationRegion & region, const vector & global_grid); + +// build nlist by a grid for a periodic region void build_nlist (vector > & nlist0, vector > & nlist1, @@ -28,6 +31,8 @@ build_nlist (vector > & nlist0, const double & rc1, const vector & grid, const SimulationRegion & region); + +// build nlist by a grid for a periodic region, atoms selected by sel0 and sel1 void build_nlist (vector > & nlist0, vector > & nlist1, @@ -38,6 +43,19 @@ build_nlist (vector > & nlist0, const double & rc1, const vector & grid, const SimulationRegion & region); + +// brute force (all-to-all distance computation) neighbor list building +// if region is NULL, open boundary is assumed, +// otherwise, periodic boundary condition is defined by region +void +build_nlist (vector > & nlist0, + vector > & nlist1, + const vector & coord, + const double & rc0_, + const double & rc1_, + const SimulationRegion * region = NULL); + +// copy periodic images for the system void copy_coord (vector & out_c, vector & out_t, diff --git a/source/lib/src/NeighborList.cpp b/source/lib/src/NeighborList.cpp index 282e0877b5..e7ced4834b 100644 --- a/source/lib/src/NeighborList.cpp +++ b/source/lib/src/NeighborList.cpp @@ -572,6 +572,58 @@ build_nlist (vector > & nlist0, } } + +void +build_nlist (vector > & nlist0, + vector > & nlist1, + const vector & posi3, + const double & rc0_, + const double & rc1_, + const SimulationRegion * region) +{ + double rc0 (rc0_); + double rc1 (rc1_); + assert (rc0 <= rc1); + double rc02 = rc0 * rc0; + // negative rc0 means not applying rc0 + if (rc0 < 0) rc02 = 0; + double rc12 = rc1 * rc1; + + unsigned natoms = posi3.size()/3; + nlist0.clear(); + nlist1.clear(); + nlist0.resize(natoms); + nlist1.resize(natoms); + for (unsigned ii = 0; ii < natoms; ++ii){ + nlist0[ii].reserve (60); + nlist1[ii].reserve (60); + } + for (unsigned ii = 0; ii < natoms; ++ii){ + for (unsigned jj = ii+1; jj < natoms; ++jj){ + double diff[3]; + if (region != NULL) { + region->diffNearestNeighbor (posi3[jj*3+0], posi3[jj*3+1], posi3[jj*3+2], + posi3[ii*3+0], posi3[ii*3+1], posi3[ii*3+2], + diff[0], diff[1], diff[2]); + } + else { + diff[0] = posi3[jj*3+0] - posi3[ii*3+0]; + diff[1] = posi3[jj*3+1] - posi3[ii*3+1]; + diff[2] = posi3[jj*3+2] - posi3[ii*3+2]; + } + double r2 = MathUtilities::dot (diff, diff); + if (r2 < rc02) { + nlist0[ii].push_back (jj); + nlist0[jj].push_back (ii); + } + else if (r2 < rc12) { + nlist1[ii].push_back (jj); + nlist1[jj].push_back (ii); + } + } + } +} + static int compute_pbc_shift (int idx, int ncell) { diff --git a/source/op/descrpt.cc b/source/op/descrpt.cc index 4e55049400..75c7640b2b 100644 --- a/source/op/descrpt.cc +++ b/source/op/descrpt.cc @@ -120,15 +120,34 @@ class DescrptOp : public OpKernel { int nei_mode = 0; if (mesh_tensor.shape().dim_size(0) == 16) { + // lammps neighbor list nei_mode = 3; } else if (mesh_tensor.shape().dim_size(0) == 12) { + // user provided extended mesh nei_mode = 2; } else if (mesh_tensor.shape().dim_size(0) == 6) { + // manual copied pbc assert (nloc == nall); nei_mode = 1; } + else if (mesh_tensor.shape().dim_size(0) == 0) { + // no pbc + nei_mode = -1; + } + else { + throw runtime_error("invalid mesh tensor"); + } + bool b_pbc = true; + // if region is given extended, do not use pbc + if (nei_mode >= 1 || nei_mode == -1) { + b_pbc = false; + } + bool b_norm_atom = false; + if (nei_mode == 1){ + b_norm_atom = true; + } // Create an output tensor TensorShape descrpt_shape ; @@ -200,7 +219,7 @@ class DescrptOp : public OpKernel { for (int dd = 0; dd < 3; ++dd){ d_coord3[ii*3+dd] = coord(kk, ii*3+dd); } - if (nei_mode <= 1){ + if (b_norm_atom){ compute_t inter[3]; region.phys2Inter (inter, &d_coord3[3*ii]); for (int dd = 0; dd < 3; ++dd){ @@ -263,14 +282,11 @@ class DescrptOp : public OpKernel { } ::build_nlist (d_nlist_a, d_nlist_r, d_coord3, nloc, rcut_a, rcut_r, nat_stt, ncell, ext_stt, ext_end, region, ncell); } - else { - build_nlist (d_nlist_a, d_nlist_r, rcut_a, rcut_r, d_coord3, region); + else if (nei_mode == -1){ + ::build_nlist (d_nlist_a, d_nlist_r, d_coord3, rcut_a, rcut_r, NULL); } - - bool b_pbc = true; - // if region is given extended, do not use pbc - if (nei_mode >= 1) { - b_pbc = false; + else { + throw runtime_error("unknow neighbor mode"); } // loop over atoms, compute descriptors for each atom @@ -399,48 +415,6 @@ class DescrptOp : public OpKernel { } } void - build_nlist (vector > & nlist0, - vector > & nlist1, - const compute_t & rc0_, - const compute_t & rc1_, - const vector & posi3, - const SimulationRegion & region) const { - compute_t rc0 (rc0_); - compute_t rc1 (rc1_); - assert (rc0 <= rc1); - compute_t rc02 = rc0 * rc0; - // negative rc0 means not applying rc0 - if (rc0 < 0) rc02 = 0; - compute_t rc12 = rc1 * rc1; - - unsigned natoms = posi3.size()/3; - nlist0.clear(); - nlist1.clear(); - nlist0.resize(natoms); - nlist1.resize(natoms); - for (unsigned ii = 0; ii < natoms; ++ii){ - nlist0[ii].reserve (60); - nlist1[ii].reserve (60); - } - for (unsigned ii = 0; ii < natoms; ++ii){ - for (unsigned jj = ii+1; jj < natoms; ++jj){ - compute_t diff[3]; - region.diffNearestNeighbor (posi3[jj*3+0], posi3[jj*3+1], posi3[jj*3+2], - posi3[ii*3+0], posi3[ii*3+1], posi3[ii*3+2], - diff[0], diff[1], diff[2]); - compute_t r2 = MathUtilities::dot (diff, diff); - if (r2 < rc02) { - nlist0[ii].push_back (jj); - nlist0[jj].push_back (ii); - } - else if (r2 < rc12) { - nlist1[ii].push_back (jj); - nlist1[jj].push_back (ii); - } - } - } - } - void make_axis (vector & axis_type, vector & axis_idx, const int & type, diff --git a/source/op/descrpt_se_a.cc b/source/op/descrpt_se_a.cc index 1764191b5a..b970f6dbf0 100644 --- a/source/op/descrpt_se_a.cc +++ b/source/op/descrpt_se_a.cc @@ -119,15 +119,34 @@ class DescrptSeAOp : public OpKernel { int nei_mode = 0; if (mesh_tensor.shape().dim_size(0) == 16) { + // lammps neighbor list nei_mode = 3; } else if (mesh_tensor.shape().dim_size(0) == 12) { + // user provided extended mesh nei_mode = 2; } else if (mesh_tensor.shape().dim_size(0) == 6) { + // manual copied pbc assert (nloc == nall); nei_mode = 1; } + else if (mesh_tensor.shape().dim_size(0) == 0) { + // no pbc + nei_mode = -1; + } + else { + throw runtime_error("invalid mesh tensor"); + } + bool b_pbc = true; + // if region is given extended, do not use pbc + if (nei_mode >= 1 || nei_mode == -1) { + b_pbc = false; + } + bool b_norm_atom = false; + if (nei_mode == 1){ + b_norm_atom = true; + } // Create an output tensor TensorShape descrpt_shape ; @@ -196,7 +215,7 @@ class DescrptSeAOp : public OpKernel { for (int dd = 0; dd < 3; ++dd){ d_coord3[ii*3+dd] = coord(kk, ii*3+dd); } - if (nei_mode <= 1){ + if (b_norm_atom){ compute_t inter[3]; region.phys2Inter (inter, &d_coord3[3*ii]); for (int dd = 0; dd < 3; ++dd){ @@ -259,14 +278,11 @@ class DescrptSeAOp : public OpKernel { } ::build_nlist (d_nlist_a, d_nlist_r, d_coord3, nloc, rcut_a, rcut_r, nat_stt, ncell, ext_stt, ext_end, region, ncell); } - else { - build_nlist (d_nlist_a, d_nlist_r, rcut_a, rcut_r, d_coord3, region); + else if (nei_mode == -1){ + ::build_nlist (d_nlist_a, d_nlist_r, d_coord3, rcut_a, rcut_r, NULL); } - - bool b_pbc = true; - // if region is given extended, do not use pbc - if (nei_mode >= 1) { - b_pbc = false; + else { + throw runtime_error("unknow neighbor mode"); } // loop over atoms, compute descriptors for each atom @@ -351,48 +367,6 @@ class DescrptSeAOp : public OpKernel { sec[ii] = sec[ii-1] + n_sel[ii-1]; } } - void - build_nlist (vector > & nlist0, - vector > & nlist1, - const compute_t & rc0_, - const compute_t & rc1_, - const vector & posi3, - const SimulationRegion & region) const { - compute_t rc0 (rc0_); - compute_t rc1 (rc1_); - assert (rc0 <= rc1); - compute_t rc02 = rc0 * rc0; - // negative rc0 means not applying rc0 - if (rc0 < 0) rc02 = 0; - compute_t rc12 = rc1 * rc1; - - unsigned natoms = posi3.size()/3; - nlist0.clear(); - nlist1.clear(); - nlist0.resize(natoms); - nlist1.resize(natoms); - for (unsigned ii = 0; ii < natoms; ++ii){ - nlist0[ii].reserve (60); - nlist1[ii].reserve (60); - } - for (unsigned ii = 0; ii < natoms; ++ii){ - for (unsigned jj = ii+1; jj < natoms; ++jj){ - compute_t diff[3]; - region.diffNearestNeighbor (posi3[jj*3+0], posi3[jj*3+1], posi3[jj*3+2], - posi3[ii*3+0], posi3[ii*3+1], posi3[ii*3+2], - diff[0], diff[1], diff[2]); - compute_t r2 = MathUtilities::dot (diff, diff); - if (r2 < rc02) { - nlist0[ii].push_back (jj); - nlist0[jj].push_back (ii); - } - else if (r2 < rc12) { - nlist1[ii].push_back (jj); - nlist1[jj].push_back (ii); - } - } - } - } }; REGISTER_KERNEL_BUILDER(Name("DescrptSeA").Device(DEVICE_CPU), DescrptSeAOp); diff --git a/source/op/descrpt_se_r.cc b/source/op/descrpt_se_r.cc index 04624d1e83..6798df503c 100644 --- a/source/op/descrpt_se_r.cc +++ b/source/op/descrpt_se_r.cc @@ -108,15 +108,34 @@ class DescrptSeROp : public OpKernel { int nei_mode = 0; if (mesh_tensor.shape().dim_size(0) == 16) { + // lammps neighbor list nei_mode = 3; } else if (mesh_tensor.shape().dim_size(0) == 12) { + // user provided extended mesh nei_mode = 2; } else if (mesh_tensor.shape().dim_size(0) == 6) { + // manual copied pbc assert (nloc == nall); nei_mode = 1; } + else if (mesh_tensor.shape().dim_size(0) == 0) { + // no pbc + nei_mode = -1; + } + else { + throw runtime_error("invalid mesh tensor"); + } + bool b_pbc = true; + // if region is given extended, do not use pbc + if (nei_mode >= 1 || nei_mode == -1) { + b_pbc = false; + } + bool b_norm_atom = false; + if (nei_mode == 1){ + b_norm_atom = true; + } // Create an output tensor TensorShape descrpt_shape ; @@ -178,7 +197,7 @@ class DescrptSeROp : public OpKernel { for (int dd = 0; dd < 3; ++dd){ d_coord3[ii*3+dd] = coord(kk, ii*3+dd); } - if (nei_mode <= 1){ + if (b_norm_atom){ compute_t inter[3]; region.phys2Inter (inter, &d_coord3[3*ii]); for (int dd = 0; dd < 3; ++dd){ @@ -241,14 +260,11 @@ class DescrptSeROp : public OpKernel { } ::build_nlist (d_nlist_null, d_nlist, d_coord3, nloc, -1, rcut, nat_stt, ncell, ext_stt, ext_end, region, ncell); } - else { - build_nlist (d_nlist_null, d_nlist, -1, rcut, d_coord3, region); + else if (nei_mode == -1){ + ::build_nlist (d_nlist_null, d_nlist, d_coord3, -1, rcut, NULL); } - - bool b_pbc = true; - // if region is given extended, do not use pbc - if (nei_mode >= 1) { - b_pbc = false; + else { + throw runtime_error("unknow neighbor mode"); } // loop over atoms, compute descriptors for each atom @@ -333,48 +349,6 @@ class DescrptSeROp : public OpKernel { sec[ii] = sec[ii-1] + n_sel[ii-1]; } } - void - build_nlist (vector > & nlist0, - vector > & nlist1, - const compute_t & rc0_, - const compute_t & rc1_, - const vector & posi3, - const SimulationRegion & region) const { - compute_t rc0 (rc0_); - compute_t rc1 (rc1_); - assert (rc0 <= rc1); - compute_t rc02 = rc0 * rc0; - // negative rc0 means not applying rc0 - if (rc0 < 0) rc02 = 0; - compute_t rc12 = rc1 * rc1; - - unsigned natoms = posi3.size()/3; - nlist0.clear(); - nlist1.clear(); - nlist0.resize(natoms); - nlist1.resize(natoms); - for (unsigned ii = 0; ii < natoms; ++ii){ - nlist0[ii].reserve (60); - nlist1[ii].reserve (60); - } - for (unsigned ii = 0; ii < natoms; ++ii){ - for (unsigned jj = ii+1; jj < natoms; ++jj){ - compute_t diff[3]; - region.diffNearestNeighbor (posi3[jj*3+0], posi3[jj*3+1], posi3[jj*3+2], - posi3[ii*3+0], posi3[ii*3+1], posi3[ii*3+2], - diff[0], diff[1], diff[2]); - compute_t r2 = MathUtilities::dot (diff, diff); - if (r2 < rc02) { - nlist0[ii].push_back (jj); - nlist0[jj].push_back (ii); - } - else if (r2 < rc12) { - nlist1[ii].push_back (jj); - nlist1[jj].push_back (ii); - } - } - } - } }; REGISTER_KERNEL_BUILDER(Name("DescrptSeR").Device(DEVICE_CPU), DescrptSeROp); diff --git a/source/tests/common.py b/source/tests/common.py index e9ad53dbf2..f92fe397cc 100644 --- a/source/tests/common.py +++ b/source/tests/common.py @@ -35,7 +35,8 @@ def gen_data() : class Data(): def __init__ (self, rand_pert = 0.1, - seed = 1) : + seed = 1, + box_scale = 20) : coord = [[0.0, 0.0, 0.1], [1.1, 0.0, 0.1], [0.0, 1.1, 0.1], [4.0, 0.0, 0.0], [5.1, 0.0, 0.0], [4.0, 1.1, 0.0]] self.nframes = 1 @@ -48,7 +49,7 @@ def __init__ (self, self.fparam = self._copy_nframes(self.fparam) self.aparam = self._copy_nframes(self.aparam) self.atype = np.array([0, 1, 1, 0, 1, 1], dtype = int) - self.cell = 20 * np.eye(3) + self.cell = box_scale * np.eye(3) self.cell = self._copy_nframes(self.cell) self.coord = self.coord.reshape([self.nframes, -1]) self.cell = self.cell.reshape([self.nframes, -1]) diff --git a/source/tests/test_descrpt_nonsmth.py b/source/tests/test_descrpt_nonsmth.py index 91a8915ef8..7d12e01e74 100644 --- a/source/tests/test_descrpt_nonsmth.py +++ b/source/tests/test_descrpt_nonsmth.py @@ -26,7 +26,8 @@ class Inter(): def setUp (self, data, - comp = 0) : + comp = 0, + pbc = True) : self.sess = tf.Session() self.data = data self.natoms = self.data.get_natoms() @@ -46,10 +47,13 @@ def setUp (self, dstd = np.ones ([self.ntypes, self.ndescrpt]) self.t_avg = tf.constant(davg.astype(global_np_float_precision)) self.t_std = tf.constant(dstd.astype(global_np_float_precision)) - self.default_mesh = np.zeros (6, dtype = np.int32) - self.default_mesh[3] = 2 - self.default_mesh[4] = 2 - self.default_mesh[5] = 2 + if pbc: + self.default_mesh = np.zeros (6, dtype = np.int32) + self.default_mesh[3] = 2 + self.default_mesh[4] = 2 + self.default_mesh[5] = 2 + else : + self.default_mesh = np.array([], dtype = np.int32) # make place holder self.coord = tf.placeholder(global_tf_float_precision, [None, self.natoms[0] * 3], name='t_coord') self.box = tf.placeholder(global_tf_float_precision, [None, 9], name='t_box') @@ -179,5 +183,88 @@ def test_virial_dw (self) : virial_dw_test(self, self, suffix = '_se') +class TestLFPbc(unittest.TestCase): + def test_pbc(self): + data = Data() + inter0 = Inter() + inter1 = Inter() + inter0.setUp(data, pbc = True) + inter1.setUp(data, pbc = False) + inter0.net_w_i = np.copy(np.ones(inter0.ndescrpt)) + inter1.net_w_i = np.copy(np.ones(inter1.ndescrpt)) + + t_energy0, t_force0, t_virial0 \ + = inter0.comp_ef (inter0.coord, inter0.box, inter0.type, inter0.tnatoms, name = "test_lf_pbc_true") + t_energy1, t_force1, t_virial1 \ + = inter1.comp_ef (inter1.coord, inter1.box, inter1.type, inter1.tnatoms, name = "test_lf_pbc_false") + + inter0.sess.run (tf.global_variables_initializer()) + inter1.sess.run (tf.global_variables_initializer()) + + dcoord, dbox, dtype = data.get_data () + + [e0, f0, v0] = inter0.sess.run ([t_energy0, t_force0, t_virial0], + feed_dict = { + inter0.coord: dcoord, + inter0.box: dbox, + inter0.type: dtype, + inter0.tnatoms: inter0.natoms}) + [e1, f1, v1] = inter1.sess.run ([t_energy1, t_force1, t_virial1], + feed_dict = { + inter1.coord: dcoord, + inter1.box: dbox, + inter1.type: dtype, + inter1.tnatoms: inter1.natoms}) + + self.assertAlmostEqual(e0[0], e1[0]) + for ii in range(f0[0].size): + # print(ii) + self.assertAlmostEqual(f0[0][ii], f1[0][ii]) + for ii in range(v0[0].size): + # print(ii) + self.assertAlmostEqual(v0[0][ii], v1[0][ii]) + + def test_pbc_small_box(self): + data0 = Data() + data1 = Data(box_scale = 2) + inter0 = Inter() + inter1 = Inter() + inter0.setUp(data0, pbc = True) + inter1.setUp(data1, pbc = False) + inter0.net_w_i = np.copy(np.ones(inter0.ndescrpt)) + inter1.net_w_i = np.copy(np.ones(inter1.ndescrpt)) + + t_energy0, t_force0, t_virial0 \ + = inter0.comp_ef (inter0.coord, inter0.box, inter0.type, inter0.tnatoms, name = "test_lf_pbc_sbox_true") + t_energy1, t_force1, t_virial1 \ + = inter1.comp_ef (inter1.coord, inter1.box, inter1.type, inter1.tnatoms, name = "test_lf_pbc_sbox_false") + + inter0.sess.run (tf.global_variables_initializer()) + inter1.sess.run (tf.global_variables_initializer()) + + dcoord, dbox, dtype = data0.get_data () + [e0, f0, v0] = inter0.sess.run ([t_energy0, t_force0, t_virial0], + feed_dict = { + inter0.coord: dcoord, + inter0.box: dbox, + inter0.type: dtype, + inter0.tnatoms: inter0.natoms}) + dcoord, dbox, dtype = data1.get_data () + [e1, f1, v1] = inter1.sess.run ([t_energy1, t_force1, t_virial1], + feed_dict = { + inter1.coord: dcoord, + inter1.box: dbox, + inter1.type: dtype, + inter1.tnatoms: inter1.natoms}) + + self.assertAlmostEqual(e0[0], e1[0]) + for ii in range(f0[0].size): + # print(ii) + self.assertAlmostEqual(f0[0][ii], f1[0][ii]) + for ii in range(v0[0].size): + # print(ii) + self.assertAlmostEqual(v0[0][ii], v1[0][ii]) + + if __name__ == '__main__': unittest.main() diff --git a/source/tests/test_descrpt_se_r.py b/source/tests/test_descrpt_se_r.py index ece2fb229c..fa21712f90 100644 --- a/source/tests/test_descrpt_se_r.py +++ b/source/tests/test_descrpt_se_r.py @@ -27,7 +27,8 @@ class Inter(): def setUp (self, - data) : + data, + pbc = True) : self.sess = tf.Session() self.data = data self.natoms = self.data.get_natoms() @@ -42,10 +43,13 @@ def setUp (self, dstd = np.ones ([self.ntypes, self.ndescrpt]) self.t_avg = tf.constant(davg.astype(global_np_float_precision)) self.t_std = tf.constant(dstd.astype(global_np_float_precision)) - self.default_mesh = np.zeros (6, dtype = np.int32) - self.default_mesh[3] = 2 - self.default_mesh[4] = 2 - self.default_mesh[5] = 2 + if pbc: + self.default_mesh = np.zeros (6, dtype = np.int32) + self.default_mesh[3] = 2 + self.default_mesh[4] = 2 + self.default_mesh[5] = 2 + else: + self.default_mesh = np.array([], dtype = np.int32) # make place holder self.coord = tf.placeholder(global_tf_float_precision, [None, self.natoms[0] * 3], name='t_coord') self.box = tf.placeholder(global_tf_float_precision, [None, 9], name='t_box') @@ -161,5 +165,89 @@ def test_virial_dw (self) : virial_dw_test(self, self, suffix = '_se_r') +class TestSeRPbc(unittest.TestCase): + def test_pbc(self): + data = Data() + inter0 = Inter() + inter1 = Inter() + inter0.setUp(data, pbc = True) + inter1.setUp(data, pbc = False) + inter0.net_w_i = np.copy(np.ones(inter0.ndescrpt)) + inter1.net_w_i = np.copy(np.ones(inter1.ndescrpt)) + + t_energy0, t_force0, t_virial0 \ + = inter0.comp_ef (inter0.coord, inter0.box, inter0.type, inter0.tnatoms, name = "test_ser_pbc_true") + t_energy1, t_force1, t_virial1 \ + = inter1.comp_ef (inter1.coord, inter1.box, inter1.type, inter1.tnatoms, name = "test_ser_pbc_false") + + inter0.sess.run (tf.global_variables_initializer()) + inter1.sess.run (tf.global_variables_initializer()) + + dcoord, dbox, dtype = data.get_data () + + [e0, f0, v0] = inter0.sess.run ([t_energy0, t_force0, t_virial0], + feed_dict = { + inter0.coord: dcoord, + inter0.box: dbox, + inter0.type: dtype, + inter0.tnatoms: inter0.natoms}) + [e1, f1, v1] = inter1.sess.run ([t_energy1, t_force1, t_virial1], + feed_dict = { + inter1.coord: dcoord, + inter1.box: dbox, + inter1.type: dtype, + inter1.tnatoms: inter1.natoms}) + + self.assertAlmostEqual(e0[0], e1[0]) + for ii in range(f0[0].size): + # print(ii) + self.assertAlmostEqual(f0[0][ii], f1[0][ii]) + for ii in range(v0[0].size): + # print(ii) + self.assertAlmostEqual(v0[0][ii], v1[0][ii]) + + + def test_pbc_small_box(self): + data0 = Data() + data1 = Data(box_scale = 2) + inter0 = Inter() + inter1 = Inter() + inter0.setUp(data0, pbc = True) + inter1.setUp(data1, pbc = False) + inter0.net_w_i = np.copy(np.ones(inter0.ndescrpt)) + inter1.net_w_i = np.copy(np.ones(inter1.ndescrpt)) + + t_energy0, t_force0, t_virial0 \ + = inter0.comp_ef (inter0.coord, inter0.box, inter0.type, inter0.tnatoms, name = "test_ser_pbc_sbox_true") + t_energy1, t_force1, t_virial1 \ + = inter1.comp_ef (inter1.coord, inter1.box, inter1.type, inter1.tnatoms, name = "test_ser_pbc_sbox_false") + + inter0.sess.run (tf.global_variables_initializer()) + inter1.sess.run (tf.global_variables_initializer()) + + dcoord, dbox, dtype = data0.get_data () + [e0, f0, v0] = inter0.sess.run ([t_energy0, t_force0, t_virial0], + feed_dict = { + inter0.coord: dcoord, + inter0.box: dbox, + inter0.type: dtype, + inter0.tnatoms: inter0.natoms}) + dcoord, dbox, dtype = data1.get_data () + [e1, f1, v1] = inter1.sess.run ([t_energy1, t_force1, t_virial1], + feed_dict = { + inter1.coord: dcoord, + inter1.box: dbox, + inter1.type: dtype, + inter1.tnatoms: inter1.natoms}) + + self.assertAlmostEqual(e0[0], e1[0]) + for ii in range(f0[0].size): + # print(ii) + self.assertAlmostEqual(f0[0][ii], f1[0][ii]) + for ii in range(v0[0].size): + # print(ii) + self.assertAlmostEqual(v0[0][ii], v1[0][ii]) + + if __name__ == '__main__': unittest.main() diff --git a/source/tests/test_descrpt_smooth.py b/source/tests/test_descrpt_smooth.py index 415f56a9aa..7876fbfc3b 100644 --- a/source/tests/test_descrpt_smooth.py +++ b/source/tests/test_descrpt_smooth.py @@ -27,7 +27,8 @@ class Inter(): def setUp (self, - data) : + data, + pbc = True) : self.sess = tf.Session() self.data = data self.natoms = self.data.get_natoms() @@ -47,10 +48,13 @@ def setUp (self, dstd = np.ones ([self.ntypes, self.ndescrpt]) self.t_avg = tf.constant(davg.astype(global_np_float_precision)) self.t_std = tf.constant(dstd.astype(global_np_float_precision)) - self.default_mesh = np.zeros (6, dtype = np.int32) - self.default_mesh[3] = 2 - self.default_mesh[4] = 2 - self.default_mesh[5] = 2 + if pbc: + self.default_mesh = np.zeros (6, dtype = np.int32) + self.default_mesh[3] = 2 + self.default_mesh[4] = 2 + self.default_mesh[5] = 2 + else: + self.default_mesh = np.array([], dtype = np.int32) # make place holder self.coord = tf.placeholder(global_tf_float_precision, [None, self.natoms[0] * 3], name='t_coord') self.box = tf.placeholder(global_tf_float_precision, [None, 9], name='t_box') @@ -172,5 +176,88 @@ def test_virial_dw (self) : virial_dw_test(self, self, suffix = '_smth') +class TestSeAPbc(unittest.TestCase): + def test_pbc(self): + data = Data() + inter0 = Inter() + inter1 = Inter() + inter0.setUp(data, pbc = True) + inter1.setUp(data, pbc = False) + inter0.net_w_i = np.copy(np.ones(inter0.ndescrpt)) + inter1.net_w_i = np.copy(np.ones(inter1.ndescrpt)) + + t_energy0, t_force0, t_virial0 \ + = inter0.comp_ef (inter0.coord, inter0.box, inter0.type, inter0.tnatoms, name = "test_sea_pbc_true") + t_energy1, t_force1, t_virial1 \ + = inter1.comp_ef (inter1.coord, inter1.box, inter1.type, inter1.tnatoms, name = "test_sea_pbc_false") + + inter0.sess.run (tf.global_variables_initializer()) + inter1.sess.run (tf.global_variables_initializer()) + + dcoord, dbox, dtype = data.get_data () + + [e0, f0, v0] = inter0.sess.run ([t_energy0, t_force0, t_virial0], + feed_dict = { + inter0.coord: dcoord, + inter0.box: dbox, + inter0.type: dtype, + inter0.tnatoms: inter0.natoms}) + [e1, f1, v1] = inter1.sess.run ([t_energy1, t_force1, t_virial1], + feed_dict = { + inter1.coord: dcoord, + inter1.box: dbox, + inter1.type: dtype, + inter1.tnatoms: inter1.natoms}) + + self.assertAlmostEqual(e0[0], e1[0]) + for ii in range(f0[0].size): + # print(ii) + self.assertAlmostEqual(f0[0][ii], f1[0][ii]) + for ii in range(v0[0].size): + # print(ii) + self.assertAlmostEqual(v0[0][ii], v1[0][ii]) + + def test_pbc_small_box(self): + data0 = Data() + data1 = Data(box_scale = 2) + inter0 = Inter() + inter1 = Inter() + inter0.setUp(data0, pbc = True) + inter1.setUp(data1, pbc = False) + inter0.net_w_i = np.copy(np.ones(inter0.ndescrpt)) + inter1.net_w_i = np.copy(np.ones(inter1.ndescrpt)) + + t_energy0, t_force0, t_virial0 \ + = inter0.comp_ef (inter0.coord, inter0.box, inter0.type, inter0.tnatoms, name = "test_sea_pbc_sbox_true") + t_energy1, t_force1, t_virial1 \ + = inter1.comp_ef (inter1.coord, inter1.box, inter1.type, inter1.tnatoms, name = "test_sea_pbc_sbox_false") + + inter0.sess.run (tf.global_variables_initializer()) + inter1.sess.run (tf.global_variables_initializer()) + + dcoord, dbox, dtype = data0.get_data () + [e0, f0, v0] = inter0.sess.run ([t_energy0, t_force0, t_virial0], + feed_dict = { + inter0.coord: dcoord, + inter0.box: dbox, + inter0.type: dtype, + inter0.tnatoms: inter0.natoms}) + dcoord, dbox, dtype = data1.get_data () + [e1, f1, v1] = inter1.sess.run ([t_energy1, t_force1, t_virial1], + feed_dict = { + inter1.coord: dcoord, + inter1.box: dbox, + inter1.type: dtype, + inter1.tnatoms: inter1.natoms}) + + self.assertAlmostEqual(e0[0], e1[0]) + for ii in range(f0[0].size): + # print(ii) + self.assertAlmostEqual(f0[0][ii], f1[0][ii]) + for ii in range(v0[0].size): + # print(ii) + self.assertAlmostEqual(v0[0][ii], v1[0][ii]) + + if __name__ == '__main__': unittest.main() From 258731f18a6cf4919a2e32a57d72fceaca570d2a Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 20 Dec 2019 17:25:01 +0800 Subject: [PATCH 040/147] fix the virial assembly bug, no influence on the results --- source/op/prod_virial_se_r.cc | 2 +- source/op/prod_virial_se_r_grad.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/op/prod_virial_se_r.cc b/source/op/prod_virial_se_r.cc index f9b5a71d84..1d21234421 100644 --- a/source/op/prod_virial_se_r.cc +++ b/source/op/prod_virial_se_r.cc @@ -122,7 +122,7 @@ class ProdVirialSeROp : public OpKernel { VALUETYPE pref = -1.0 * net_deriv (net_iter + i_idx * ndescrpt + jj); for (int dd0 = 0; dd0 < 3; ++dd0){ for (int dd1 = 0; dd1 < 3; ++dd1){ - VALUETYPE tmp_v = pref * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd0) * in_deriv (in_iter + i_idx * ndescrpt * 3 + jj * 3 + dd1); + VALUETYPE tmp_v = pref * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd1) * in_deriv (in_iter + i_idx * ndescrpt * 3 + jj * 3 + dd0); virial (virial_iter + dd0 * 3 + dd1) -= tmp_v; atom_virial (atom_virial_iter + j_idx * 9 + dd0 * 3 + dd1) -= tmp_v; } diff --git a/source/op/prod_virial_se_r_grad.cc b/source/op/prod_virial_se_r_grad.cc index 002aa1b907..20b53cf3c9 100644 --- a/source/op/prod_virial_se_r_grad.cc +++ b/source/op/prod_virial_se_r_grad.cc @@ -126,7 +126,7 @@ class ProdVirialSeRGradOp : public OpKernel for (int dd0 = 0; dd0 < 3; ++dd0){ for (int dd1 = 0; dd1 < 3; ++dd1){ grad_net (grad_net_iter + i_idx * ndescrpt + jj) -= - -1.0 * grad (grad_iter + dd0 * 3 + dd1) * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd0) * in_deriv (in_iter + i_idx * ndescrpt * 3 + jj * 3 + dd1); + -1.0 * grad (grad_iter + dd0 * 3 + dd1) * rij (rij_iter + i_idx * nnei * 3 + jj * 3 + dd1) * in_deriv (in_iter + i_idx * ndescrpt * 3 + jj * 3 + dd0); } } } From 8f09de9e28afbba8287bba16c78dc2b49b1143fb Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 20 Dec 2019 19:05:23 +0800 Subject: [PATCH 041/147] support no-pbc-training --- source/train/Data.py | 8 ++++++++ source/train/DataSystem.py | 24 ++++++++++++++---------- source/train/DeepPot.py | 26 ++++++++++++++++++-------- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/source/train/Data.py b/source/train/Data.py index d5a91f6b7b..4de2f52627 100644 --- a/source/train/Data.py +++ b/source/train/Data.py @@ -25,6 +25,8 @@ def __init__ (self, self.type_map = self._load_type_map(sys_path) if self.type_map is not None: assert(len(self.type_map) >= max(self.atom_type)+1) + # check pbc + self.pbc = self._check_pbc(sys_path) # enforce type_map if necessary if type_map is not None and self.type_map is not None: atom_type_ = [type_map.index(self.type_map[ii]) for ii in self.atom_type] @@ -348,6 +350,12 @@ def _load_type_map(self, sys_path) : else : return None + def _check_pbc(self, sys_path): + pbc = True + if os.path.isfile(os.path.join(sys_path, 'nopbc')) : + pbc = False + return pbc + class DataSets (object): def __init__ (self, diff --git a/source/train/DataSystem.py b/source/train/DataSystem.py index 997baf878c..c1dff9f06b 100644 --- a/source/train/DataSystem.py +++ b/source/train/DataSystem.py @@ -95,20 +95,24 @@ def _load_test(self, ntests = -1): for nn in test_system_data: self.test_data[nn].append(test_system_data[nn]) + def _make_default_mesh(self): self.default_mesh = [] cell_size = np.max (self.rcut) for ii in range(self.nsystems) : - test_system_data = self.data_systems[ii].get_batch(self.batch_size[ii]) - self.data_systems[ii].reset_get_batch() - # test_system_data = self.data_systems[ii].get_test() - avg_box = np.average (test_system_data["box"], axis = 0) - avg_box = np.reshape (avg_box, [3,3]) - ncell = (np.linalg.norm(avg_box, axis=1)/ cell_size).astype(np.int32) - ncell[ncell < 2] = 2 - default_mesh = np.zeros (6, dtype = np.int32) - default_mesh[3:6] = ncell - self.default_mesh.append(default_mesh) + if self.data_systems[ii].pbc : + test_system_data = self.data_systems[ii].get_batch(self.batch_size[ii]) + self.data_systems[ii].reset_get_batch() + # test_system_data = self.data_systems[ii].get_test() + avg_box = np.average (test_system_data["box"], axis = 0) + avg_box = np.reshape (avg_box, [3,3]) + ncell = (np.linalg.norm(avg_box, axis=1)/ cell_size).astype(np.int32) + ncell[ncell < 2] = 2 + default_mesh = np.zeros (6, dtype = np.int32) + default_mesh[3:6] = ncell + self.default_mesh.append(default_mesh) + else: + self.default_mesh.append(np.array([], dtype = np.int32)) def compute_energy_shift(self, rcond = 1e-3, key = 'energy') : diff --git a/source/train/DeepPot.py b/source/train/DeepPot.py index 88bf92f63d..09519fc0e1 100644 --- a/source/train/DeepPot.py +++ b/source/train/DeepPot.py @@ -53,6 +53,8 @@ def __init__(self, self.modifier_type = self.sess.run(t_modifier_type).decode('UTF-8') except ValueError: self.modifier_type = None + except KeyError: + self.modifier_type = None if self.modifier_type == 'dipole_charge': t_mdl_name = self.graph.get_tensor_by_name('load/modifier_attr/mdl_name:0') t_mdl_charge_map = self.graph.get_tensor_by_name('load/modifier_attr/mdl_charge_map:0') @@ -108,9 +110,18 @@ def eval_inner(self, aparam = None, atomic = False) : # standarize the shape of inputs - coords = np.array(coords) - cells = np.array(cells) - atom_types = np.array(atom_types, dtype = int) + atom_types = np.array(atom_types, dtype = int).reshape([-1]) + natoms = atom_types.size + coords = np.reshape(np.array(coords), [-1, natoms * 3]) + nframes = coords.shape[0] + if cells is None: + pbc = False + # make cells to work around the requirement of pbc + cells = np.tile(np.eye(3), [nframes, 1]).reshape([nframes, 9]) + else: + pbc = True + cells = np.array(cells).reshape([nframes, 9]) + if self.has_fparam : assert(fparam is not None) fparam = np.array(fparam) @@ -119,10 +130,6 @@ def eval_inner(self, aparam = np.array(aparam) # reshape the inputs - cells = np.reshape(cells, [-1, 9]) - nframes = cells.shape[0] - coords = np.reshape(coords, [nframes, -1]) - natoms = coords.shape[1] // 3 if self.has_fparam : fdim = self.get_dim_fparam() if fparam.size == nframes * fdim : @@ -167,7 +174,10 @@ def eval_inner(self, for ii in range(nframes) : feed_dict_test[self.t_coord] = np.reshape(coords[ii:ii+1, :], [-1]) feed_dict_test[self.t_box ] = np.reshape(cells [ii:ii+1, :], [-1]) - feed_dict_test[self.t_mesh ] = make_default_mesh(cells[ii:ii+1, :]) + if pbc: + feed_dict_test[self.t_mesh ] = make_default_mesh(cells[ii:ii+1, :]) + else: + feed_dict_test[self.t_mesh ] = np.array([], dtype = np.int32) if self.has_fparam: feed_dict_test[self.t_fparam] = np.reshape(fparam[ii:ii+1, :], [-1]) if self.has_aparam: From b9980776ac62b978f7876ee0f219cfb514d7a6e8 Mon Sep 17 00:00:00 2001 From: Lu Date: Fri, 20 Dec 2019 22:09:07 +0800 Subject: [PATCH 042/147] fix the virial assembly bug, no influence on the results fixed same issue with cuda code --- source/op/cuda/prod_virial_se_a.cu | 5 ++++- source/op/cuda/prod_virial_se_r.cu | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/source/op/cuda/prod_virial_se_a.cu b/source/op/cuda/prod_virial_se_a.cu index f93e14bcec..241e2b7e06 100644 --- a/source/op/cuda/prod_virial_se_a.cu +++ b/source/op/cuda/prod_virial_se_a.cu @@ -45,6 +45,9 @@ __global__ void deriv_wrt_neighbors_se_a(VALUETYPE * virial, { // idx -> nloc // idy -> nnei + // idz = dd0 * 3 + dd1 + // dd0 = idz / 3 + // dd1 = idz % 3 const unsigned int idx = blockIdx.x * blockDim.x + threadIdx.x; const unsigned int idy = blockIdx.y; const unsigned int idz = threadIdx.y; @@ -58,7 +61,7 @@ __global__ void deriv_wrt_neighbors_se_a(VALUETYPE * virial, return; } // atomicAdd(virial + idz, net_deriv[idx * ndescrpt + idy * 4 + idw] * rij[idx * nnei * 3 + idy * 3 + idz / 3] * in_deriv[idx * ndescrpt * 3 + (idy * 4 + idw) * 3 + idz % 3]); - atomicAdd(atom_virial + j_idx * 9 + idz, net_deriv[idx * ndescrpt + idy * 4 + idw] * rij[idx * nnei * 3 + idy * 3 + idz / 3] * in_deriv[idx * ndescrpt * 3 + (idy * 4 + idw) * 3 + idz % 3]); + atomicAdd(atom_virial + j_idx * 9 + idz, net_deriv[idx * ndescrpt + idy * 4 + idw] * rij[idx * nnei * 3 + idy * 3 + idz % 3] * in_deriv[idx * ndescrpt * 3 + (idy * 4 + idw) * 3 + idz / 3]); } void ProdVirialSeALauncher(VALUETYPE * virial, diff --git a/source/op/cuda/prod_virial_se_r.cu b/source/op/cuda/prod_virial_se_r.cu index d5b6aad3cc..a2c02007fc 100644 --- a/source/op/cuda/prod_virial_se_r.cu +++ b/source/op/cuda/prod_virial_se_r.cu @@ -47,6 +47,9 @@ __global__ void deriv_wrt_neighbors_se_r(VALUETYPE * virial, { // idx -> nloc // idy -> nnei + // idz = dd0 * 3 + dd1 + // dd0 = idz / 3 + // dd1 = idz % 3 const unsigned int idx = blockIdx.x * blockDim.x + threadIdx.x; const unsigned int idy = blockIdx.y; const unsigned int idz = threadIdx.y; @@ -58,7 +61,7 @@ __global__ void deriv_wrt_neighbors_se_r(VALUETYPE * virial, if (j_idx < 0) { return; } - atomicAdd(atom_virial + j_idx * 9 + idz, net_deriv[idx * ndescrpt + idy] * rij[idx * nnei * 3 + idy * 3 + idz / 3] * in_deriv[idx * ndescrpt * 3 + idy * 3 + idz % 3]); + atomicAdd(atom_virial + j_idx * 9 + idz, net_deriv[idx * ndescrpt + idy] * rij[idx * nnei * 3 + idy * 3 + idz % 3] * in_deriv[idx * ndescrpt * 3 + idy * 3 + idz / 3]); } void ProdVirialSeRLauncher(VALUETYPE * virial, From b88c8325bf05066ecb4f7b751e35dd70c810898d Mon Sep 17 00:00:00 2001 From: Han Wang Date: Tue, 24 Dec 2019 08:31:45 +0800 Subject: [PATCH 043/147] fix bug when compiling with float32 --- source/lib/include/Ewald.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/lib/include/Ewald.h b/source/lib/include/Ewald.h index e115ec3e97..f6bd016337 100644 --- a/source/lib/include/Ewald.h +++ b/source/lib/include/Ewald.h @@ -81,7 +81,7 @@ rec_err_esti(const VALUETYPE & test_q, template void cmpt_k(vector & KK, - const SimulationRegion& region, + const SimulationRegion& region, const EwaldParameters& param) { const double * boxt_ = region.getBoxTensor(); @@ -154,7 +154,8 @@ EwaldReciprocal(VALUETYPE & ener, for (int ii = 0; ii < natoms; ++ii){ int thread_id = omp_get_thread_num(); double ir[3]; - region.phys2Inter(ir, &coord[ii*3]); + double tmpcoord[3] = {coord[ii*3], coord[ii*3+1], coord[ii*3+2]}; + region.phys2Inter(ir, tmpcoord); for (int mm0 = -KK[0]/2; mm0 <= KK[0]/2; ++mm0){ double mr[3]; mr[0] = ir[0] * mm0; From 1c20a694e8f5156dc4f0b6edb77336eeda43db69 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 27 Dec 2019 14:08:06 +0800 Subject: [PATCH 044/147] when the key `systems` is provided with a string, all possible systems will be recursively searched within the dir given by `systems` --- source/train/train.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/train/train.py b/source/train/train.py index 874d66fb6a..1df0b6d80d 100755 --- a/source/train/train.py +++ b/source/train/train.py @@ -85,6 +85,13 @@ def train (args) : # serial training _do_work(jdata, run_opt) +def expand_sys_str(root_dir): + all_sys = [] + from pathlib import Path + for filename in Path(root_dir).rglob('type.raw'): + all_sys.append(os.path.dirname(filename)) + return all_sys + def _do_work(jdata, run_opt): # init the model model = NNPTrainer (jdata, run_opt = run_opt) @@ -93,6 +100,8 @@ def _do_work(jdata, run_opt): # init params and run options assert('training' in jdata) systems = j_must_have(jdata['training'], 'systems') + if type(systems) == str: + systems = expand_sys_str(systems) set_pfx = j_must_have(jdata['training'], 'set_prefix') numb_sys = len(systems) seed = None From c6aaf49ad66b5a828372078d994746c537a7abb1 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 27 Dec 2019 15:36:53 +0800 Subject: [PATCH 045/147] init session only once for data stats --- source/train/DescrptLocFrame.py | 61 +++++++++++++++++++-------------- source/train/DescrptSeA.py | 61 +++++++++++++++++++-------------- source/train/DescrptSeR.py | 56 +++++++++++++++++------------- 3 files changed, 104 insertions(+), 74 deletions(-) diff --git a/source/train/DescrptLocFrame.py b/source/train/DescrptLocFrame.py index 25748e2770..ed1fe6b989 100644 --- a/source/train/DescrptLocFrame.py +++ b/source/train/DescrptLocFrame.py @@ -45,6 +45,33 @@ def __init__(self, jdata): self.davg = None self.dstd = None + self.place_holders = {} + avg_zero = np.zeros([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) + std_ones = np.ones ([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) + sub_graph = tf.Graph() + with sub_graph.as_default(): + name_pfx = 'd_lf_' + for ii in ['coord', 'box']: + self.place_holders[ii] = tf.placeholder(global_np_float_precision, [None, None], name = name_pfx+'t_'+ii) + self.place_holders['type'] = tf.placeholder(tf.int32, [None, None], name=name_pfx+'t_type') + self.place_holders['natoms_vec'] = tf.placeholder(tf.int32, [self.ntypes+2], name=name_pfx+'t_natoms') + self.place_holders['default_mesh'] = tf.placeholder(tf.int32, [None], name=name_pfx+'t_mesh') + self.stat_descrpt, descrpt_deriv, rij, nlist, axis, rot_mat \ + = op_module.descrpt (self.place_holders['coord'], + self.place_holders['type'], + self.place_holders['natoms_vec'], + self.place_holders['box'], + self.place_holders['default_mesh'], + tf.constant(avg_zero), + tf.constant(std_ones), + rcut_a = self.rcut_a, + rcut_r = self.rcut_r, + sel_a = self.sel_a, + sel_r = self.sel_r, + axis_rule = self.axis_rule) + self.sub_sess = tf.Session(graph = sub_graph) + + def get_rcut (self) : return self.rcut_r @@ -174,31 +201,15 @@ def _compute_dstats_sys_nonsmth (self, data_atype, natoms_vec, mesh) : - avg_zero = np.zeros([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) - std_ones = np.ones ([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) - sub_graph = tf.Graph() - with sub_graph.as_default(): - descrpt, descrpt_deriv, rij, nlist, axis, rot_mat \ - = op_module.descrpt (tf.constant(data_coord), - tf.constant(data_atype), - tf.constant(natoms_vec, dtype = tf.int32), - tf.constant(data_box), - tf.constant(mesh), - tf.constant(avg_zero), - tf.constant(std_ones), - rcut_a = self.rcut_a, - rcut_r = self.rcut_r, - sel_a = self.sel_a, - sel_r = self.sel_r, - axis_rule = self.axis_rule) - # self.sess.run(tf.global_variables_initializer()) - # sub_sess = tf.Session(graph = sub_graph, - # config=tf.ConfigProto(intra_op_parallelism_threads=self.run_opt.num_intra_threads, - # inter_op_parallelism_threads=self.run_opt.num_inter_threads - # )) - sub_sess = tf.Session(graph = sub_graph) - dd_all = sub_sess.run(descrpt) - sub_sess.close() + dd_all \ + = self.sub_sess.run(self.stat_descrpt, + feed_dict = { + self.place_holders['coord']: data_coord, + self.place_holders['type']: data_atype, + self.place_holders['natoms_vec']: natoms_vec, + self.place_holders['box']: data_box, + self.place_holders['default_mesh']: mesh, + }) natoms = natoms_vec dd_all = np.reshape(dd_all, [-1, self.ndescrpt * natoms[0]]) start_index = 0 diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 2861548c79..da3be138fe 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -56,6 +56,32 @@ def __init__ (self, jdata): self.dstd = None self.davg = None + self.place_holders = {} + avg_zero = np.zeros([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) + std_ones = np.ones ([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) + sub_graph = tf.Graph() + with sub_graph.as_default(): + name_pfx = 'd_sea_' + for ii in ['coord', 'box']: + self.place_holders[ii] = tf.placeholder(global_np_float_precision, [None, None], name = name_pfx+'t_'+ii) + self.place_holders['type'] = tf.placeholder(tf.int32, [None, None], name=name_pfx+'t_type') + self.place_holders['natoms_vec'] = tf.placeholder(tf.int32, [self.ntypes+2], name=name_pfx+'t_natoms') + self.place_holders['default_mesh'] = tf.placeholder(tf.int32, [None], name=name_pfx+'t_mesh') + self.stat_descrpt, descrpt_deriv, rij, nlist \ + = op_module.descrpt_se_a(self.place_holders['coord'], + self.place_holders['type'], + self.place_holders['natoms_vec'], + self.place_holders['box'], + self.place_holders['default_mesh'], + tf.constant(avg_zero), + tf.constant(std_ones), + rcut_a = self.rcut_a, + rcut_r = self.rcut_r, + rcut_r_smth = self.rcut_r_smth, + sel_a = self.sel_a, + sel_r = self.sel_r) + self.sub_sess = tf.Session(graph = sub_graph) + def get_rcut (self) : return self.rcut_r @@ -240,32 +266,15 @@ def _compute_dstats_sys_smth (self, data_atype, natoms_vec, mesh) : - avg_zero = np.zeros([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) - std_ones = np.ones ([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) - sub_graph = tf.Graph() - with sub_graph.as_default(): - descrpt, descrpt_deriv, rij, nlist \ - = op_module.descrpt_se_a (tf.constant(data_coord), - tf.constant(data_atype), - tf.constant(natoms_vec, dtype = tf.int32), - tf.constant(data_box), - tf.constant(mesh), - tf.constant(avg_zero), - tf.constant(std_ones), - rcut_a = self.rcut_a, - rcut_r = self.rcut_r, - rcut_r_smth = self.rcut_r_smth, - sel_a = self.sel_a, - sel_r = self.sel_r) - # self.sess.run(tf.global_variables_initializer()) - # sub_sess = tf.Session(graph = sub_graph, - # config=tf.ConfigProto(intra_op_parallelism_threads=self.run_opt.num_intra_threads, - # inter_op_parallelism_threads=self.run_opt.num_inter_threads - - # )) - sub_sess = tf.Session(graph = sub_graph) - dd_all = sub_sess.run(descrpt) - sub_sess.close() + dd_all \ + = self.sub_sess.run(self.stat_descrpt, + feed_dict = { + self.place_holders['coord']: data_coord, + self.place_holders['type']: data_atype, + self.place_holders['natoms_vec']: natoms_vec, + self.place_holders['box']: data_box, + self.place_holders['default_mesh']: mesh, + }) natoms = natoms_vec dd_all = np.reshape(dd_all, [-1, self.ndescrpt * natoms[0]]) start_index = 0 diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index c750172316..e1d8acc368 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -52,6 +52,30 @@ def __init__ (self, jdata): self.davg = None self.dstd = None + self.place_holders = {} + avg_zero = np.zeros([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) + std_ones = np.ones ([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) + sub_graph = tf.Graph() + with sub_graph.as_default(): + name_pfx = 'd_ser_' + for ii in ['coord', 'box']: + self.place_holders[ii] = tf.placeholder(global_np_float_precision, [None, None], name = name_pfx+'t_'+ii) + self.place_holders['type'] = tf.placeholder(tf.int32, [None, None], name=name_pfx+'t_type') + self.place_holders['natoms_vec'] = tf.placeholder(tf.int32, [self.ntypes+2], name=name_pfx+'t_natoms') + self.place_holders['default_mesh'] = tf.placeholder(tf.int32, [None], name=name_pfx+'t_mesh') + self.stat_descrpt, descrpt_deriv, rij, nlist \ + = op_module.descrpt_se_r(self.place_holders['coord'], + self.place_holders['type'], + self.place_holders['natoms_vec'], + self.place_holders['box'], + self.place_holders['default_mesh'], + tf.constant(avg_zero), + tf.constant(std_ones), + rcut = self.rcut, + rcut_smth = self.rcut_smth, + sel = self.sel_r) + self.sub_sess = tf.Session(graph = sub_graph) + def get_rcut (self) : return self.rcut @@ -197,29 +221,15 @@ def _compute_dstats_sys_se_r (self, data_atype, natoms_vec, mesh) : - avg_zero = np.zeros([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) - std_ones = np.ones ([self.ntypes,self.ndescrpt]).astype(global_np_float_precision) - sub_graph = tf.Graph() - with sub_graph.as_default(): - descrpt, descrpt_deriv, rij, nlist \ - = op_module.descrpt_se_r (tf.constant(data_coord), - tf.constant(data_atype), - tf.constant(natoms_vec, dtype = tf.int32), - tf.constant(data_box), - tf.constant(mesh), - tf.constant(avg_zero), - tf.constant(std_ones), - rcut = self.rcut, - rcut_smth = self.rcut_smth, - sel = self.sel_r) - # sub_sess = tf.Session(graph = sub_graph, - # config=tf.ConfigProto(intra_op_parallelism_threads=self.run_opt.num_intra_threads, - # inter_op_parallelism_threads=self.run_opt.num_inter_threads - - # )) - sub_sess = tf.Session(graph = sub_graph) - dd_all = sub_sess.run(descrpt) - sub_sess.close() + dd_all \ + = self.sub_sess.run(self.stat_descrpt, + feed_dict = { + self.place_holders['coord']: data_coord, + self.place_holders['type']: data_atype, + self.place_holders['natoms_vec']: natoms_vec, + self.place_holders['box']: data_box, + self.place_holders['default_mesh']: mesh, + }) natoms = natoms_vec dd_all = np.reshape(dd_all, [-1, self.ndescrpt * natoms[0]]) start_index = 0 From e8bbee4988911356b3539bac7489ed800c18bc79 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 27 Dec 2019 15:53:57 +0800 Subject: [PATCH 046/147] add energy dipole loss --- source/train/Loss.py | 94 +++++++++++++++++++++++++++++++++++++++++ source/train/Model.py | 2 + source/train/Trainer.py | 12 ++++-- 3 files changed, 105 insertions(+), 3 deletions(-) diff --git a/source/train/Loss.py b/source/train/Loss.py index 264e8b7b9c..3b51f3bd1d 100644 --- a/source/train/Loss.py +++ b/source/train/Loss.py @@ -178,6 +178,100 @@ def print_on_training(self, return print_str +class EnerDipoleLoss () : + def __init__ (self, jdata, **kwarg) : + self.starter_learning_rate = kwarg['starter_learning_rate'] + args = ClassArg()\ + .add('start_pref_e', float, must = True, default = 0.1) \ + .add('limit_pref_e', float, must = True, default = 1.00)\ + .add('start_pref_ed', float, must = True, default = 1.00)\ + .add('limit_pref_ed', float, must = True, default = 1.00) + class_data = args.parse(jdata) + self.start_pref_e = class_data['start_pref_e'] + self.limit_pref_e = class_data['limit_pref_e'] + self.start_pref_ed = class_data['start_pref_ed'] + self.limit_pref_ed = class_data['limit_pref_ed'] + # data required + add_data_requirement('energy', 1, atomic=False, must=True, high_prec=True) + add_data_requirement('energy_dipole', 3, atomic=False, must=True, high_prec=False) + + def build (self, + learning_rate, + natoms, + model_dict, + label_dict, + suffix): + coord = model_dict['coord'] + energy = model_dict['energy'] + atom_ener = model_dict['atom_ener'] + nframes = tf.shape(atom_ener)[0] + natoms = tf.shape(atom_ener)[1] + # build energy dipole + atom_ener0 = atom_ener - tf.reshape(tf.tile(tf.reshape(energy/global_cvt_2_ener_float(natoms), [-1, 1]), [1, natoms]), [nframes, natoms]) + coord = tf.reshape(coord, [nframes, natoms, 3]) + atom_ener0 = tf.reshape(atom_ener0, [nframes, 1, natoms]) + ener_dipole = tf.matmul(atom_ener0, coord) + ener_dipole = tf.reshape(ener_dipole, [nframes, 3]) + + energy_hat = label_dict['energy'] + ener_dipole_hat = label_dict['energy_dipole'] + find_energy = label_dict['find_energy'] + find_ener_dipole = label_dict['find_energy_dipole'] + + l2_ener_loss = tf.reduce_mean( tf.square(energy - energy_hat), name='l2_'+suffix) + + ener_dipole_reshape = tf.reshape(ener_dipole, [-1]) + ener_dipole_hat_reshape = tf.reshape(ener_dipole_hat, [-1]) + l2_ener_dipole_loss = tf.reduce_mean( tf.square(ener_dipole_reshape - ener_dipole_hat_reshape), name='l2_'+suffix) + + # atom_norm_ener = 1./ global_cvt_2_ener_float(natoms[0]) + atom_norm_ener = 1./ global_cvt_2_ener_float(natoms) + pref_e = global_cvt_2_ener_float(find_energy * (self.limit_pref_e + (self.start_pref_e - self.limit_pref_e) * learning_rate / self.starter_learning_rate) ) + pref_ed = global_cvt_2_tf_float(find_ener_dipole * (self.limit_pref_ed + (self.start_pref_ed - self.limit_pref_ed) * learning_rate / self.starter_learning_rate) ) + + l2_loss = 0 + more_loss = {} + l2_loss += atom_norm_ener * (pref_e * l2_ener_loss) + l2_loss += global_cvt_2_ener_float(pref_ed * l2_ener_dipole_loss) + more_loss['l2_ener_loss'] = l2_ener_loss + more_loss['l2_ener_dipole_loss'] = l2_ener_dipole_loss + + self.l2_l = l2_loss + self.l2_more = more_loss + return l2_loss, more_loss + + + def print_header(self) : + prop_fmt = ' %9s %9s' + print_str = '' + print_str += prop_fmt % ('l2_tst', 'l2_trn') + print_str += prop_fmt % ('l2_e_tst', 'l2_e_trn') + print_str += prop_fmt % ('l2_ed_tst', 'l2_ed_trn') + return print_str + + + def print_on_training(self, + sess, + natoms, + feed_dict_test, + feed_dict_batch) : + error_test, error_e_test, error_ed_test\ + = sess.run([self.l2_l, \ + self.l2_more['l2_ener_loss'], \ + self.l2_more['l2_ener_dipole_loss']], + feed_dict=feed_dict_test) + error_train, error_e_train, error_ed_train\ + = sess.run([self.l2_l, \ + self.l2_more['l2_ener_loss'], \ + self.l2_more['l2_ener_dipole_loss']], + feed_dict=feed_dict_batch) + print_str = "" + prop_fmt = " %9.2e %9.2e" + print_str += prop_fmt % (np.sqrt(error_test), np.sqrt(error_train)) + print_str += prop_fmt % (np.sqrt(error_e_test) / natoms[0], np.sqrt(error_e_train) / natoms[0]) + print_str += prop_fmt % (np.sqrt(error_ed_test), np.sqrt(error_ed_train)) + return print_str + class TensorLoss () : def __init__ (self, jdata, **kwarg) : diff --git a/source/train/Model.py b/source/train/Model.py index 3615440612..2ff0b02a8d 100644 --- a/source/train/Model.py +++ b/source/train/Model.py @@ -270,6 +270,8 @@ def build (self, model_dict['virial'] = virial model_dict['atom_ener'] = energy_raw model_dict['atom_virial'] = atom_virial + model_dict['coord'] = coord + model_dict['atype'] = atype return model_dict diff --git a/source/train/Trainer.py b/source/train/Trainer.py index 352013d337..28be110918 100644 --- a/source/train/Trainer.py +++ b/source/train/Trainer.py @@ -18,7 +18,7 @@ from deepmd.DescrptSeR import DescrptSeR from deepmd.DescrptSeAR import DescrptSeAR from deepmd.Model import Model, WFCModel, DipoleModel, PolarModel, GlobalPolarModel -from deepmd.Loss import EnerStdLoss, TensorLoss +from deepmd.Loss import EnerStdLoss, EnerDipoleLoss, TensorLoss from deepmd.LearningRate import LearningRateExp from tensorflow.python.framework import ops @@ -146,8 +146,15 @@ def _init_param(self, jdata): loss_param = jdata['loss'] except: loss_param = None + loss_type = loss_param.get('type', 'std') + if fitting_type == 'ener': - self.loss = EnerStdLoss(loss_param, starter_learning_rate = self.lr.start_lr()) + if loss_type == 'std': + self.loss = EnerStdLoss(loss_param, starter_learning_rate = self.lr.start_lr()) + elif loss_type == 'ener_dipole': + self.loss = EnerDipoleLoss(loss_param, starter_learning_rate = self.lr.start_lr()) + else: + raise RuntimeError('unknow loss type') elif fitting_type == 'wfc': self.loss = TensorLoss(loss_param, model = self.model, @@ -262,7 +269,6 @@ def _build_network(self, data): self.place_holders['natoms_vec'] = tf.placeholder(tf.int32, [self.ntypes+2], name='t_natoms') self.place_holders['default_mesh'] = tf.placeholder(tf.int32, [None], name='t_mesh') self.place_holders['is_training'] = tf.placeholder(tf.bool) - self.model_pred\ = self.model.build (self.place_holders['coord'], self.place_holders['type'], From 30482b369945cee6f497068aeeb1c15c93d0f8cb Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 27 Dec 2019 16:09:57 +0800 Subject: [PATCH 047/147] fix bug of getting loss_type from None loss_param --- source/train/Trainer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/train/Trainer.py b/source/train/Trainer.py index 28be110918..0e4a30ab54 100644 --- a/source/train/Trainer.py +++ b/source/train/Trainer.py @@ -144,9 +144,10 @@ def _init_param(self, jdata): # infer loss type by fitting_type try : loss_param = jdata['loss'] + loss_type = loss_param.get('type', 'std') except: loss_param = None - loss_type = loss_param.get('type', 'std') + loss_type = 'std' if fitting_type == 'ener': if loss_type == 'std': From 29196140691db375497d0b6b581acb4a724d6c50 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 27 Dec 2019 18:55:25 +0800 Subject: [PATCH 048/147] warning rather than raising when the required batch size is smaller than the dataset --- source/train/Data.py | 5 ++++- source/train/DataSystem.py | 9 +++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/source/train/Data.py b/source/train/Data.py index 4de2f52627..bd3c2c149d 100644 --- a/source/train/Data.py +++ b/source/train/Data.py @@ -157,7 +157,10 @@ def get_numb_set (self) : def get_numb_batch (self, batch_size, set_idx) : data = self._load_set(self.train_dirs[set_idx]) - return data["coord"].shape[0] // batch_size + ret = data["coord"].shape[0] // batch_size + if ret == 0: + ret = 1 + return ret def get_sys_numb_batch (self, batch_size) : ret = 0 diff --git a/source/train/DataSystem.py b/source/train/DataSystem.py index c1dff9f06b..f0e69f1c44 100644 --- a/source/train/DataSystem.py +++ b/source/train/DataSystem.py @@ -2,6 +2,7 @@ import os, sys import collections +import warnings import numpy as np module_path = os.path.dirname(os.path.realpath(__file__)) + "/" @@ -76,12 +77,12 @@ def __init__ (self, for ii in range(self.nsystems) : chk_ret = self.data_systems[ii].check_batch_size(self.batch_size[ii]) if chk_ret is not None : - raise RuntimeError ("system %s required batch size %d is larger than the size %d of the dataset %s" % \ - (self.system_dirs[ii], self.batch_size[ii], chk_ret[1], chk_ret[0])) + warnings.warn("system %s required batch size is larger than the size of the dataset %s (%d > %d)" % \ + (self.system_dirs[ii], chk_ret[0], self.batch_size[ii], chk_ret[1])) chk_ret = self.data_systems[ii].check_test_size(test_size) if chk_ret is not None : - print("WARNNING: system %s required test size %d is larger than the size %d of the dataset %s" % \ - (self.system_dirs[ii], test_size, chk_ret[1], chk_ret[0])) + warnings.warn("system %s required test size is larger than the size of the dataset %s (%d > %d)" % \ + (self.system_dirs[ii], chk_ret[0], test_size, chk_ret[1])) # print summary if run_opt is not None: From 8b59c845f612d5c2a941b841140afd2a5f38283d Mon Sep 17 00:00:00 2001 From: Lu Date: Mon, 6 Jan 2020 20:06:49 +0800 Subject: [PATCH 049/147] fix bug of "-l-ldeepmd" --- source/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index d83ffe9e0e..4c43fc9227 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -173,7 +173,7 @@ if (BUILD_CPP_IF) if (USE_CUDA_TOOLKIT) set (LIB_DEEPMD_OP_CUDA "deepmd_op_cuda") else() - set (LIB_DEEPMD_OP_CUDA "") + set (LIB_DEEPMD_OP_CUDA "deepmd_op") endif() if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.9) set (LIB_DEEPMD_NATIVE "deepmd_native_md") From 58610f3df5c671c054ad93e00be0c429636ca785 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 9 Jan 2020 08:54:14 +0800 Subject: [PATCH 050/147] scale and shift the polar output --- source/train/Fitting.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 8ee8c80f32..32409fc7fe 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -383,6 +383,8 @@ def __init__ (self, jdata, descrpt) : .add('neuron', list, default = [120,120,120], alias = 'n_neuron')\ .add('resnet_dt', bool, default = True)\ .add('fit_diag', bool, default = True)\ + .add('diag_shift', [list,float], default = [0.0 for ii in range(self.ntypes)])\ + .add('scale', [list,float], default = [1.0 for ii in range(self.ntypes)])\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'pol_type')\ .add('seed', int) class_data = args.parse(jdata) @@ -391,6 +393,8 @@ def __init__ (self, jdata, descrpt) : self.sel_type = class_data['sel_type'] self.fit_diag = class_data['fit_diag'] self.seed = class_data['seed'] + self.diag_shift = class_data['diag_shift'] + self.scale = class_data['scale'] self.dim_rot_mat_1 = descrpt.get_dim_rot_mat_1() self.dim_rot_mat = self.dim_rot_mat_1 * 3 self.useBN = False @@ -477,6 +481,10 @@ def build (self, final_layer = tf.matmul(rot_mat_i, final_layer, transpose_a = True) # nframes x natoms x 3 x 3 final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms[2+type_i], 3, 3]) + # shift and scale + sel_type_idx = self.sel_type.index(type_i) + final_layer = final_layer * self.scale[sel_type_idx] + final_layer = final_layer + self.diag_shift[sel_type_idx] * tf.eye(3, batch_shape=[tf.shape(inputs)[0], natoms[2+type_i]], dtype = global_tf_float_precision) # concat the results if count == 0: From d20753aae9110a9f58d631a3a3f9f22d5b732c3c Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Wed, 8 Jan 2020 20:46:56 -0500 Subject: [PATCH 051/147] bump test tensorflow version to 2.1 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 48aa742722..e0e8280352 100644 --- a/.travis.yml +++ b/.travis.yml @@ -65,12 +65,12 @@ matrix: env: - CC=gcc-5 - CXX=g++-5 - - TENSORFLOW_VERSION=2.0 + - TENSORFLOW_VERSION=2.1 - python: 3.7 env: - CC=gcc-8 - CXX=g++-8 - - TENSORFLOW_VERSION=2.0 + - TENSORFLOW_VERSION=2.1 before_install: - pip install --upgrade pip - pip install --upgrade setuptools From 1847b0d3a96d95ef2eeefd8ea551d5ab4aaa1a75 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 9 Jan 2020 10:41:59 +0800 Subject: [PATCH 052/147] scale tensor loss --- source/train/Fitting.py | 6 ++++++ source/train/Loss.py | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 32409fc7fe..33402959aa 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -395,6 +395,12 @@ def __init__ (self, jdata, descrpt) : self.seed = class_data['seed'] self.diag_shift = class_data['diag_shift'] self.scale = class_data['scale'] + if type(self.sel_type) is not list: + self.sel_type = [self.sel_type] + if type(self.diag_shift) is not list: + self.diag_shift = [self.diag_shift] + if type(self.scale) is not list: + self.scale = [self.scale] self.dim_rot_mat_1 = descrpt.get_dim_rot_mat_1() self.dim_rot_mat = self.dim_rot_mat_1 * 3 self.useBN = False diff --git a/source/train/Loss.py b/source/train/Loss.py index 3b51f3bd1d..7f388503f5 100644 --- a/source/train/Loss.py +++ b/source/train/Loss.py @@ -284,6 +284,10 @@ def __init__ (self, jdata, **kwarg) : self.tensor_size = kwarg['tensor_size'] self.label_name = kwarg['label_name'] self.atomic = kwarg.get('atomic', True) + if jdata is not None: + self.scale = jdata.get('scale', 1.0) + else: + self.scale = 1.0 # data required add_data_requirement(self.label_name, self.tensor_size, @@ -300,7 +304,7 @@ def build (self, suffix): polar_hat = label_dict[self.label_name] polar = model_dict[self.tensor_name] - l2_loss = tf.reduce_mean( tf.square(polar - polar_hat), name='l2_'+suffix) + l2_loss = tf.reduce_mean( tf.square(self.scale*(polar - polar_hat)), name='l2_'+suffix) if not self.atomic : atom_norm = 1./ global_cvt_2_tf_float(natoms[0]) l2_loss = l2_loss * atom_norm From 6eeca8f56c9e648a9da5342b6cda0f0da6ca0fa9 Mon Sep 17 00:00:00 2001 From: Lu Date: Thu, 9 Jan 2020 13:58:13 +0800 Subject: [PATCH 053/147] fix bug of "not support architecture compute_75" when use CUDA-9.0 toolkit --- source/op/cuda/CMakeLists.txt | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/source/op/cuda/CMakeLists.txt b/source/op/cuda/CMakeLists.txt index a9847abd3e..50678fe887 100644 --- a/source/op/cuda/CMakeLists.txt +++ b/source/op/cuda/CMakeLists.txt @@ -14,14 +14,25 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CUDA_STANDARD 11) # nvcc -o libdeepmd_op_cuda.so -I/usr/local/cub-1.8.0 -rdc=true -DHIGH_PREC=true -gencode arch=compute_61,code=sm_61 -shared -Xcompiler -fPIC deepmd_op.cu -L/usr/local/cuda/lib64 -lcudadevrt # very important here! Include path to cub. -include_directories(cub) -# nvcc flags -set(CUDA_NVCC_FLAGS -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) - -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 - -gencode arch=compute_70,code=sm_70; # Volta - GV100/Tesla V100, GTX 1180 (GV104) - -gencode arch=compute_75,code=sm_75; # Turing - RTX 2080, Titan RTX, Quadro R8000 - -O3; -Xcompiler -fPIC; - ) +include_directories(cub) +if (${CUDA_VERSION_MAJOR} STREQUAL "10") + message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) + # nvcc flags + set(CUDA_NVCC_FLAGS -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) + -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 + -gencode arch=compute_70,code=sm_70; # Volta - GV100/Tesla V100, GTX 1180 (GV104) + -gencode arch=compute_75,code=sm_75; # Turing - RTX 2080, Titan RTX, Quadro R8000 + -O3; -Xcompiler -fPIC; + ) +else (${CUDA_VERSION_MAJOR} STREQUAL "10") + message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) + # nvcc flags + set(CUDA_NVCC_FLAGS -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) + -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 + -gencode arch=compute_70,code=sm_70; # Volta - GV100/Tesla V100, GTX 1180 (GV104) + -O3; -Xcompiler -fPIC; + ) +endif() set (SOURCE_FILES descrpt_se_a.cu descrpt_se_r.cu prod_force_se_a.cu prod_force_se_r.cu prod_virial_se_a.cu prod_virial_se_r.cu From 286c3183b9a87c7c6a5161ff64fff5dbeed52d06 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 9 Jan 2020 18:54:47 +0800 Subject: [PATCH 054/147] compatible with latest lammps pppm interface --- source/CMakeLists.txt | 10 ++++++++++ source/lmp/env.sh.in | 2 +- source/lmp/pppm_dplr.cpp | 5 +++++ source/lmp/pppm_dplr.h | 4 ++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 4c43fc9227..4af2ee9934 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -133,6 +133,16 @@ if (USE_TTM) set(TTM_DEF "-DUSE_TTM") endif (USE_TTM) +# old pppm interface +if(NOT DEFINED OLD_LMP_PPPM) + set(OLD_LMP_PPPM FALSE) +endif(NOT DEFINED OLD_LMP_PPPM) +if (OLD_LMP_PPPM) + set(OLD_LMP_PPPM_DEF "-DOLD_LMP_PPPM") + message(STATUS "Use old lammps pppm interface") +endif() +add_definitions (${OLD_LMP_PPPM_DEF}) + # define build type if ((NOT DEFINED CMAKE_BUILD_TYPE) OR CMAKE_BUILD_TYPE STREQUAL "") set (CMAKE_BUILD_TYPE release) diff --git a/source/lmp/env.sh.in b/source/lmp/env.sh.in index 2a9253ba70..00bc3b18b6 100644 --- a/source/lmp/env.sh.in +++ b/source/lmp/env.sh.in @@ -6,6 +6,6 @@ TF_INCLUDE_DIRS=`echo $TENSORFLOW_INCLUDE_DIRS | sed "s/;/ -I/g"` TF_LIBRARY_PATH=`echo $TENSORFLOW_LIBRARY_PATH | sed "s/;/ -L/g"` TF_RPATH=`echo $TENSORFLOW_LIBRARY_PATH | sed "s/;/ -Wl,-rpath=/g"` -NNP_INC=" -std=c++11 @PREC_DEF@ @TTM_DEF@ -I$TF_INCLUDE_DIRS -I$DEEPMD_ROOT/include/deepmd " +NNP_INC=" -std=c++11 @PREC_DEF@ @TTM_DEF@ @OLD_LMP_PPPM_DEF@ -I$TF_INCLUDE_DIRS -I$DEEPMD_ROOT/include/deepmd " NNP_PATH=" -L$TF_LIBRARY_PATH -L$DEEPMD_ROOT/lib" NNP_LIB=" -Wl,--no-as-needed -l@LIB_DEEPMD_OP@ -l@LIB_DEEPMD_OP_CUDA@ -l@LIB_DEEPMD@ -ltensorflow_cc -ltensorflow_framework -Wl,-rpath=$TF_RPATH -Wl,-rpath=$DEEPMD_ROOT/lib" diff --git a/source/lmp/pppm_dplr.cpp b/source/lmp/pppm_dplr.cpp index f706320f79..e5643e114f 100644 --- a/source/lmp/pppm_dplr.cpp +++ b/source/lmp/pppm_dplr.cpp @@ -40,8 +40,13 @@ enum{FORWARD_IK,FORWARD_AD,FORWARD_IK_PERATOM,FORWARD_AD_PERATOM}; /* ---------------------------------------------------------------------- */ +#ifdef OLD_LMP_PPPM PPPMDPLR::PPPMDPLR(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, narg, arg) +#else +PPPMDPLR::PPPMDPLR(LAMMPS *lmp) : + PPPM(lmp) +#endif { triclinic_support = 1; } diff --git a/source/lmp/pppm_dplr.h b/source/lmp/pppm_dplr.h index 884d41bce2..17680c01cd 100644 --- a/source/lmp/pppm_dplr.h +++ b/source/lmp/pppm_dplr.h @@ -35,7 +35,11 @@ namespace LAMMPS_NS { class PPPMDPLR : public PPPM { public: +#ifdef OLD_LMP_PPPM PPPMDPLR(class LAMMPS *, int, char **); +#else + PPPMDPLR(class LAMMPS *); +#endif virtual ~PPPMDPLR () {}; void init(); const vector & get_fele() const {return fele;}; From 3cd4867c50ea0acae332295d10df9677fc6e40cb Mon Sep 17 00:00:00 2001 From: Lu Date: Thu, 9 Jan 2020 19:30:53 +0800 Subject: [PATCH 055/147] fix bug of "unsupported architecture " when use some version's CUDA toolkit --- source/op/cuda/CMakeLists.txt | 61 ++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/source/op/cuda/CMakeLists.txt b/source/op/cuda/CMakeLists.txt index 50678fe887..79b3d23a6f 100644 --- a/source/op/cuda/CMakeLists.txt +++ b/source/op/cuda/CMakeLists.txt @@ -14,24 +14,77 @@ SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CUDA_STANDARD 11) # nvcc -o libdeepmd_op_cuda.so -I/usr/local/cub-1.8.0 -rdc=true -DHIGH_PREC=true -gencode arch=compute_61,code=sm_61 -shared -Xcompiler -fPIC deepmd_op.cu -L/usr/local/cuda/lib64 -lcudadevrt # very important here! Include path to cub. +# for searching device compute capability, https://developer.nvidia.com/cuda-gpus include_directories(cub) -if (${CUDA_VERSION_MAJOR} STREQUAL "10") + +if (${CUDA_VERSION_MAJOR} GREATER "10") + message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) + # nvcc flags + set(CUDA_NVCC_FLAGS -gencode arch=compute_50,code=sm_50; + -gencode arch=compute_52,code=sm_52; # Tesla M40, Tesla M40, Quadro M6000... + -gencode arch=compute_53,code=sm_53; + -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) + -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 + -gencode arch=compute_70,code=sm_70; # Volta - GV100/Tesla V100, GTX 1180 (GV104) + -gencode arch=compute_75,code=sm_75; # Turing - RTX 2080, Titan RTX, Quadro R8000 + -O3; -Xcompiler -fPIC; + ) +elseif (${CUDA_VERSION_MAJOR} STREQUAL "10") message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) # nvcc flags - set(CUDA_NVCC_FLAGS -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) + set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; # Tesla K10, Quadro K600 K420 K410, + -gencode arch=compute_35,code=sm_35; # Tesla K20 K40, TITAN Z Black, GTX 780Ti 780 + -gencode arch=compute_37,code=sm_37; # Tesla K80 + -gencode arch=compute_50,code=sm_50; # Quadro 620 1200 + -gencode arch=compute_52,code=sm_52; # Tesla M40 M40, Quadro M6000 M5000 M4000 M2000, TITAN X, GTX 980Ti 980 970 960 950 + -gencode arch=compute_53,code=sm_53; # Jetson TX1, Tegra X1 + -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 -gencode arch=compute_70,code=sm_70; # Volta - GV100/Tesla V100, GTX 1180 (GV104) -gencode arch=compute_75,code=sm_75; # Turing - RTX 2080, Titan RTX, Quadro R8000 -O3; -Xcompiler -fPIC; ) -else (${CUDA_VERSION_MAJOR} STREQUAL "10") +elseif (${CUDA_VERSION_MAJOR} STREQUAL "9") message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) # nvcc flags - set(CUDA_NVCC_FLAGS -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) + set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; + -gencode arch=compute_35,code=sm_35; + -gencode arch=compute_37,code=sm_37; + -gencode arch=compute_50,code=sm_50; + -gencode arch=compute_52,code=sm_52; # Tesla M40, Tesla M40, Quadro M6000... + -gencode arch=compute_53,code=sm_53; + -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 -gencode arch=compute_70,code=sm_70; # Volta - GV100/Tesla V100, GTX 1180 (GV104) + -gencode arch=compute_72,code=sm_72; + -O3; -Xcompiler -fPIC; + ) +elseif (${CUDA_VERSION_MAJOR} STREQUAL "8") + message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) + # nvcc flags + set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; + -gencode arch=compute_35,code=sm_35; + -gencode arch=compute_37,code=sm_37; + -gencode arch=compute_50,code=sm_50; + -gencode arch=compute_52,code=sm_52; # Tesla M40, Tesla M40, Quadro M6000... + -gencode arch=compute_53,code=sm_53; + -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) + -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 + -O3; -Xcompiler -fPIC; + ) +elseif (${CUDA_VERSION_MAJOR} STREQUAL "7") + message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) + # nvcc flags + set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; + -gencode arch=compute_35,code=sm_35; + -gencode arch=compute_37,code=sm_37; + -gencode arch=compute_50,code=sm_50; + -gencode arch=compute_52,code=sm_52; # Tesla M40, Tesla M40, Quadro M6000... + -gencode arch=compute_53,code=sm_53; -O3; -Xcompiler -fPIC; ) +else () + message(FATAL_ERROR "unsupported CUDA_VERSION " ${CUDA_VERSION} ", please use a newer version (>=7.0) of CUDA toolkit!") endif() set (SOURCE_FILES From 04a1f1c7ef8a183092d1330d1e846dead613e0f5 Mon Sep 17 00:00:00 2001 From: Lu Date: Thu, 9 Jan 2020 19:36:55 +0800 Subject: [PATCH 056/147] delete unused functions --- source/op/cuda/descrpt_se_a.cu | 14 -------------- source/op/cuda/descrpt_se_r.cu | 14 -------------- 2 files changed, 28 deletions(-) diff --git a/source/op/cuda/descrpt_se_a.cu b/source/op/cuda/descrpt_se_a.cu index 8893e8a00a..d9f6d357b0 100644 --- a/source/op/cuda/descrpt_se_a.cu +++ b/source/op/cuda/descrpt_se_a.cu @@ -40,20 +40,6 @@ inline void cudaAssert(cudaError_t code, const char *file, int line, bool abort= } } -#if defined(__CUDA_ARCH__) && __CUDA_ARCH__ < 600 -static __inline__ __device__ double atomicAdd(double* address, double val) { - unsigned long long int* address_as_ull = (unsigned long long int*)address; - unsigned long long int old = *address_as_ull, assumed; - do { - assumed = old; - old = atomicCAS(address_as_ull, assumed, - __double_as_longlong(val + __longlong_as_double(assumed))); - // Note: uses integer comparison to avoid hang in case of NaN (since NaN != NaN) } while (assumed != old); - } while (assumed != old); - return __longlong_as_double(old); -} -#endif - template < typename Key, int BLOCK_THREADS, diff --git a/source/op/cuda/descrpt_se_r.cu b/source/op/cuda/descrpt_se_r.cu index cc7dd4e904..37cee39d43 100644 --- a/source/op/cuda/descrpt_se_r.cu +++ b/source/op/cuda/descrpt_se_r.cu @@ -41,20 +41,6 @@ inline void cudaAssert(cudaError_t code, const char *file, int line, bool abort= } } -#if defined(__CUDA_ARCH__) && __CUDA_ARCH__ < 600 -static __inline__ __device__ double atomicAdd(double* address, double val) { - unsigned long long int* address_as_ull = (unsigned long long int*)address; - unsigned long long int old = *address_as_ull, assumed; - do { - assumed = old; - old = atomicCAS(address_as_ull, assumed, - __double_as_longlong(val + __longlong_as_double(assumed))); - // Note: uses integer comparison to avoid hang in case of NaN (since NaN != NaN) } while (assumed != old); - } while (assumed != old); - return __longlong_as_double(old); -} -#endif - template < typename Key, int BLOCK_THREADS, From 79faee4aef36728a63c78fe99269d52eb7fb75ba Mon Sep 17 00:00:00 2001 From: Lu Date: Thu, 9 Jan 2020 19:38:31 +0800 Subject: [PATCH 057/147] Update CMakeLists.txt --- source/op/cuda/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/source/op/cuda/CMakeLists.txt b/source/op/cuda/CMakeLists.txt index 79b3d23a6f..383357b9a1 100644 --- a/source/op/cuda/CMakeLists.txt +++ b/source/op/cuda/CMakeLists.txt @@ -56,7 +56,6 @@ elseif (${CUDA_VERSION_MAJOR} STREQUAL "9") -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 -gencode arch=compute_70,code=sm_70; # Volta - GV100/Tesla V100, GTX 1180 (GV104) - -gencode arch=compute_72,code=sm_72; -O3; -Xcompiler -fPIC; ) elseif (${CUDA_VERSION_MAJOR} STREQUAL "8") From db582f3cdc4aa1ff8d92b1c7aafe3c0c3ec8b650 Mon Sep 17 00:00:00 2001 From: Lu Date: Thu, 9 Jan 2020 20:43:38 +0800 Subject: [PATCH 058/147] move message out --- source/op/cuda/CMakeLists.txt | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/source/op/cuda/CMakeLists.txt b/source/op/cuda/CMakeLists.txt index 383357b9a1..25f796500b 100644 --- a/source/op/cuda/CMakeLists.txt +++ b/source/op/cuda/CMakeLists.txt @@ -17,21 +17,20 @@ SET(CMAKE_CUDA_STANDARD 11) # for searching device compute capability, https://developer.nvidia.com/cuda-gpus include_directories(cub) +message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) + if (${CUDA_VERSION_MAJOR} GREATER "10") - message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) - # nvcc flags - set(CUDA_NVCC_FLAGS -gencode arch=compute_50,code=sm_50; - -gencode arch=compute_52,code=sm_52; # Tesla M40, Tesla M40, Quadro M6000... - -gencode arch=compute_53,code=sm_53; - -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) - -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 - -gencode arch=compute_70,code=sm_70; # Volta - GV100/Tesla V100, GTX 1180 (GV104) - -gencode arch=compute_75,code=sm_75; # Turing - RTX 2080, Titan RTX, Quadro R8000 - -O3; -Xcompiler -fPIC; - ) -elseif (${CUDA_VERSION_MAJOR} STREQUAL "10") - message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) # nvcc flags + set(CUDA_NVCC_FLAGS -gencode arch=compute_50,code=sm_50; + -gencode arch=compute_52,code=sm_52; # Tesla M40, Tesla M40, Quadro M6000... + -gencode arch=compute_53,code=sm_53; + -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) + -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 + -gencode arch=compute_70,code=sm_70; # Volta - GV100/Tesla V100, GTX 1180 (GV104) + -gencode arch=compute_75,code=sm_75; # Turing - RTX 2080, Titan RTX, Quadro R8000 + -O3; -Xcompiler -fPIC; + ) +elseif (${CUDA_VERSION_MAJOR} STREQUAL "10") set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; # Tesla K10, Quadro K600 K420 K410, -gencode arch=compute_35,code=sm_35; # Tesla K20 K40, TITAN Z Black, GTX 780Ti 780 -gencode arch=compute_37,code=sm_37; # Tesla K80 @@ -45,8 +44,6 @@ elseif (${CUDA_VERSION_MAJOR} STREQUAL "10") -O3; -Xcompiler -fPIC; ) elseif (${CUDA_VERSION_MAJOR} STREQUAL "9") - message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) - # nvcc flags set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; -gencode arch=compute_35,code=sm_35; -gencode arch=compute_37,code=sm_37; @@ -59,8 +56,6 @@ elseif (${CUDA_VERSION_MAJOR} STREQUAL "9") -O3; -Xcompiler -fPIC; ) elseif (${CUDA_VERSION_MAJOR} STREQUAL "8") - message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) - # nvcc flags set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; -gencode arch=compute_35,code=sm_35; -gencode arch=compute_37,code=sm_37; @@ -72,8 +67,6 @@ elseif (${CUDA_VERSION_MAJOR} STREQUAL "8") -O3; -Xcompiler -fPIC; ) elseif (${CUDA_VERSION_MAJOR} STREQUAL "7") - message(STATUS "CUDA major version is " ${CUDA_VERSION_MAJOR}) - # nvcc flags set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; -gencode arch=compute_35,code=sm_35; -gencode arch=compute_37,code=sm_37; From 505d7c6985a2ed0c3a19b3d8d5ec7b369e532e15 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sat, 11 Jan 2020 17:21:11 +0800 Subject: [PATCH 059/147] fix bug of ndim when nframe==1 --- data/raw/raw_to_set.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data/raw/raw_to_set.sh b/data/raw/raw_to_set.sh index 58f2ab4ce5..8e4b917adb 100755 --- a/data/raw/raw_to_set.sh +++ b/data/raw/raw_to_set.sh @@ -36,8 +36,8 @@ do test -f fparam.raw$pi && mv fparam.raw$pi set.$pi/fparam.raw cd set.$pi - python -c 'import numpy as np; data = np.loadtxt("box.raw" ); data = data.astype (np.float32); np.save ("box", data)' - python -c 'import numpy as np; data = np.loadtxt("coord.raw" ); data = data.astype (np.float32); np.save ("coord", data)' + python -c 'import numpy as np; data = np.loadtxt("box.raw" , ndmin = 2); data = data.astype (np.float32); np.save ("box", data)' + python -c 'import numpy as np; data = np.loadtxt("coord.raw" , ndmin = 2); data = data.astype (np.float32); np.save ("coord", data)' python -c \ 'import numpy as np; import os.path; if os.path.isfile("energy.raw"): @@ -48,28 +48,28 @@ if os.path.isfile("energy.raw"): python -c \ 'import numpy as np; import os.path; if os.path.isfile("force.raw" ): - data = np.loadtxt("force.raw" ); + data = np.loadtxt("force.raw", ndmin = 2); data = data.astype (np.float32); np.save ("force", data) ' python -c \ 'import numpy as np; import os.path; if os.path.isfile("virial.raw"): - data = np.loadtxt("virial.raw"); + data = np.loadtxt("virial.raw", ndmin = 2); data = data.astype (np.float32); np.save ("virial", data) ' python -c \ 'import numpy as np; import os.path; if os.path.isfile("atom_ener.raw"): - data = np.loadtxt("atom_ener.raw"); + data = np.loadtxt("atom_ener.raw", ndmin = 2); data = data.astype (np.float32); np.save ("atom_ener", data) ' python -c \ 'import numpy as np; import os.path; if os.path.isfile("fparam.raw"): - data = np.loadtxt("fparam.raw"); + data = np.loadtxt("fparam.raw", ndmin = 2); data = data.astype (np.float32); np.save ("fparam", data) ' From b76e438ed86e2ed70809da2945a6436952908647 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Mon, 13 Jan 2020 15:52:52 -0500 Subject: [PATCH 060/147] clean codes * remove unused varibles * remove unused import * load module only once --- setup.py | 2 +- source/op/_prod_force_grad.py | 17 +---------------- source/op/_prod_force_se_a_grad.py | 17 +---------------- source/op/_prod_force_se_r_grad.py | 17 +---------------- source/op/_prod_virial_grad.py | 17 +---------------- source/op/_prod_virial_se_a_grad.py | 17 +---------------- source/op/_prod_virial_se_r_grad.py | 17 +---------------- source/op/_soft_min_force_grad.py | 16 +--------------- source/op/_soft_min_virial_grad.py | 16 +--------------- source/scripts/config.py | 2 +- source/scripts/freeze.py | 21 +-------------------- source/train/Data.py | 9 ++------- source/train/DataModifier.py | 14 ++------------ source/train/DataSystem.py | 9 +++------ source/train/DeepDipole.py | 2 -- source/train/DeepEval.py | 14 +------------- source/train/DeepPolar.py | 2 -- source/train/DeepPot.py | 1 - source/train/DeepWFC.py | 2 -- source/train/DescrptLocFrame.py | 16 +--------------- source/train/DescrptSeA.py | 18 +----------------- source/train/DescrptSeAR.py | 18 +----------------- source/train/DescrptSeR.py | 20 +------------------- source/train/EwaldRecp.py | 14 +------------- source/train/Fitting.py | 11 +---------- source/train/LearningRate.py | 1 - source/train/Loss.py | 4 ---- source/train/Model.py | 20 +------------------- source/train/Network.py | 3 --- source/train/TabInter.py | 1 - source/train/Trainer.py | 25 ++----------------------- source/train/compat.py | 6 +----- source/train/env.py | 17 +++++++++++++++++ source/train/print_old_model.py | 3 +-- source/train/train.py | 9 +-------- 35 files changed, 48 insertions(+), 350 deletions(-) diff --git a/setup.py b/setup.py index 2f5679458a..50ccafa849 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from skbuild.cmaker import get_cmake_version from packaging.version import LegacyVersion from os import path, makedirs -import imp,sys +import imp readme_file = path.join(path.dirname(path.abspath(__file__)), 'README.md') try: diff --git a/source/op/_prod_force_grad.py b/source/op/_prod_force_grad.py index 9d16682b53..ddd20d9a5b 100644 --- a/source/op/_prod_force_grad.py +++ b/source/op/_prod_force_grad.py @@ -3,23 +3,8 @@ Gradients for prod force. """ -import os -import platform -import tensorflow as tf from tensorflow.python.framework import ops -from tensorflow.python.ops import array_ops -from tensorflow.python.ops import sparse_ops - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) -module_file = os.path.join(module_path, 'libop_grads.{}'.format(ext)) -assert (os.path.isfile(module_file)), 'module op_grads does not exist' -op_grads_module = tf.load_op_library(module_file) +from deepmd.env import op_grads_module @ops.RegisterGradient("ProdForce") def _prod_force_grad_cc (op, grad): diff --git a/source/op/_prod_force_se_a_grad.py b/source/op/_prod_force_se_a_grad.py index 566f304483..8f69ef5139 100644 --- a/source/op/_prod_force_se_a_grad.py +++ b/source/op/_prod_force_se_a_grad.py @@ -3,23 +3,8 @@ Gradients for prod force. """ -import os -import platform -import tensorflow as tf from tensorflow.python.framework import ops -from tensorflow.python.ops import array_ops -from tensorflow.python.ops import sparse_ops - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) -module_file = os.path.join(module_path, 'libop_grads.{}'.format(ext)) -assert (os.path.isfile(module_file)), 'module op_grads does not exist' -op_grads_module = tf.load_op_library(module_file) +from deepmd.env import op_grads_module @ops.RegisterGradient("ProdForceSeA") def _prod_force_se_a_grad_cc (op, grad): diff --git a/source/op/_prod_force_se_r_grad.py b/source/op/_prod_force_se_r_grad.py index 71b2c05306..721ab927da 100644 --- a/source/op/_prod_force_se_r_grad.py +++ b/source/op/_prod_force_se_r_grad.py @@ -3,23 +3,8 @@ Gradients for prod force. """ -import os -import platform -import tensorflow as tf from tensorflow.python.framework import ops -from tensorflow.python.ops import array_ops -from tensorflow.python.ops import sparse_ops - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) -module_file = os.path.join(module_path, 'libop_grads.{}'.format(ext)) -assert (os.path.isfile(module_file)), 'module op_grads does not exist' -op_grads_module = tf.load_op_library(module_file) +from deepmd.env import op_grads_module @ops.RegisterGradient("ProdForceSeR") def _prod_force_se_a_grad_cc (op, grad): diff --git a/source/op/_prod_virial_grad.py b/source/op/_prod_virial_grad.py index 5d6ae58aea..8ed49200ed 100644 --- a/source/op/_prod_virial_grad.py +++ b/source/op/_prod_virial_grad.py @@ -3,23 +3,8 @@ Gradients for prod virial. """ -import os -import platform -import tensorflow as tf from tensorflow.python.framework import ops -from tensorflow.python.ops import array_ops -from tensorflow.python.ops import sparse_ops - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) -module_file = os.path.join(module_path, 'libop_grads.{}'.format(ext)) -assert (os.path.isfile(module_file)), 'module op_grads does not exist' -op_grads_module = tf.load_op_library(module_file) +from deepmd.env import op_grads_module @ops.RegisterGradient("ProdVirial") def _prod_virial_grad_cc (op, grad, grad_atom): diff --git a/source/op/_prod_virial_se_a_grad.py b/source/op/_prod_virial_se_a_grad.py index 5c28a06c2d..ea19a3ef14 100644 --- a/source/op/_prod_virial_se_a_grad.py +++ b/source/op/_prod_virial_se_a_grad.py @@ -3,23 +3,8 @@ Gradients for prod virial. """ -import os -import platform -import tensorflow as tf from tensorflow.python.framework import ops -from tensorflow.python.ops import array_ops -from tensorflow.python.ops import sparse_ops - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) -module_file = os.path.join(module_path, 'libop_grads.{}'.format(ext)) -assert (os.path.isfile(module_file)), 'module op_grads does not exist' -op_grads_module = tf.load_op_library(module_file) +from deepmd.env import op_grads_module @ops.RegisterGradient("ProdVirialSeA") def _prod_virial_se_a_grad_cc (op, grad, grad_atom): diff --git a/source/op/_prod_virial_se_r_grad.py b/source/op/_prod_virial_se_r_grad.py index 7ac054a750..367f2c90c3 100644 --- a/source/op/_prod_virial_se_r_grad.py +++ b/source/op/_prod_virial_se_r_grad.py @@ -3,23 +3,8 @@ Gradients for prod virial. """ -import os -import platform -import tensorflow as tf from tensorflow.python.framework import ops -from tensorflow.python.ops import array_ops -from tensorflow.python.ops import sparse_ops - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) -module_file = os.path.join(module_path, 'libop_grads.{}'.format(ext)) -assert (os.path.isfile(module_file)), 'module op_grads does not exist' -op_grads_module = tf.load_op_library(module_file) +from deepmd.env import op_grads_module @ops.RegisterGradient("ProdVirialSeR") def _prod_virial_se_a_grad_cc (op, grad, grad_atom): diff --git a/source/op/_soft_min_force_grad.py b/source/op/_soft_min_force_grad.py index 13d56472ad..be3d2c29d5 100644 --- a/source/op/_soft_min_force_grad.py +++ b/source/op/_soft_min_force_grad.py @@ -3,23 +3,9 @@ Gradients for soft min force """ -import os -import platform -import tensorflow as tf from tensorflow.python.framework import ops -from tensorflow.python.ops import array_ops -from tensorflow.python.ops import sparse_ops +from deepmd.env import op_grads_module -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) -module_file = os.path.join(module_path, 'libop_grads.{}'.format(ext)) -assert (os.path.isfile(module_file)), 'module op_grads does not exist' -op_grads_module = tf.load_op_library(module_file) @ops.RegisterGradient("SoftMinForce") def _soft_min_force_grad_cc (op, grad): diff --git a/source/op/_soft_min_virial_grad.py b/source/op/_soft_min_virial_grad.py index 91149e6f9e..6c6d980aa2 100644 --- a/source/op/_soft_min_virial_grad.py +++ b/source/op/_soft_min_virial_grad.py @@ -3,23 +3,9 @@ Gradients for soft min virial. """ -import os -import platform -import tensorflow as tf from tensorflow.python.framework import ops -from tensorflow.python.ops import array_ops -from tensorflow.python.ops import sparse_ops +from deepmd.env import op_grads_module -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) -module_file = os.path.join(module_path, 'libop_grads.{}'.format(ext)) -assert (os.path.isfile(module_file)), 'module op_grads does not exist' -op_grads_module = tf.load_op_library(module_file) @ops.RegisterGradient("SoftMinVirial") def _soft_min_virial_grad_cc (op, grad, grad_atom): diff --git a/source/scripts/config.py b/source/scripts/config.py index 6e87cf8329..5d3d804b26 100644 --- a/source/scripts/config.py +++ b/source/scripts/config.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -import glob,os,sys,json,argparse +import glob,os,json import numpy as np diff --git a/source/scripts/freeze.py b/source/scripts/freeze.py index c83e7e569c..2e6b211bc8 100755 --- a/source/scripts/freeze.py +++ b/source/scripts/freeze.py @@ -3,29 +3,10 @@ # freeze.py : # see https://blog.metaflow.fr/tensorflow-how-to-freeze-a-model-and-serve-it-with-a-python-api-d4f3596b3adc -import platform -import os, argparse, json -import sys - from deepmd.env import tf - -dir = os.path.dirname(os.path.realpath(__file__)) - -from tensorflow.python.framework import ops - -# load force module -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) + "/../" -assert (os.path.isfile (module_path + "deepmd/libop_abi.{}".format(ext) )), "force module does not exist" -op_module = tf.load_op_library(module_path + "deepmd/libop_abi.{}".format(ext)) +from deepmd.env import op_module # load grad of force module -sys.path.append (module_path ) import deepmd._prod_force_grad import deepmd._prod_virial_grad import deepmd._prod_force_se_a_grad diff --git a/source/train/Data.py b/source/train/Data.py index bd3c2c149d..db151d79cb 100644 --- a/source/train/Data.py +++ b/source/train/Data.py @@ -2,10 +2,8 @@ import time import glob -import random import numpy as np import os.path -from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.RunOptions import global_ener_float_precision @@ -230,7 +228,7 @@ def _get_subdata(self, data, idx = None) : def _load_batch_set (self, set_name) : self.batch_set = self._load_set(set_name) - self.batch_set, sf_idx = self._shuffle_data(self.batch_set) + self.batch_set, _ = self._shuffle_data(self.batch_set) self.reset_get_batch() def reset_get_batch(self): @@ -241,7 +239,7 @@ def _load_test_set (self, shuffle_test) : self.test_set = self._load_set(set_name) if shuffle_test : - self.test_set, sf_idx = self._shuffle_data(self.test_set) + self.test_set, _ = self._shuffle_data(self.test_set) def _shuffle_data (self, data) : @@ -261,7 +259,6 @@ def _shuffle_data (self, return ret, idx def _load_set(self, set_name) : - ret = {} # get nframes path = os.path.join(set_name, "coord.npy") if self.data_dict['coord']['high_prec'] : @@ -488,7 +485,6 @@ def load_data(self, set_name, data_name, shape, is_necessary = True): return 0, data def load_set(self, set_name, shuffle = True): - start_time = time.time() data = {} data["box"] = self.load_data(set_name, "box", [-1, 9]) nframe = data["box"].shape[0] @@ -526,7 +522,6 @@ def load_set(self, set_name, shuffle = True): data[ii] = data[ii][:, self.idx_map] for ii in ["coord", "force", "atom_pref"]: data[ii] = data[ii][:, self.idx3_map] - end_time = time.time() return data def load_batch_set (self, diff --git a/source/train/DataModifier.py b/source/train/DataModifier.py index 27f3f93b60..fbbfff60bc 100644 --- a/source/train/DataModifier.py +++ b/source/train/DataModifier.py @@ -1,4 +1,4 @@ -import os,platform +import os import numpy as np from deepmd.DeepDipole import DeepDipole from deepmd.env import tf @@ -9,17 +9,7 @@ from deepmd.RunOptions import global_ener_float_precision from deepmd.RunOptions import global_cvt_2_tf_float from deepmd.RunOptions import global_cvt_2_ener_float - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" - -module_path = os.path.dirname(os.path.realpath(__file__)) + "/" -assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" -op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) +from deepmd.env import op_module class DipoleChargeModifier(DeepDipole): diff --git a/source/train/DataSystem.py b/source/train/DataSystem.py index f0e69f1c44..27e397a030 100644 --- a/source/train/DataSystem.py +++ b/source/train/DataSystem.py @@ -1,14 +1,11 @@ #!/usr/bin/env python3 -import os, sys +import os import collections import warnings import numpy as np - -module_path = os.path.dirname(os.path.realpath(__file__)) + "/" -sys.path.append (module_path) -from Data import DataSets -from Data import DeepmdData +from deepmd.Data import DataSets +from deepmd.Data import DeepmdData class DeepmdDataSystem() : diff --git a/source/train/DeepDipole.py b/source/train/DeepDipole.py index 31b166284e..e7cb65d693 100644 --- a/source/train/DeepDipole.py +++ b/source/train/DeepDipole.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -import os,sys -import numpy as np from deepmd.DeepEval import DeepTensor class DeepDipole (DeepTensor) : diff --git a/source/train/DeepEval.py b/source/train/DeepEval.py index 386d68a4e2..bc873a575e 100644 --- a/source/train/DeepEval.py +++ b/source/train/DeepEval.py @@ -1,22 +1,11 @@ #!/usr/bin/env python3 import platform -import os,sys +import os import numpy as np from deepmd.env import tf from deepmd.common import make_default_mesh -from tensorflow.python.framework import ops - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) -assert (os.path.isfile (os.path.join(module_path, "libop_abi.{}".format(ext)))), "op module does not exist" -op_module = tf.load_op_library(os.path.join(module_path, "libop_abi.{}".format(ext))) class DeepEval(): """ @@ -25,7 +14,6 @@ class DeepEval(): def __init__(self, model_file, load_prefix = 'load') : - model_file = model_file self.graph = self._load_graph (model_file, prefix = load_prefix) t_mt = self.graph.get_tensor_by_name(os.path.join(load_prefix, 'model_attr/model_type:0')) sess = tf.Session (graph = self.graph) diff --git a/source/train/DeepPolar.py b/source/train/DeepPolar.py index 3af499dd07..e0821443e6 100644 --- a/source/train/DeepPolar.py +++ b/source/train/DeepPolar.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -import os,sys -import numpy as np from deepmd.DeepEval import DeepTensor class DeepPolar (DeepTensor) : diff --git a/source/train/DeepPot.py b/source/train/DeepPot.py index 09519fc0e1..e3df6d6c8f 100644 --- a/source/train/DeepPot.py +++ b/source/train/DeepPot.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 -import os,sys import numpy as np from deepmd.env import tf from deepmd.common import make_default_mesh diff --git a/source/train/DeepWFC.py b/source/train/DeepWFC.py index 98bf2578a0..ee329628da 100644 --- a/source/train/DeepWFC.py +++ b/source/train/DeepWFC.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -import os,sys -import numpy as np from deepmd.DeepEval import DeepTensor class DeepWFC (DeepTensor) : diff --git a/source/train/DescrptLocFrame.py b/source/train/DescrptLocFrame.py index ed1fe6b989..5d50384aad 100644 --- a/source/train/DescrptLocFrame.py +++ b/source/train/DescrptLocFrame.py @@ -1,23 +1,9 @@ -import platform -import os import numpy as np from deepmd.env import tf from deepmd.common import ClassArg from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision -from deepmd.RunOptions import global_ener_float_precision -from deepmd.RunOptions import global_cvt_2_tf_float -from deepmd.RunOptions import global_cvt_2_ener_float - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) + "/" -assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" -op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) +from deepmd.env import op_module class DescrptLocFrame () : def __init__(self, jdata): diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index da3be138fe..15ad2df7d6 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -1,23 +1,9 @@ -import platform -import os,sys,warnings import numpy as np from deepmd.env import tf from deepmd.common import ClassArg from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision -from deepmd.RunOptions import global_ener_float_precision -from deepmd.RunOptions import global_cvt_2_tf_float -from deepmd.RunOptions import global_cvt_2_ener_float - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) + "/" -assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" -op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) +from deepmd.env import op_module class DescrptSeA (): def __init__ (self, jdata): @@ -241,7 +227,6 @@ def _pass_filter(self, trainable = True) : start_index = 0 inputs = tf.reshape(inputs, [-1, self.ndescrpt * natoms[0]]) - shape = inputs.get_shape().as_list() output = [] output_qmat = [] for type_i in range(self.ntypes): @@ -403,7 +388,6 @@ def _filter_type_ext(self, seed=None, trainable = True): # natom x (nei x 4) - shape = inputs.get_shape().as_list() outputs_size = [1] + self.filter_neuron outputs_size_2 = self.n_axis_neuron with tf.variable_scope(name, reuse=reuse): diff --git a/source/train/DescrptSeAR.py b/source/train/DescrptSeAR.py index 5328d28cf7..dadc2f3d95 100644 --- a/source/train/DescrptSeAR.py +++ b/source/train/DescrptSeAR.py @@ -1,26 +1,10 @@ -import platform -import os,sys,warnings import numpy as np from deepmd.env import tf from deepmd.common import ClassArg -from deepmd.RunOptions import global_tf_float_precision -from deepmd.RunOptions import global_np_float_precision -from deepmd.RunOptions import global_ener_float_precision -from deepmd.RunOptions import global_cvt_2_tf_float -from deepmd.RunOptions import global_cvt_2_ener_float from deepmd.DescrptSeA import DescrptSeA from deepmd.DescrptSeR import DescrptSeR - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) + "/" -assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" -op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) +from deepmd.env import op_module class DescrptSeAR (): def __init__ (self, jdata): diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index e1d8acc368..85553eeeb9 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -1,23 +1,9 @@ -import os,warnings -import platform import numpy as np from deepmd.env import tf from deepmd.common import ClassArg from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision -from deepmd.RunOptions import global_ener_float_precision -from deepmd.RunOptions import global_cvt_2_tf_float -from deepmd.RunOptions import global_cvt_2_ener_float - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) + "/" -assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" -op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) +from deepmd.env import op_module class DescrptSeR (): def __init__ (self, jdata): @@ -201,7 +187,6 @@ def _pass_filter(self, trainable = True) : start_index = 0 inputs = tf.reshape(inputs, [-1, self.ndescrpt * natoms[0]]) - shape = inputs.get_shape().as_list() output = [] for type_i in range(self.ntypes): inputs_i = tf.slice (inputs, @@ -234,10 +219,8 @@ def _compute_dstats_sys_se_r (self, dd_all = np.reshape(dd_all, [-1, self.ndescrpt * natoms[0]]) start_index = 0 sysr = [] - sysa = [] sysn = [] sysr2 = [] - sysa2 = [] for type_i in range(self.ntypes): end_index = start_index + self.ndescrpt * natoms[2+type_i] dd = dd_all[:, start_index:end_index] @@ -269,7 +252,6 @@ def _filter_r(self, seed=None, trainable = True): # natom x nei - shape = inputs.get_shape().as_list() outputs_size = [1] + self.filter_neuron with tf.variable_scope(name, reuse=reuse): start_index = 0 diff --git a/source/train/EwaldRecp.py b/source/train/EwaldRecp.py index 4e48e5a0cf..0fbeed30d6 100644 --- a/source/train/EwaldRecp.py +++ b/source/train/EwaldRecp.py @@ -1,5 +1,3 @@ -import platform -import os import numpy as np from deepmd.env import tf from deepmd.common import ClassArg @@ -8,17 +6,7 @@ from deepmd.RunOptions import global_ener_float_precision from deepmd.RunOptions import global_cvt_2_tf_float from deepmd.RunOptions import global_cvt_2_ener_float - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" - -module_path = os.path.dirname(os.path.realpath(__file__)) + "/" -assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" -op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) +from deepmd.env import op_module class EwaldRecp () : def __init__(self, diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 33402959aa..c940bcbcb1 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -1,4 +1,4 @@ -import os,warnings +import warnings import numpy as np from deepmd.env import tf @@ -8,10 +8,6 @@ from deepmd.DescrptSeA import DescrptSeA from deepmd.RunOptions import global_tf_float_precision -from deepmd.RunOptions import global_np_float_precision -from deepmd.RunOptions import global_ener_float_precision -from deepmd.RunOptions import global_cvt_2_tf_float -from deepmd.RunOptions import global_cvt_2_ener_float class EnerFitting (): def __init__ (self, jdata, descrpt): @@ -158,7 +154,6 @@ def build (self, start_index = 0 inputs = tf.reshape(inputs, [-1, self.dim_descrpt * natoms[0]]) - shape = inputs.get_shape().as_list() if bias_atom_e is not None : assert(len(bias_atom_e) == self.ntypes) @@ -253,7 +248,6 @@ def build (self, start_index = 0 inputs = tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]) rot_mat = tf.reshape(rot_mat, [-1, 9 * natoms[0]]) - shape = inputs.get_shape().as_list() count = 0 for type_i in range(self.ntypes): @@ -328,7 +322,6 @@ def build (self, start_index = 0 inputs = tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]) rot_mat = tf.reshape(rot_mat, [-1, 9 * natoms[0]]) - shape = inputs.get_shape().as_list() count = 0 for type_i in range(self.ntypes): @@ -437,7 +430,6 @@ def build (self, start_index = 0 inputs = tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]) rot_mat = tf.reshape(rot_mat, [-1, self.dim_rot_mat * natoms[0]]) - shape = inputs.get_shape().as_list() count = 0 for type_i in range(self.ntypes): @@ -565,7 +557,6 @@ def build (self, start_index = 0 inputs = tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]) rot_mat = tf.reshape(rot_mat, [-1, self.dim_rot_mat * natoms[0]]) - shape = inputs.get_shape().as_list() count = 0 for type_i in range(self.ntypes): diff --git a/source/train/LearningRate.py b/source/train/LearningRate.py index 3df4178f38..fe66e52516 100644 --- a/source/train/LearningRate.py +++ b/source/train/LearningRate.py @@ -1,4 +1,3 @@ -import os,sys,warnings import numpy as np from deepmd.env import tf from deepmd.common import ClassArg diff --git a/source/train/Loss.py b/source/train/Loss.py index 7f388503f5..4b38a3b1ba 100644 --- a/source/train/Loss.py +++ b/source/train/Loss.py @@ -1,11 +1,7 @@ -import os,sys,warnings import numpy as np from deepmd.env import tf from deepmd.common import ClassArg, add_data_requirement -from deepmd.RunOptions import global_tf_float_precision -from deepmd.RunOptions import global_np_float_precision -from deepmd.RunOptions import global_ener_float_precision from deepmd.RunOptions import global_cvt_2_tf_float from deepmd.RunOptions import global_cvt_2_ener_float diff --git a/source/train/Model.py b/source/train/Model.py index 2ff0b02a8d..6c4e059986 100644 --- a/source/train/Model.py +++ b/source/train/Model.py @@ -1,26 +1,11 @@ -import os,sys,warnings -import platform import numpy as np from deepmd.env import tf from collections import defaultdict from deepmd.TabInter import TabInter from deepmd.common import ClassArg -from deepmd.RunOptions import global_tf_float_precision -from deepmd.RunOptions import global_np_float_precision -from deepmd.RunOptions import global_ener_float_precision -from deepmd.RunOptions import global_cvt_2_tf_float from deepmd.RunOptions import global_cvt_2_ener_float - -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) + "/" -assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" -op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) +from deepmd.env import op_module def _make_all_stat_ref(data, nbatches): @@ -174,7 +159,6 @@ def build (self, trainable = False, initializer = tf.constant_initializer(tab_data, dtype = tf.float64)) - coord = tf.reshape (coord_, [-1, natoms[1] * 3]) atype = tf.reshape (atype_, [-1, natoms[1]]) dout \ @@ -351,8 +335,6 @@ def build (self, name = 'output_dim', dtype = tf.int32) - coord = tf.reshape (coord_, [-1, natoms[1] * 3]) - atype = tf.reshape (atype_, [-1, natoms[1]]) dout \ = self.descrpt.build(coord_, diff --git a/source/train/Network.py b/source/train/Network.py index bf8c50775c..1adc1e1b31 100644 --- a/source/train/Network.py +++ b/source/train/Network.py @@ -1,10 +1,7 @@ -import os,warnings import numpy as np from deepmd.env import tf from deepmd.RunOptions import global_tf_float_precision -from deepmd.RunOptions import global_np_float_precision -from deepmd.RunOptions import global_ener_float_precision def one_layer(inputs, outputs_size, diff --git a/source/train/TabInter.py b/source/train/TabInter.py index e6de0bb42e..99190e1191 100644 --- a/source/train/TabInter.py +++ b/source/train/TabInter.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 -import os, sys, shutil import numpy as np from scipy.interpolate import CubicSpline diff --git a/source/train/Trainer.py b/source/train/Trainer.py index 0e4a30ab54..f8da95b8ab 100644 --- a/source/train/Trainer.py +++ b/source/train/Trainer.py @@ -1,17 +1,11 @@ #!/usr/bin/env python3 import os -import platform -import sys import time import shutil -import warnings import numpy as np from deepmd.env import tf from deepmd.RunOptions import global_tf_float_precision -from deepmd.RunOptions import global_np_float_precision from deepmd.RunOptions import global_ener_float_precision -from deepmd.RunOptions import global_cvt_2_tf_float -from deepmd.RunOptions import global_cvt_2_ener_float from deepmd.Fitting import EnerFitting, WFCFitting, PolarFittingLocFrame, PolarFittingSeA, GlobalPolarFittingSeA, DipoleFittingSeA from deepmd.DescrptLocFrame import DescrptLocFrame from deepmd.DescrptSeA import DescrptSeA @@ -21,22 +15,10 @@ from deepmd.Loss import EnerStdLoss, EnerDipoleLoss, TensorLoss from deepmd.LearningRate import LearningRateExp -from tensorflow.python.framework import ops from tensorflow.python.client import timeline - -# load force module -if platform.system() == "Windows": - ext = "dll" -elif platform.system() == "Darwin": - ext = "dylib" -else: - ext = "so" -module_path = os.path.dirname(os.path.realpath(__file__)) + "/" -assert (os.path.isfile (module_path + "libop_abi.{}".format(ext) )), "op module does not exist" -op_module = tf.load_op_library(module_path + "libop_abi.{}".format(ext)) +from deepmd.env import op_module # load grad of force module -sys.path.append (module_path ) import deepmd._prod_force_grad import deepmd._prod_virial_grad import deepmd._prod_force_se_a_grad @@ -45,10 +27,8 @@ import deepmd._prod_virial_se_r_grad import deepmd._soft_min_force_grad import deepmd._soft_min_virial_grad -from deepmd.RunOptions import RunOptions -from deepmd.TabInter import TabInter -from deepmd.common import j_must_have, ClassArg, add_data_requirement, data_requirement +from deepmd.common import j_must_have, ClassArg def _is_subdir(path, directory): path = os.path.realpath(path) @@ -414,7 +394,6 @@ def train (self, train_time = 0 while cur_batch < stop_batch : batch_data = data.get_batch (sys_weights = self.sys_weights) - cur_batch_size = batch_data["coord"].shape[0] feed_dict_batch = {} for kk in batch_data.keys(): if kk == 'find_type' or kk == 'type' : diff --git a/source/train/compat.py b/source/train/compat.py index 0cf522e500..40ac118e23 100644 --- a/source/train/compat.py +++ b/source/train/compat.py @@ -1,4 +1,4 @@ -import os,json,warnings +import json,warnings from deepmd.common import j_have,j_must_have,j_must_have_d def convert_input_v0_v1(jdata, warning = True, dump = None) : @@ -37,10 +37,6 @@ def _smth_model(jdata): return model def _nonsmth_descriptor(jdata) : - output = {} - seed = None - if j_have (jdata, 'seed') : - seed = jdata['seed'] # model descriptor = {} descriptor['type'] = 'loc_frame' diff --git a/source/train/env.py b/source/train/env.py index 22630724ff..f5baf53aa4 100644 --- a/source/train/env.py +++ b/source/train/env.py @@ -1,5 +1,6 @@ import os import logging +import platform import numpy as np from imp import reload @@ -30,3 +31,19 @@ def set_mkl(): set_env_if_empty("KMP_BLOCKTIME", "0") set_env_if_empty("KMP_AFFINITY", "granularity=fine,verbose,compact,1,0") reload(np) + +def get_module(module_name): + """Load force module.""" + if platform.system() == "Windows": + ext = "dll" + elif platform.system() == "Darwin": + ext = "dylib" + else: + ext = "so" + module_path = os.path.dirname(os.path.realpath(__file__)) + "/" + assert (os.path.isfile (module_path + "{}.{}".format(module_name, ext) )), "module %s does not exist" % module_name + module = tf.load_op_library(module_path + "{}.{}".format(module_name, ext)) + return module + +op_module = get_module("libop_abi") +op_grads_module = get_module("libop_grads") \ No newline at end of file diff --git a/source/train/print_old_model.py b/source/train/print_old_model.py index 9e47968672..14719723f9 100644 --- a/source/train/print_old_model.py +++ b/source/train/print_old_model.py @@ -12,7 +12,7 @@ from deepmd.DataSystem import DataSystem from deepmd.Model import NNPModel from deepmd.Model import LearingRate -from deepmd.common import j_must_have, j_must_have_d, j_have +from deepmd.common import j_must_have def gen_data() : tmpdata = Data(rand_pert = 0.1, seed = 1) @@ -41,7 +41,6 @@ def compute_efv(jfile): test_size = j_must_have(jdata, 'numb_test') batch_size = 1 test_size = 1 - stop_batch = j_must_have(jdata, 'stop_batch') rcut = j_must_have (jdata, 'rcut') data = DataSystem(systems, set_pfx, batch_size, test_size, rcut, run_opt) diff --git a/source/train/train.py b/source/train/train.py index 1df0b6d80d..3349115992 100755 --- a/source/train/train.py +++ b/source/train/train.py @@ -4,16 +4,11 @@ import sys import time import numpy as np -import argparse import json from deepmd.env import tf from deepmd.compat import convert_input_v0_v1 - -lib_path = os.path.dirname(os.path.realpath(__file__)) + "/../lib/" -sys.path.append (lib_path) - from deepmd.RunOptions import RunOptions -from deepmd.DataSystem import DataSystem, DeepmdDataSystem +from deepmd.DataSystem import DeepmdDataSystem from deepmd.Trainer import NNPTrainer from deepmd.common import data_requirement from deepmd.DataModifier import DipoleChargeModifier @@ -103,7 +98,6 @@ def _do_work(jdata, run_opt): if type(systems) == str: systems = expand_sys_str(systems) set_pfx = j_must_have(jdata['training'], 'set_prefix') - numb_sys = len(systems) seed = None if 'seed' in jdata['training'].keys() : seed = jdata['training']['seed'] if seed is not None: @@ -143,7 +137,6 @@ def _do_work(jdata, run_opt): model.build (data, stop_batch) # train the model with the provided systems in a cyclic way start_time = time.time() - cur_batch = 0 model.train (data) end_time = time.time() run_opt.message("finished training\nwall time: %.3f s" % (end_time-start_time)) From ce6e68a34375465aef4a17b01cbd6c96de97f53f Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Mon, 13 Jan 2020 17:05:10 -0500 Subject: [PATCH 061/147] fix bug --- source/train/Model.py | 1 + 1 file changed, 1 insertion(+) diff --git a/source/train/Model.py b/source/train/Model.py index 6c4e059986..ba48bbc0a0 100644 --- a/source/train/Model.py +++ b/source/train/Model.py @@ -159,6 +159,7 @@ def build (self, trainable = False, initializer = tf.constant_initializer(tab_data, dtype = tf.float64)) + coord = tf.reshape (coord_, [-1, natoms[1] * 3]) atype = tf.reshape (atype_, [-1, natoms[1]]) dout \ From 0828a7ba6f24ec5fbe3c17cd72a38c63acf16435 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Sat, 18 Jan 2020 15:53:57 -0500 Subject: [PATCH 062/147] use travis-ci to build wheels and upload to pypi Update .travis.yml Update .travis.yml Update .travis.yml Update .travis.yml Update .travis.yml tf --- .travis.yml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e0e8280352..c5b511b6bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,9 +14,10 @@ addons: - g++-7 - gcc-8 - g++-8 -matrix: +jobs: include: - - python: 3.6 + - stage: unit tests + python: 3.6 env: - CC=gcc-4.8 - CXX=g++-4.8 @@ -71,6 +72,23 @@ matrix: - CC=gcc-8 - CXX=g++-8 - TENSORFLOW_VERSION=2.1 + - stage: build whls + services: docker + env: + - TWINE_USERNAME=__token__ + - CIBW_BUILD="cp36-* cp37-*" + - CIBW_BEFORE_BUILD="pip install tensorflow && sed -i 's/libresolv.so.2\"/libresolv.so.2\", \"libtensorflow_framework.so.2\"/g' \$(find / -name policy.json)" + - CIBW_SKIP="*-win32 *-manylinux_i686" + - CC=gcc-7 + - CXX=g++-7 + - TENSORFLOW_VERSION=2.1 + install: + - python -m pip install twine cibuildwheel==1.1.0 scikit-build + script: + - python -m cibuildwheel --output-dir wheelhouse + - python setup.py sdist + after_success: + - if [[ $TRAVIS_TAG ]]; then python -m twine upload wheelhouse/*; fi before_install: - pip install --upgrade pip - pip install --upgrade setuptools From fa84b3bac67df84b940681a591726a72f42f7614 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Sun, 19 Jan 2020 04:33:35 -0500 Subject: [PATCH 063/147] also upload tar.gz --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c5b511b6bc..019256c993 100644 --- a/.travis.yml +++ b/.travis.yml @@ -88,7 +88,7 @@ jobs: - python -m cibuildwheel --output-dir wheelhouse - python setup.py sdist after_success: - - if [[ $TRAVIS_TAG ]]; then python -m twine upload wheelhouse/*; fi + - if [[ $TRAVIS_TAG ]]; then python -m twine upload wheelhouse/*; python -m twine upload dist/*.tar.gz; fi before_install: - pip install --upgrade pip - pip install --upgrade setuptools From 9682111fece218b0deb070abc796d3bd96b35dbd Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 20 Jan 2020 23:11:51 +0800 Subject: [PATCH 064/147] use envs TF_INTRA_OP_PARALLELISM_THREADS and TF_INTER_OP_PARALLELISM_THREADS to control the multi-threading of tf, clean up runoptions. --- source/lib/src/common.cc | 2 +- source/train/DeepEval.py | 6 ++-- source/train/DeepPot.py | 3 +- source/train/DescrptLocFrame.py | 3 +- source/train/DescrptSeA.py | 3 +- source/train/DescrptSeR.py | 3 +- source/train/EwaldRecp.py | 3 +- source/train/RunOptions.py.in | 53 ++++++++++++++------------------- source/train/Trainer.py | 6 ++-- source/train/env.py | 20 +++++++++++-- 10 files changed, 55 insertions(+), 47 deletions(-) diff --git a/source/lib/src/common.cc b/source/lib/src/common.cc index c37b1cf2e1..296800a396 100644 --- a/source/lib/src/common.cc +++ b/source/lib/src/common.cc @@ -159,7 +159,7 @@ get_env_nthreads(int & num_intra_nthreads, { num_intra_nthreads = 0; num_inter_nthreads = 0; - const char* env_intra_nthreads = std::getenv("OMP_NUM_THREADS"); + const char* env_intra_nthreads = std::getenv("TF_INTRA_OP_PARALLELISM_THREADS"); const char* env_inter_nthreads = std::getenv("TF_INTER_OP_PARALLELISM_THREADS"); if (env_intra_nthreads && string(env_intra_nthreads) != string("") && diff --git a/source/train/DeepEval.py b/source/train/DeepEval.py index bc873a575e..f0cefe6355 100644 --- a/source/train/DeepEval.py +++ b/source/train/DeepEval.py @@ -4,9 +4,9 @@ import numpy as np from deepmd.env import tf +from deepmd.env import default_tf_session_config from deepmd.common import make_default_mesh - class DeepEval(): """ common methods for DeepPot, DeepWFC, DeepPolar, ... @@ -16,7 +16,7 @@ def __init__(self, load_prefix = 'load') : self.graph = self._load_graph (model_file, prefix = load_prefix) t_mt = self.graph.get_tensor_by_name(os.path.join(load_prefix, 'model_attr/model_type:0')) - sess = tf.Session (graph = self.graph) + sess = tf.Session (graph = self.graph, config=default_tf_session_config) [mt] = sess.run([t_mt], feed_dict = {}) self.model_type = mt.decode('utf-8') @@ -122,7 +122,7 @@ def __init__(self, # outputs self.t_tensor = self.graph.get_tensor_by_name (os.path.join(load_prefix, 'o_%s:0' % self.variable_name)) # start a tf session associated to the graph - self.sess = tf.Session (graph = self.graph) + self.sess = tf.Session (graph = self.graph, config=default_tf_session_config) [self.ntypes, self.rcut, self.tmap, self.tselt] = self.sess.run([self.t_ntypes, self.t_rcut, self.t_tmap, self.t_sel_type]) self.tmap = self.tmap.decode('UTF-8').split() diff --git a/source/train/DeepPot.py b/source/train/DeepPot.py index e3df6d6c8f..2a75bb7388 100644 --- a/source/train/DeepPot.py +++ b/source/train/DeepPot.py @@ -2,6 +2,7 @@ import numpy as np from deepmd.env import tf +from deepmd.env import default_tf_session_config from deepmd.common import make_default_mesh from deepmd.DeepEval import DeepEval from deepmd.DataModifier import DipoleChargeModifier @@ -43,7 +44,7 @@ def __init__(self, self.t_aparam = self.graph.get_tensor_by_name ('load/t_aparam:0') self.has_aparam = self.t_aparam is not None # start a tf session associated to the graph - self.sess = tf.Session (graph = self.graph) + self.sess = tf.Session (graph = self.graph, config=default_tf_session_config) [self.ntypes, self.rcut, self.dfparam, self.daparam, self.tmap] = self.sess.run([self.t_ntypes, self.t_rcut, self.t_dfparam, self.t_daparam, self.t_tmap]) self.tmap = self.tmap.decode('UTF-8').split() # setup modifier diff --git a/source/train/DescrptLocFrame.py b/source/train/DescrptLocFrame.py index 5d50384aad..69c1473db0 100644 --- a/source/train/DescrptLocFrame.py +++ b/source/train/DescrptLocFrame.py @@ -4,6 +4,7 @@ from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module +from deepmd.env import default_tf_session_config class DescrptLocFrame () : def __init__(self, jdata): @@ -55,7 +56,7 @@ def __init__(self, jdata): sel_a = self.sel_a, sel_r = self.sel_r, axis_rule = self.axis_rule) - self.sub_sess = tf.Session(graph = sub_graph) + self.sub_sess = tf.Session(graph = sub_graph, config=default_tf_session_config) def get_rcut (self) : diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 15ad2df7d6..3d2ce5d5cd 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -4,6 +4,7 @@ from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module +from deepmd.env import default_tf_session_config class DescrptSeA (): def __init__ (self, jdata): @@ -66,7 +67,7 @@ def __init__ (self, jdata): rcut_r_smth = self.rcut_r_smth, sel_a = self.sel_a, sel_r = self.sel_r) - self.sub_sess = tf.Session(graph = sub_graph) + self.sub_sess = tf.Session(graph = sub_graph, config=default_tf_session_config) def get_rcut (self) : diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index 85553eeeb9..76b039f633 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -4,6 +4,7 @@ from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module +from deepmd.env import default_tf_session_config class DescrptSeR (): def __init__ (self, jdata): @@ -60,7 +61,7 @@ def __init__ (self, jdata): rcut = self.rcut, rcut_smth = self.rcut_smth, sel = self.sel_r) - self.sub_sess = tf.Session(graph = sub_graph) + self.sub_sess = tf.Session(graph = sub_graph, config=default_tf_session_config) def get_rcut (self) : diff --git a/source/train/EwaldRecp.py b/source/train/EwaldRecp.py index 0fbeed30d6..2517669454 100644 --- a/source/train/EwaldRecp.py +++ b/source/train/EwaldRecp.py @@ -7,6 +7,7 @@ from deepmd.RunOptions import global_cvt_2_tf_float from deepmd.RunOptions import global_cvt_2_ener_float from deepmd.env import op_module +from deepmd.env import default_tf_session_config class EwaldRecp () : def __init__(self, @@ -25,7 +26,7 @@ def __init__(self, = op_module.ewald_recp(self.t_coord, self.t_charge, self.t_nloc, self.t_box, ewald_h = self.hh, ewald_beta = self.beta) - self.sess = tf.Session(graph=graph) + self.sess = tf.Session(graph=graph, config=default_tf_session_config) def eval(self, coord, diff --git a/source/train/RunOptions.py.in b/source/train/RunOptions.py.in index aa6bf081db..63d3544ca6 100644 --- a/source/train/RunOptions.py.in +++ b/source/train/RunOptions.py.in @@ -1,5 +1,6 @@ import os,sys -import tensorflow as tf +from deepmd.env import tf +from deepmd.env import get_tf_default_nthreads import numpy as np import deepmd.cluster.Slurm as Slurm import deepmd.cluster.Local as Local @@ -28,14 +29,6 @@ global_git_branch='@GIT_BRANCH@' global_tf_include_dir='@TensorFlow_INCLUDE_DIRS@' global_tf_libs='@TensorFlow_LIBRARY@' -def _get_threads_env () : - num_intra_threads = None - if 'OMP_NUM_THREADS' in os.environ : - num_intra_threads = int(os.environ['OMP_NUM_THREADS']) - else : - num_intra_threads = 0 - return num_intra_threads - def _is_slurm() : return "SLURM_JOB_NODELIST" in os.environ @@ -106,10 +99,6 @@ class RunOptions (object) : def __init__ (self, args, try_distrib = False): - # thread settings - self.num_intra_threads = _get_threads_env() - self.num_inter_threads = 0 - # distributed tasks if try_distrib : self._try_init_mpi() @@ -132,8 +121,6 @@ class RunOptions (object) : if args.restart is not None: self.restart = os.path.abspath(args.restart) self.init_mode = "restart" - if args.inter_threads is not None : - self.num_inter_threads = args.inter_threads def message (self, msg) : if self.verbose : @@ -167,28 +154,32 @@ class RunOptions (object) : def print_summary(self) : msg = "" msg += "---Summary of the training---------------------------------------\n" - msg += 'installed to: %s\n' % global_install_prefix - msg += 'source : %s\n' % global_git_summ - msg += 'source brach: %s\n' % global_git_branch - msg += 'source commit: %s\n' % global_git_hash - msg += 'source commit at: %s\n' % global_git_date - msg += 'build float prec: %s\n' % global_float_prec - msg += 'build with tf inc: %s\n' % global_tf_include_dir + msg += 'installed to: %s\n' % global_install_prefix + msg += 'source : %s\n' % global_git_summ + msg += 'source brach: %s\n' % global_git_branch + msg += 'source commit: %s\n' % global_git_hash + msg += 'source commit at: %s\n' % global_git_date + msg += 'build float prec: %s\n' % global_float_prec + msg += 'build with tf inc: %s\n' % global_tf_include_dir for idx,ii in enumerate(global_tf_libs.split(';')) : if idx == 0 : - msg += 'build with tf lib: %s\n' % ii + msg += 'build with tf lib: %s\n' % ii else : - msg += ' %s\n' % ii + msg += ' %s\n' % ii if self.is_distrib: msg += "distributed\n" - msg += "ps list: %s\n" % str(self.cluster['ps']) - msg += "worker list: %s\n" % str(self.cluster['worker']) - msg += "chief on: %s\n" % self.nodename + msg += "ps list: %s\n" % str(self.cluster['ps']) + msg += "worker list: %s\n" % str(self.cluster['worker']) + msg += "chief on: %s\n" % self.nodename else : - msg += "running on: %s\n" % self.nodename - msg += "gpu per node: %s\n" % self.gpus - msg += "num_inter_threads: %d\n" % self.num_inter_threads - msg += "num_intra_threads: %d\n" % self.num_intra_threads + msg += "running on: %s\n" % self.nodename + if self.gpus is None: + msg += "CUDA_VISIBLE_DEVICES: unset\n" + else: + msg += "CUDA_VISIBLE_DEVICES: %s\n" % self.gpus + intra, inter = get_tf_default_nthreads() + msg += "num_intra_threads: %d\n" % intra + msg += "num_inter_threads: %d\n" % inter msg += "-----------------------------------------------------------------\n" self.message(msg) diff --git a/source/train/Trainer.py b/source/train/Trainer.py index f8da95b8ab..7d26159a25 100644 --- a/source/train/Trainer.py +++ b/source/train/Trainer.py @@ -4,6 +4,7 @@ import shutil import numpy as np from deepmd.env import tf +from deepmd.env import default_tf_session_config from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_ener_float_precision from deepmd.Fitting import EnerFitting, WFCFitting, PolarFittingLocFrame, PolarFittingSeA, GlobalPolarFittingSeA, DipoleFittingSeA @@ -288,10 +289,7 @@ def _build_training(self): self._message("built training") def _init_sess_serial(self) : - self.sess = tf.Session( - config=tf.ConfigProto(intra_op_parallelism_threads=self.run_opt.num_intra_threads, - inter_op_parallelism_threads=self.run_opt.num_inter_threads - )) + self.sess = tf.Session(config=default_tf_session_config) self.saver = tf.train.Saver() saver = self.saver if self.run_opt.init_mode == 'init_from_scratch' : diff --git a/source/train/env.py b/source/train/env.py index f5baf53aa4..dec9ec8eaa 100644 --- a/source/train/env.py +++ b/source/train/env.py @@ -11,10 +11,11 @@ except ImportError: import tensorflow as tf -def set_env_if_empty(key, value): +def set_env_if_empty(key, value, verbose=True): if os.environ.get(key) is None: os.environ[key] = value - logging.warn("Environment variable {} is empty. Use the default value {}".format(key, value)) + if verbose: + logging.warn("Environment variable {} is empty. Use the default value {}".format(key, value)) def set_mkl(): """Tuning MKL for the best performance @@ -32,6 +33,18 @@ def set_mkl(): set_env_if_empty("KMP_AFFINITY", "granularity=fine,verbose,compact,1,0") reload(np) +def set_tf_default_nthreads(): + set_env_if_empty("TF_INTRA_OP_PARALLELISM_THREADS", "0", verbose=False) + set_env_if_empty("TF_INTER_OP_PARALLELISM_THREADS", "0", verbose=False) + +def get_tf_default_nthreads(): + return int(os.environ.get('TF_INTRA_OP_PARALLELISM_THREADS')), int(os.environ.get('TF_INTER_OP_PARALLELISM_THREADS')) + +def get_tf_session_config(): + set_tf_default_nthreads() + intra, inter = get_tf_default_nthreads() + return tf.ConfigProto(intra_op_parallelism_threads=intra, inter_op_parallelism_threads=inter) + def get_module(module_name): """Load force module.""" if platform.system() == "Windows": @@ -46,4 +59,5 @@ def get_module(module_name): return module op_module = get_module("libop_abi") -op_grads_module = get_module("libop_grads") \ No newline at end of file +op_grads_module = get_module("libop_grads") +default_tf_session_config = get_tf_session_config() From 140762ffc6c38cbc6a7ce7f1c1049350817ed450 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Tue, 21 Jan 2020 10:12:00 +0800 Subject: [PATCH 065/147] document the enviromental variables controling multithreading --- README.md | 11 +++++++++-- source/train/main.py | 5 ----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a6187acc03..d180777af3 100644 --- a/README.md +++ b/README.md @@ -437,8 +437,6 @@ positional arguments: optional arguments: -h, --help show this help message and exit - -t INTER_THREADS, --inter-threads INTER_THREADS - With default value 0. Setting the "inter_op_parallelism_threads" key for the tensorflow, the "intra_op_parallelism_threads" will be set by the env variable OMP_NUM_THREADS --init-model INIT_MODEL Initialize a model by the provided checkpoint --restart RESTART Restart the training from the provided checkpoint @@ -449,6 +447,15 @@ The keys `intra_op_parallelism_threads` and `inter_op_parallelism_threads` are T **`--restart model.ckpt`**, continues the training from the checkpoint `model.ckpt`. +On some resources limited machines, one may want to control the number of threads used by DeePMD-kit. This is achieved by three environmental variables: `OMP_NUM_THREADS`, `TF_INTRA_OP_PARALLELISM_THREADS` and `TF_INTER_OP_PARALLELISM_THREADS`. `OMP_NUM_THREADS` controls the multithreading of DeePMD-kit implemented operations. `TF_INTRA_OP_PARALLELISM_THREADS` and `TF_INTER_OP_PARALLELISM_THREADS` controls `intra_op_parallelism_threads` and `inter_op_parallelism_threads`, which are Tensorflow configurations for multithreading. An explanation is found [here](https://stackoverflow.com/questions/41233635/meaning-of-inter-op-parallelism-threads-and-intra-op-parallelism-threads). + +For example if you wish to use 3 cores of 2 CPUs on one node, you may set the environmental variables and run DeePMD-kit as follows: +```bash +export OMP_NUM_THREADS=6 +export TF_INTRA_OP_PARALLELISM_THREADS=3 +export TF_INTER_OP_PARALLELISM_THREADS=2 +dp train input.json +``` ## Freeze a model diff --git a/source/train/main.py b/source/train/main.py index c0e4a173be..dac5bd04ff 100644 --- a/source/train/main.py +++ b/source/train/main.py @@ -18,11 +18,6 @@ def main () : parser_train = subparsers.add_parser('train', help='train a model') parser_train.add_argument('INPUT', help='the input parameter file in json format') - parser_train.add_argument('-t','--inter-threads', type = int, default = default_num_inter_threads, - help= - 'With default value %d. ' % default_num_inter_threads + - 'Setting the "inter_op_parallelism_threads" key for the tensorflow, ' + - 'the "intra_op_parallelism_threads" will be set by the env variable OMP_NUM_THREADS') parser_train.add_argument('--init-model', type = str, help= 'Initialize the model by the provided checkpoint.') From 1a81455bcf74109f70bafad0ce8e355b421222c3 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Mon, 20 Jan 2020 22:10:01 -0500 Subject: [PATCH 066/147] update pip installation method; remove useless troubleshooting --- README.md | 60 ++++++++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index a6187acc03..23393ee2ed 100644 --- a/README.md +++ b/README.md @@ -111,18 +111,17 @@ Both CPU and GPU version offline package are avaiable in [the Releases page](htt ## Install the python interface ### Install the Tensorflow's python interface -First, check the python version and compiler version on your machine +First, check the python version on your machine ```bash -python --version; gcc --version +python --version ``` -If your python version is 3.7.x, it is highly recommended that the GNU C/C++ compiler is higher than or equal to 5.0. We follow the virtual environment approach to install the tensorflow's Python interface. The full instruction can be found on [the tensorflow's official website](https://www.tensorflow.org/install/pip). Now we assume that the Python interface will be installed to virtual environment directory `$tensorflow_venv` ```bash virtualenv -p python3 $tensorflow_venv source $tensorflow_venv/bin/activate pip install --upgrade pip -pip install --upgrade tensorflow==1.14.0 +pip install --upgrade tensorflow==2.1.0 ``` It is notice that everytime a new shell is started and one wants to use `DeePMD-kit`, the virtual environment should be activated by ```bash @@ -136,31 +135,17 @@ If one has multiple python interpreters named like python3.x, it can be specifie ```bash virtualenv -p python3.7 $tensorflow_venv ``` -If one needs the GPU support of deepmd-kit, the GPU version of tensorflow should be installed by -```bash -pip install --upgrade tensorflow-gpu==1.14.0 -``` To verify the installation, run ```bash -python -c "import tensorflow as tf; sess=tf.Session(); print(sess.run(tf.reduce_sum(tf.random_normal([1000, 1000]))))" +python -c "import tensorflow as tf;print(tf.reduce_sum(tf.random.normal([1000, 1000])))" ``` One should remember to activate the virtual environment every time he/she uses deepmd-kit. ### Install the DeePMD-kit's python interface -Clone the DeePMD-kit source code -```bash -cd /some/workspace -git clone --recursive https://github.com/deepmodeling/deepmd-kit.git deepmd-kit -b devel -``` -If one downloads the .zip file from the github, then the default folder of source code would be `deepmd-kit-master` rather than `deepmd-kit`. For convenience, you may want to record the location of source to a variable, saying `deepmd_source_dir` by -```bash -cd deepmd-kit -deepmd_source_dir=`pwd` -``` -Then execute +Execute ```bash -pip install . +pip install deepmd-kit ``` To test the installation, one may execute ```bash @@ -189,11 +174,30 @@ If one does not need to use DeePMD-kit with Lammps or I-Pi, then the python inte ### Install the Tensorflow's C++ interface -It is highly recommended that one keeps the same C/C++ compiler as the python interface. The C++ interface of DeePMD-kit was tested with compiler gcc >= 4.8. It is noticed that the I-Pi support is only compiled with gcc >= 4.9. +Check the compiler version on your machine + +``` +gcc --version +``` + +The C++ interface of DeePMD-kit was tested with compiler gcc >= 4.8. It is noticed that the I-Pi support is only compiled with gcc >= 4.9. First the C++ interface of Tensorflow should be installed. It is noted that the version of Tensorflow should be in consistent with the python interface. We assume that you have followed our instruction and installed tensorflow python interface 1.14.0 with, then you may follow [the instruction for CPU](doc/install-tf.1.14.md) to install the corresponding C++ interface (CPU only). If one wants GPU supports, he/she should follow [the instruction for GPU](doc/install-tf.1.14-gpu.md) to install the C++ interface. ### Install the DeePMD-kit's C++ interface + +Clone the DeePMD-kit source code +```bash +cd /some/workspace +git clone --recursive https://github.com/deepmodeling/deepmd-kit.git deepmd-kit +``` + +For convenience, you may want to record the location of source to a variable, saying `deepmd_source_dir` by +```bash +cd deepmd-kit +deepmd_source_dir=`pwd` +``` + Now goto the source code directory of DeePMD-kit and make a build place. ```bash cd $deepmd_source_dir/source @@ -606,18 +610,6 @@ rm -r * ``` and redo the `cmake` process. -## Training: TensorFlow abi binary cannot be found when doing training -If you confront such kind of error: - -``` -$deepmd_root/lib/deepmd/libop_abi.so: undefined symbol: -_ZN10tensorflow8internal21CheckOpMessageBuilder9NewStringB5cxx11Ev -``` - -This may happen if you are using a gcc >= 5.0, and tensorflow was compiled with gcc < 5.0. You may set `-DOP_CXX_ABI=0` in the process of `cmake`. - -Another possible reason might be the large gap between the python version of TensorFlow and the TensorFlow c++ interface. - ## MD: cannot run LAMMPS after installing a new version of DeePMD-kit This typically happens when you install a new version of DeePMD-kit and copy directly the generated `USER-DEEPMD` to a LAMMPS source code folder and re-install LAMMPS. From a9598687ee62205224e5754c985f69946cce4e78 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Wed, 22 Jan 2020 10:16:49 +0800 Subject: [PATCH 067/147] fix bug of test data --- source/train/test.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/train/test.py b/source/train/test.py index 29b66932dd..ce725d4002 100755 --- a/source/train/test.py +++ b/source/train/test.py @@ -6,7 +6,6 @@ import argparse import numpy as np -from deepmd.Data import DataSets from deepmd.Data import DeepmdData from deepmd import DeepEval from deepmd import DeepPot @@ -35,13 +34,15 @@ def test_ener (args) : if args.rand_seed is not None : np.random.seed(args.rand_seed % (2**32)) - data = DataSets (args.system, args.set_prefix, shuffle_test = args.shuffle_test) + dp = DeepPot(args.model) + data = DeepmdData(args.system, args.set_prefix, shuffle_test = args.shuffle_test, type_map = dp.get_type_map()) + test_data = data.get_test () numb_test = args.numb_test natoms = len(test_data["type"][0]) nframes = test_data["box"].shape[0] numb_test = min(nframes, numb_test) - dp = DeepPot(args.model) + coord = test_data["coord"][:numb_test].reshape([numb_test, -1]) box = test_data["box"][:numb_test] atype = test_data["type"][0] From 3af58b63491f4b0c6ad6ca117a60cf03f6c29b83 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Wed, 22 Jan 2020 15:31:03 +0800 Subject: [PATCH 068/147] add setup requirements --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 50ccafa849..8c6a335ad4 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ tf_install_dir = imp.find_module('tensorflow', [site_packages_path])[1] install_requires=['numpy', 'scipy'] -setup_requires=['setuptools_scm'] +setup_requires=['setuptools_scm', 'scikit-build', 'cmake'] # add cmake as a build requirement if cmake>3.0 is not installed try: From a2ac409ca9e0f5f1a936b237b6375576bcfca273 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Wed, 22 Jan 2020 10:26:10 -0500 Subject: [PATCH 069/147] comment upgrading of pip --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 019256c993..4db9e48dd4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -90,7 +90,7 @@ jobs: after_success: - if [[ $TRAVIS_TAG ]]; then python -m twine upload wheelhouse/*; python -m twine upload dist/*.tar.gz; fi before_install: - - pip install --upgrade pip + #- pip install --upgrade pip - pip install --upgrade setuptools - pip install tensorflow==$TENSORFLOW_VERSION install: From 57abf992f45622c935e4ee1447c7b88609c29248 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Wed, 22 Jan 2020 18:50:49 -0500 Subject: [PATCH 070/147] add get_type_map for c++ api --- source/lib/include/NNPInter.h | 1 + source/lib/src/NNPInter.cc | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/source/lib/include/NNPInter.h b/source/lib/include/NNPInter.h index f0b5a01f82..69a0ecf7d1 100644 --- a/source/lib/include/NNPInter.h +++ b/source/lib/include/NNPInter.h @@ -59,6 +59,7 @@ class NNPInter int numb_types () const {assert(inited); return ntypes;}; int dim_fparam () const {assert(inited); return dfparam;}; int dim_aparam () const {assert(inited); return daparam;}; + void get_type_map (std::string & type_map); private: Session* session; int num_intra_nthreads, num_inter_nthreads; diff --git a/source/lib/src/NNPInter.cc b/source/lib/src/NNPInter.cc index 6093ed128e..58042019c7 100644 --- a/source/lib/src/NNPInter.cc +++ b/source/lib/src/NNPInter.cc @@ -677,6 +677,11 @@ compute (ENERGYTYPE & dener, run_model (dener, dforce_, dvirial, datom_energy_, datom_virial_, session, input_tensors, nnpmap, nghost); } +void +NNPInter:: +get_type_map(std::string & type_map){ + type_map = get_scalar("model_attr/tmap"); +} From d3f7cded80ec25dcf4f182554f74797a1c1836cd Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Wed, 22 Jan 2020 19:14:52 -0500 Subject: [PATCH 071/147] add document for cpu-only tensorflow --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 23393ee2ed..873fd92d1e 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,10 @@ If one has multiple python interpreters named like python3.x, it can be specifie ```bash virtualenv -p python3.7 $tensorflow_venv ``` +If one does not need the GPU support of deepmd-kit and is concerned about package size, the CPU-only version of tensorflow should be installed by +```bash +pip install --upgrade tensorflow-cpu==2.1.0 +``` To verify the installation, run ```bash python -c "import tensorflow as tf;print(tf.reduce_sum(tf.random.normal([1000, 1000])))" From b7940fcded97f3fdda7b7d8b63b8db77b8d0832a Mon Sep 17 00:00:00 2001 From: Lu Date: Thu, 23 Jan 2020 13:02:33 +0800 Subject: [PATCH 072/147] fix bug of 0 output when sec_a.back() is lager than 1024 --- source/op/cuda/descrpt_se_a.cu | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source/op/cuda/descrpt_se_a.cu b/source/op/cuda/descrpt_se_a.cu index d9f6d357b0..39434306f2 100644 --- a/source/op/cuda/descrpt_se_a.cu +++ b/source/op/cuda/descrpt_se_a.cu @@ -194,13 +194,15 @@ __global__ void compute_descriptor_se_a (VALUETYPE* descript, const VALUETYPE* coord, const VALUETYPE rmin, const VALUETYPE rmax, - compute_t* sel_a_diff_dev) + compute_t* sel_a_diff_dev, + const int sec_a_size) { // <<>> - const unsigned int idx = blockIdx.x; - const unsigned int idy = threadIdx.x; + const unsigned int idx = blockIdx.y; + const unsigned int idy = blockIdx.x * blockDim.x + threadIdx.x; const int idx_deriv = idy * 4 * 3; // 4 components time 3 directions const int idx_value = idy * 4; // 4 components + if (idy >= sec_a_size) {return;} // else {return;} VALUETYPE * row_descript = descript + idx * ndescrpt; @@ -341,7 +343,9 @@ void DescrptSeALauncher(const VALUETYPE* coord, ); } - compute_descriptor_se_a<<>> ( + const int nblock_ = (sec_a.back() + LEN -1) / LEN; + dim3 block_grid(nblock_, nloc); + compute_descriptor_se_a<<>> ( descript, ndescrpt, descript_deriv, @@ -356,7 +360,8 @@ void DescrptSeALauncher(const VALUETYPE* coord, coord, rcut_r_smth, rcut_r, - sel_a_diff + sel_a_diff, + sec_a.back() ); //// // res = cudaFree(sec_a_dev); cudaErrcheck(res); From fb79cbeb03809a5fdc157baee72eb4df42fc0928 Mon Sep 17 00:00:00 2001 From: Lu Date: Thu, 23 Jan 2020 15:05:48 +0800 Subject: [PATCH 073/147] fix bug of 0 output when sec_a.back() is lager than 1024 --- source/op/cuda/descrpt_se_r.cu | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/source/op/cuda/descrpt_se_r.cu b/source/op/cuda/descrpt_se_r.cu index 37cee39d43..fa9678be34 100644 --- a/source/op/cuda/descrpt_se_r.cu +++ b/source/op/cuda/descrpt_se_r.cu @@ -195,14 +195,16 @@ __global__ void compute_descriptor_se_r (VALUETYPE* descript, const VALUETYPE* coord, const VALUETYPE rmin, const VALUETYPE rmax, - compute_t* sel_diff_dev) + compute_t* sel_diff_dev, + const int sec_size) { // <<>> - const unsigned int idx = blockIdx.x; - const unsigned int idy = threadIdx.x; + const unsigned int idx = blockIdx.y; + const unsigned int idy = blockIdx.x * blockDim.x + threadIdx.x; const int idx_deriv = idy * 3; // 1 components time 3 directions const int idx_value = idy; // 1 components - + if (idy >= sec_size) {return;} + // else {return;} VALUETYPE * row_descript = descript + idx * ndescrpt; VALUETYPE * row_descript_deriv = descript_deriv + idx * descript_deriv_size; @@ -310,7 +312,9 @@ void DescrptSeRLauncher(const VALUETYPE* coord, nei_iter ); } - compute_descriptor_se_r<<>> ( + const int nblock_ = (sec.back() + LEN -1) / LEN; + dim3 block_grid(nblock_, nloc); + compute_descriptor_se_r<<>> ( descript, ndescrpt, descript_deriv, @@ -325,6 +329,7 @@ void DescrptSeRLauncher(const VALUETYPE* coord, coord, rcut_smth, rcut, - sel_diff + sel_diff, + sec.back() ); } \ No newline at end of file From 637692bf9f6e61d3e994ae8ca5563f782355a66b Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 31 Jan 2020 10:47:43 +0800 Subject: [PATCH 074/147] fix bug #165 --- source/train/test.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) mode change 100755 => 100644 source/train/test.py diff --git a/source/train/test.py b/source/train/test.py old mode 100755 new mode 100644 index ce725d4002..272e8d4377 --- a/source/train/test.py +++ b/source/train/test.py @@ -36,11 +36,18 @@ def test_ener (args) : dp = DeepPot(args.model) data = DeepmdData(args.system, args.set_prefix, shuffle_test = args.shuffle_test, type_map = dp.get_type_map()) + data.add('energy', 1, atomic=False, must=False, high_prec=True) + data.add('force', 3, atomic=True, must=False, high_prec=False) + data.add('virial', 9, atomic=False, must=False, high_prec=False) + if dp.get_dim_fparam() > 0: + data.add('fparam', dp.get_dim_fparam(), atomic=False, must=True, high_prec=False) + if dp.get_dim_aparam() > 0: + data.add('aparam', dp.get_dim_aparam(), atomic=True, must=True, high_prec=False) test_data = data.get_test () - numb_test = args.numb_test natoms = len(test_data["type"][0]) nframes = test_data["box"].shape[0] + numb_test = args.numb_test numb_test = min(nframes, numb_test) coord = test_data["coord"][:numb_test].reshape([numb_test, -1]) From a20ddee203cc1f41b2ad6b2264322bbcd6a53c86 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 31 Jan 2020 20:40:27 +0800 Subject: [PATCH 075/147] fix bug of nopbc in dp test --- source/train/test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/train/test.py b/source/train/test.py index 272e8d4377..d05a7cfb47 100644 --- a/source/train/test.py +++ b/source/train/test.py @@ -52,6 +52,8 @@ def test_ener (args) : coord = test_data["coord"][:numb_test].reshape([numb_test, -1]) box = test_data["box"][:numb_test] + if not data.pbc: + box = None atype = test_data["type"][0] if dp.get_dim_fparam() > 0: fparam = test_data["fparam"][:numb_test] From d517991c20c95a4b24737df8b86faef4085aa4dc Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Fri, 31 Jan 2020 16:35:29 -0500 Subject: [PATCH 076/147] allow no interaction between custom atom types --- source/train/DescrptSeA.py | 74 ++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 3d2ce5d5cd..6d28362ac5 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -16,7 +16,8 @@ def __init__ (self, jdata): .add('axis_neuron', int, default = 4, alias = 'n_axis_neuron') \ .add('resnet_dt',bool, default = False) \ .add('trainable',bool, default = True) \ - .add('seed', int) + .add('seed', int) \ + .add('no_inter_types', list, default = []) class_data = args.parse(jdata) self.sel_a = class_data['sel'] self.rcut_r = class_data['rcut'] @@ -26,6 +27,12 @@ def __init__ (self, jdata): self.filter_resnet_dt = class_data['resnet_dt'] self.seed = class_data['seed'] self.trainable = class_data['trainable'] + no_inter_types = class_data['no_inter_types'] + self.no_inter_types = set() + for tt in no_inter_types: + assert(len(tt) == 2) + self.no_inter_types.add((tt[0], tt[1])) + self.no_inter_types.add((tt[1], tt[0])) # descrpt config self.sel_r = [ 0 for ii in range(len(self.sel_a)) ] @@ -235,7 +242,7 @@ def _pass_filter(self, [ 0, start_index* self.ndescrpt], [-1, natoms[2+type_i]* self.ndescrpt] ) inputs_i = tf.reshape(inputs_i, [-1, self.ndescrpt]) - layer, qmat = self._filter(inputs_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable) + layer, qmat = self._filter(inputs_i, type_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable) layer = tf.reshape(layer, [tf.shape(inputs)[0], natoms[2+type_i] * self.get_dim_out()]) qmat = tf.reshape(qmat, [tf.shape(inputs)[0], natoms[2+type_i] * self.get_dim_rot_mat_1() * 3]) output.append(layer) @@ -297,6 +304,7 @@ def _compute_std (self,sumv2, sumv, sumn) : def _filter(self, inputs, + type_input, natoms, activation_fn=tf.nn.tanh, stddev=1.0, @@ -323,35 +331,39 @@ def _filter(self, # with (natom x nei_type_i) x 4 inputs_reshape = tf.reshape(inputs_i, [-1, 4]) xyz_scatter = tf.reshape(tf.slice(inputs_reshape, [0,0],[-1,1]),[-1,1]) - for ii in range(1, len(outputs_size)): - w = tf.get_variable('matrix_'+str(ii)+'_'+str(type_i), - [outputs_size[ii - 1], outputs_size[ii]], - global_tf_float_precision, - tf.random_normal_initializer(stddev=stddev/np.sqrt(outputs_size[ii]+outputs_size[ii-1]), seed = seed), - trainable = trainable) - b = tf.get_variable('bias_'+str(ii)+'_'+str(type_i), - [1, outputs_size[ii]], - global_tf_float_precision, - tf.random_normal_initializer(stddev=stddev, mean = bavg, seed = seed), - trainable = trainable) - if self.filter_resnet_dt : - idt = tf.get_variable('idt_'+str(ii)+'_'+str(type_i), - [1, outputs_size[ii]], - global_tf_float_precision, - tf.random_normal_initializer(stddev=0.001, mean = 1.0, seed = seed), - trainable = trainable) - if outputs_size[ii] == outputs_size[ii-1]: - if self.filter_resnet_dt : - xyz_scatter += activation_fn(tf.matmul(xyz_scatter, w) + b) * idt - else : - xyz_scatter += activation_fn(tf.matmul(xyz_scatter, w) + b) - elif outputs_size[ii] == outputs_size[ii-1] * 2: - if self.filter_resnet_dt : - xyz_scatter = tf.concat([xyz_scatter,xyz_scatter], 1) + activation_fn(tf.matmul(xyz_scatter, w) + b) * idt - else : - xyz_scatter = tf.concat([xyz_scatter,xyz_scatter], 1) + activation_fn(tf.matmul(xyz_scatter, w) + b) - else: - xyz_scatter = activation_fn(tf.matmul(xyz_scatter, w) + b) + if (type_input, type_i) not in self.no_inter_types: + for ii in range(1, len(outputs_size)): + w = tf.get_variable('matrix_'+str(ii)+'_'+str(type_i), + [outputs_size[ii - 1], outputs_size[ii]], + global_tf_float_precision, + tf.random_normal_initializer(stddev=stddev/np.sqrt(outputs_size[ii]+outputs_size[ii-1]), seed = seed), + trainable = trainable) + b = tf.get_variable('bias_'+str(ii)+'_'+str(type_i), + [1, outputs_size[ii]], + global_tf_float_precision, + tf.random_normal_initializer(stddev=stddev, mean = bavg, seed = seed), + trainable = trainable) + if self.filter_resnet_dt : + idt = tf.get_variable('idt_'+str(ii)+'_'+str(type_i), + [1, outputs_size[ii]], + global_tf_float_precision, + tf.random_normal_initializer(stddev=0.001, mean = 1.0, seed = seed), + trainable = trainable) + if outputs_size[ii] == outputs_size[ii-1]: + if self.filter_resnet_dt : + xyz_scatter += activation_fn(tf.matmul(xyz_scatter, w) + b) * idt + else : + xyz_scatter += activation_fn(tf.matmul(xyz_scatter, w) + b) + elif outputs_size[ii] == outputs_size[ii-1] * 2: + if self.filter_resnet_dt : + xyz_scatter = tf.concat([xyz_scatter,xyz_scatter], 1) + activation_fn(tf.matmul(xyz_scatter, w) + b) * idt + else : + xyz_scatter = tf.concat([xyz_scatter,xyz_scatter], 1) + activation_fn(tf.matmul(xyz_scatter, w) + b) + else: + xyz_scatter = activation_fn(tf.matmul(xyz_scatter, w) + b) + else: + w = tf.zeros((outputs_size[0], outputs_size[-1]), dtype=global_tf_float_precision) + xyz_scatter = tf.matmul(xyz_scatter, w) # natom x nei_type_i x out_size xyz_scatter = tf.reshape(xyz_scatter, (-1, shape_i[1]//4, outputs_size[-1])) xyz_scatter_total.append(xyz_scatter) From 86c75da5ee68836e98fb5b46306db87bc157a0d2 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sat, 1 Feb 2020 10:24:26 +0800 Subject: [PATCH 077/147] std should be set to 1 if its value vanishes --- source/train/DescrptSeA.py | 5 ++++- source/train/DescrptSeR.py | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 3d2ce5d5cd..08b97c7948 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -292,7 +292,10 @@ def _compute_dstats_sys_smth (self, def _compute_std (self,sumv2, sumv, sumn) : - return np.sqrt(sumv2/sumn - np.multiply(sumv/sumn, sumv/sumn)) + val = np.sqrt(sumv2/sumn - np.multiply(sumv/sumn, sumv/sumn)) + if val == 0: + val = 1 + return val def _filter(self, diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index 76b039f633..cc5ca13c94 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -240,7 +240,11 @@ def _compute_dstats_sys_se_r (self, def _compute_std (self,sumv2, sumv, sumn) : - return np.sqrt(sumv2/sumn - np.multiply(sumv/sumn, sumv/sumn)) + val = np.sqrt(sumv2/sumn - np.multiply(sumv/sumn, sumv/sumn)) + if val == 0: + val = 1 + return val + def _filter_r(self, inputs, From 2b98a4e31a1e4fcaa223bff2bfc8f72c583922dd Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sat, 1 Feb 2020 10:31:00 +0800 Subject: [PATCH 078/147] protect the descrpt to 1e-2 rather than set to 1 --- source/train/DescrptSeA.py | 4 ++-- source/train/DescrptSeR.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 08b97c7948..9a8ee47fb6 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -293,8 +293,8 @@ def _compute_dstats_sys_smth (self, def _compute_std (self,sumv2, sumv, sumn) : val = np.sqrt(sumv2/sumn - np.multiply(sumv/sumn, sumv/sumn)) - if val == 0: - val = 1 + if np.abs(val) < 1e-2: + val = 1e-2 return val diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index cc5ca13c94..7a2d2125e5 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -241,8 +241,8 @@ def _compute_dstats_sys_se_r (self, def _compute_std (self,sumv2, sumv, sumn) : val = np.sqrt(sumv2/sumn - np.multiply(sumv/sumn, sumv/sumn)) - if val == 0: - val = 1 + if np.abs(val) < 1e-2: + val = 1e-2 return val From f78195dc879a53db57f4fe7e88a346f4639e14df Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sat, 1 Feb 2020 16:12:23 +0800 Subject: [PATCH 079/147] recursively test systems --- source/train/main.py | 2 +- source/train/test.py | 31 +++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/source/train/main.py b/source/train/main.py index dac5bd04ff..49aea59084 100644 --- a/source/train/main.py +++ b/source/train/main.py @@ -37,7 +37,7 @@ def main () : parser_tst.add_argument("-m", "--model", default="frozen_model.pb", type=str, help="Frozen model file to import") parser_tst.add_argument("-s", "--system", default=".", type=str, - help="The system dir") + help="The system dir. Recursively detect systems in this directory") parser_tst.add_argument("-S", "--set-prefix", default="set", type=str, help="The set prefix") parser_tst.add_argument("-n", "--numb-test", default=100, type=int, diff --git a/source/train/test.py b/source/train/test.py index d05a7cfb47..6269947758 100644 --- a/source/train/test.py +++ b/source/train/test.py @@ -16,20 +16,31 @@ def test (args): de = DeepEval(args.model) - if de.model_type == 'ener': - test_ener(args) - elif de.model_type == 'dipole': - test_dipole(args) - elif de.model_type == 'polar': - test_polar(args) - elif de.model_type == 'wfc': - test_wfc(args) - else : - raise RuntimeError('unknow model type '+de.model_type) + all_sys = [] + from pathlib import Path + for filename in Path(args.system).rglob('type.raw'): + all_sys.append(os.path.dirname(filename)) + for ii in all_sys: + args.system = ii + print ("# ---------------output of dp test--------------- ") + print ("# testing system : " + ii) + if de.model_type == 'ener': + test_ener(args) + elif de.model_type == 'dipole': + test_dipole(args) + elif de.model_type == 'polar': + test_polar(args) + elif de.model_type == 'wfc': + test_wfc(args) + else : + raise RuntimeError('unknow model type '+de.model_type) + print ("# ----------------------------------------------- ") + def l2err (diff) : return np.sqrt(np.average (diff*diff)) + def test_ener (args) : if args.rand_seed is not None : np.random.seed(args.rand_seed % (2**32)) From ce4fa4daab9dc1d89abc8f5e9ef31aa0321d80ac Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Sat, 1 Feb 2020 21:07:40 -0500 Subject: [PATCH 080/147] supports user-specified atomic energy --- source/train/Fitting.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index c940bcbcb1..5532777257 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -20,7 +20,8 @@ def __init__ (self, jdata, descrpt): .add('neuron', list, default = [120,120,120], alias = 'n_neuron')\ .add('resnet_dt', bool, default = True)\ .add('rcond', float, default = 1e-3) \ - .add('seed', int) + .add('seed', int) \ + .add('atom_ener', list, default = []) class_data = args.parse(jdata) self.numb_fparam = class_data['numb_fparam'] self.numb_aparam = class_data['numb_aparam'] @@ -28,6 +29,12 @@ def __init__ (self, jdata, descrpt): self.resnet_dt = class_data['resnet_dt'] self.rcond = class_data['rcond'] self.seed = class_data['seed'] + self.atom_ener = [] + for at, ae in enumerate(class_data['atom_ener']): + if ae is not None: + self.atom_ener.append(tf.constant(ae, global_tf_float_precision, name = "atom_%d_ener" % at)) + else: + self.atom_ener.append(None) self.useBN = False self.bias_atom_e = None # data requirement @@ -198,6 +205,22 @@ def build (self, else : layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) final_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + + if type_i < len(self.atom_ener) and self.atom_ener[type_i] is not None: + inputs_zero = tf.zeros_like(inputs_i, dtype=global_tf_float_precision) + layer = inputs_zero + if self.numb_fparam > 0 : + layer = tf.concat([layer, ext_fparam], axis = 1) + if self.numb_aparam > 0 : + layer = tf.concat([layer, ext_aparam], axis = 1) + for ii in range(0,len(self.n_neuron)) : + if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, use_timestep = self.resnet_dt) + else : + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed) + zero_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=True, seed = self.seed) + final_layer += self.atom_ener[type_i] - zero_layer + final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms[2+type_i]]) # concat the results From 60c3c7c59dadc16fc6b76f0218d597bb5c6ae95b Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Sat, 1 Feb 2020 21:08:20 -0500 Subject: [PATCH 081/147] supports setting davg of descriptor to 0 --- source/train/DescrptSeA.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 70223cbcdb..f80a3c64b1 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -17,7 +17,8 @@ def __init__ (self, jdata): .add('resnet_dt',bool, default = False) \ .add('trainable',bool, default = True) \ .add('seed', int) \ - .add('no_inter_types', list, default = []) + .add('no_inter_types', list, default = []) \ + .add('set_davg_zero', bool, default = False) class_data = args.parse(jdata) self.sel_a = class_data['sel'] self.rcut_r = class_data['rcut'] @@ -33,6 +34,7 @@ def __init__ (self, jdata): assert(len(tt) == 2) self.no_inter_types.add((tt[0], tt[1])) self.no_inter_types.add((tt[1], tt[0])) + self.set_davg_zero = class_data['set_davg_zero'] # descrpt config self.sel_r = [ 0 for ii in range(len(self.sel_a)) ] @@ -131,7 +133,8 @@ def compute_input_stats (self, all_davg.append(davg) all_dstd.append(dstd) - self.davg = np.array(all_davg) + if not self.set_davg_zero: + self.davg = np.array(all_davg) self.dstd = np.array(all_dstd) From 1194f8c5051d969688e14ec8f857411e698d40ec Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sun, 2 Feb 2020 16:50:16 +0800 Subject: [PATCH 082/147] implement block weighted prob_sys_size --- source/tests/test_deepmd_data_sys.py | 32 ++++++++++++ source/train/DataSystem.py | 74 ++++++++++++++++++++++------ 2 files changed, 92 insertions(+), 14 deletions(-) diff --git a/source/tests/test_deepmd_data_sys.py b/source/tests/test_deepmd_data_sys.py index 39c5a45a60..d08b148f3a 100644 --- a/source/tests/test_deepmd_data_sys.py +++ b/source/tests/test_deepmd_data_sys.py @@ -231,6 +231,38 @@ def test_get_batch(self): ), 0.0) + + def test_prob_sys_size_1(self) : + batch_size = 1 + test_size = 1 + ds = DeepmdDataSystem(self.sys_name, batch_size, test_size, 2.0) + prob = ds._prob_sys_size_ext("prob_sys_size; 0:2:2; 2:4:8") + self.assertAlmostEqual(np.sum(prob), 1) + self.assertAlmostEqual(np.sum(prob[0:2]), 0.2) + self.assertAlmostEqual(np.sum(prob[2:4]), 0.8) + # number of training set is self.nset-1 + # shift is the total number of set size shift... + shift = np.sum(np.arange(self.nset-1)) + self.assertAlmostEqual(prob[1]/prob[0], float(self.nframes[1]*(self.nset-1)+shift)/float(self.nframes[0]*(self.nset-1)+shift)) + self.assertAlmostEqual(prob[3]/prob[2], float(self.nframes[3]*(self.nset-1)+shift)/float(self.nframes[2]*(self.nset-1)+shift)) + + + def test_prob_sys_size_1(self) : + batch_size = 1 + test_size = 1 + ds = DeepmdDataSystem(self.sys_name, batch_size, test_size, 2.0) + prob = ds._prob_sys_size_ext("prob_sys_size; 1:2:0.4; 2:4:1.6") + self.assertAlmostEqual(np.sum(prob), 1) + self.assertAlmostEqual(np.sum(prob[1:2]), 0.2) + self.assertAlmostEqual(np.sum(prob[2:4]), 0.8) + # number of training set is self.nset-1 + # shift is the total number of set size shift... + shift = np.sum(np.arange(self.nset-1)) + self.assertAlmostEqual(prob[0], 0.0) + self.assertAlmostEqual(prob[1], 0.2) + self.assertAlmostEqual(prob[3]/prob[2], float(self.nframes[3]*(self.nset-1)+shift)/float(self.nframes[2]*(self.nset-1)+shift)) + + def _idx_map(self, target, idx_map, ndof): natoms = len(idx_map) target = target.reshape([-1, natoms, ndof]) diff --git a/source/train/DataSystem.py b/source/train/DataSystem.py index 27e397a030..714b8ebbb1 100644 --- a/source/train/DataSystem.py +++ b/source/train/DataSystem.py @@ -157,22 +157,47 @@ def get_data_dict(self) : def get_batch (self, sys_idx = None, - sys_weights = None, - style = "prob_sys_size") : + sys_probs = None, + auto_prob_style = "prob_sys_size") : + """ + Get a batch of data from the data system + + Parameters + ---------- + sys_idx: int + The index of system from which the batch is get. + If sys_idx is not None, `sys_probs` and `auto_prob_style` are ignored + If sys_idx is None, automatically determine the system according to `sys_probs` or `auto_prob_style`, see the following. + sys_probs: list of float + The probabilitis of systems to get the batch. + Summation of positive elements of this list should be no greater than 1. + Element of this list can be negative, the probability of the corresponding system is determined automatically by the number of batches in the system. + auto_prob_style: float + Determine the probability of systems automatically. The method is assigned by this key and can be + - "prob_uniform" : the probability all the systems are equal, namely 1.0/self.get_nsystems() + - "prob_sys_size" : the probability of a system is proportional to the number of batches in the system + - "prob_sys_size;stt_idx:end_idx:weight;stt_idx:end_idx:weight;..." : + the list of systems is devided into blocks. A block is specified by `stt_idx:end_idx:weight`, + where `stt_idx` is the starting index of the system, `end_idx` is then ending (not including) index of the system, + the probabilities of the systems in this block sums up to `weight`, and the relatively probabilities within this block is proportional + to the number of batches in the system. + """ if not hasattr(self, 'default_mesh') : self._make_default_mesh() if sys_idx is not None : self.pick_idx = sys_idx else : - if sys_weights is None : - if style == "prob_sys_size" : - prob = self.prob_nbatches - elif style == "prob_uniform" : + if sys_probs is None : + if auto_prob_style == "prob_uniform" : prob = None + elif auto_prob_style == "prob_sys_size" : + prob = self.prob_nbatches + elif auto_prob_style[:13] == "prob_sys_size;" : + prob = self._prob_sys_size_ext(auto_prob_style) else : - raise RuntimeError("unkown get_batch style") + raise RuntimeError("unkown style " + auto_prob_style ) else : - prob = self.process_sys_weights(sys_weights) + prob = self._process_sys_probs(sys_probs) self.pick_idx = np.random.choice(np.arange(self.nsystems), p = prob) b_data = self.data_systems[self.pick_idx].get_batch(self.batch_size[self.pick_idx]) b_data["natoms_vec"] = self.natoms_vec[self.pick_idx] @@ -264,18 +289,39 @@ def _check_type_map_consistency(self, type_map_list): ret = ii return ret - def _process_sys_weights(self, sys_weights) : - sys_weights = np.array(sys_weights) - type_filter = sys_weights >= 0 - assigned_sum_prob = np.sum(type_filter * sys_weights) + def _process_sys_probs(self, sys_probs) : + sys_probs = np.array(sys_probs) + type_filter = sys_probs >= 0 + assigned_sum_prob = np.sum(type_filter * sys_probs) assert assigned_sum_prob <= 1, "the sum of assigned probability should be less than 1" rest_sum_prob = 1. - assigned_sum_prob rest_nbatch = (1 - type_filter) * self.nbatches rest_prob = rest_sum_prob * rest_nbatch / np.sum(rest_nbatch) - ret_prob = rest_prob + type_filter * sys_weights + ret_prob = rest_prob + type_filter * sys_probs assert np.sum(ret_prob) == 1, "sum of probs should be 1" return ret_prob - + + def _prob_sys_size_ext(self, keywords): + block_str = keywords.split(';')[1:] + block_stt = [] + block_end = [] + block_weights = [] + for ii in block_str: + stt = int(ii.split(':')[0]) + end = int(ii.split(':')[1]) + weight = float(ii.split(':')[2]) + assert(weight >= 0), "the weight of a block should be no less than 0" + block_stt.append(stt) + block_end.append(end) + block_weights.append(weight) + nblocks = len(block_str) + block_probs = np.array(block_weights) / np.sum(block_weights) + sys_probs = np.zeros([self.get_nsystems()]) + for ii in range(nblocks): + nbatch_block = self.nbatches[block_stt[ii]:block_end[ii]] + tmp_prob = [float(i) for i in nbatch_block] / np.sum(nbatch_block) + sys_probs[block_stt[ii]:block_end[ii]] = tmp_prob * block_probs[ii] + return sys_probs From a2aa039b64e163f93a36da63c3dd676f67cd8ef2 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sun, 2 Feb 2020 17:17:33 +0800 Subject: [PATCH 083/147] set automatic system probability style --- source/train/DataSystem.py | 2 +- source/train/Trainer.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source/train/DataSystem.py b/source/train/DataSystem.py index 714b8ebbb1..3960ca75a9 100644 --- a/source/train/DataSystem.py +++ b/source/train/DataSystem.py @@ -192,7 +192,7 @@ def get_batch (self, prob = None elif auto_prob_style == "prob_sys_size" : prob = self.prob_nbatches - elif auto_prob_style[:13] == "prob_sys_size;" : + elif auto_prob_style[:14] == "prob_sys_size;" : prob = self._prob_sys_size_ext(auto_prob_style) else : raise RuntimeError("unkown style " + auto_prob_style ) diff --git a/source/train/Trainer.py b/source/train/Trainer.py index 7d26159a25..a9731089b8 100644 --- a/source/train/Trainer.py +++ b/source/train/Trainer.py @@ -178,7 +178,8 @@ def _init_param(self, jdata): .add('timing_in_training', bool, default = True)\ .add('profiling', bool, default = False)\ .add('profiling_file',str, default = 'timeline.json')\ - .add('sys_weights', list ) + .add('sys_probs', list )\ + .add('auto_sys_prob_style', str, default = "prob_sys_size") tr_data = tr_args.parse(training_param) self.numb_test = tr_data['numb_test'] self.disp_file = tr_data['disp_file'] @@ -189,7 +190,8 @@ def _init_param(self, jdata): self.timing_in_training = tr_data['timing_in_training'] self.profiling = tr_data['profiling'] self.profiling_file = tr_data['profiling_file'] - self.sys_weights = tr_data['sys_weights'] + self.sys_probs = tr_data['sys_probs'] + self.auto_sys_prob_style = tr_data['auto_sys_prob_style'] self.useBN = False if fitting_type == 'ener' and self.fitting.get_numb_fparam() > 0 : self.numb_fparam = self.fitting.get_numb_fparam() @@ -391,7 +393,9 @@ def train (self, train_time = 0 while cur_batch < stop_batch : - batch_data = data.get_batch (sys_weights = self.sys_weights) + batch_data = data.get_batch (sys_probs = self.sys_probs, + auto_prob_style = self.auto_sys_prob_style + ) feed_dict_batch = {} for kk in batch_data.keys(): if kk == 'find_type' or kk == 'type' : From d7e13b2a13f6347e6865f28d567d81828e39eb2f Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sun, 2 Feb 2020 17:40:42 +0800 Subject: [PATCH 084/147] control auto_prob_style from input parameter. print probabilities of each in summary --- source/tests/test_data_modifier.py | 3 +- source/tests/test_data_modifier_shuffle.py | 3 +- source/train/DataSystem.py | 52 +++++++++++++--------- source/train/Trainer.py | 6 +-- source/train/train.py | 6 ++- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/source/tests/test_data_modifier.py b/source/tests/test_data_modifier.py index 134e31095e..4e7b43663e 100644 --- a/source/tests/test_data_modifier.py +++ b/source/tests/test_data_modifier.py @@ -61,8 +61,7 @@ def _setUp(self): batch_size, test_size, rcut, - set_prefix=set_pfx, - run_opt=run_opt) + set_prefix=set_pfx) data.add_dict(data_requirement) # clear the default graph diff --git a/source/tests/test_data_modifier_shuffle.py b/source/tests/test_data_modifier_shuffle.py index 81d36ed8ab..91b69fd936 100644 --- a/source/tests/test_data_modifier_shuffle.py +++ b/source/tests/test_data_modifier_shuffle.py @@ -67,8 +67,7 @@ def _setUp(self): batch_size, test_size, rcut, - set_prefix=set_pfx, - run_opt=run_opt) + set_prefix=set_pfx) data.add_dict(data_requirement) # clear the default graph diff --git a/source/train/DataSystem.py b/source/train/DataSystem.py index 3960ca75a9..aca8994535 100644 --- a/source/train/DataSystem.py +++ b/source/train/DataSystem.py @@ -16,7 +16,6 @@ def __init__ (self, rcut, set_prefix = 'set', shuffle_test = True, - run_opt = None, type_map = None, modifier = None) : # init data @@ -81,10 +80,6 @@ def __init__ (self, warnings.warn("system %s required test size is larger than the size of the dataset %s (%d > %d)" % \ (self.system_dirs[ii], chk_ret[0], test_size, chk_ret[1])) - # print summary - if run_opt is not None: - self.print_summary(run_opt) - def _load_test(self, ntests = -1): self.test_data = collections.defaultdict(list) @@ -155,6 +150,24 @@ def reduce(self, def get_data_dict(self) : return self.data_systems[0].get_data_dict() + + def _get_sys_probs(self, + sys_probs, + auto_prob_style) : + if sys_probs is None : + if auto_prob_style == "prob_uniform" : + prob = None + elif auto_prob_style == "prob_sys_size" : + prob = self.prob_nbatches + elif auto_prob_style[:14] == "prob_sys_size;" : + prob = self._prob_sys_size_ext(auto_prob_style) + else : + raise RuntimeError("unkown style " + auto_prob_style ) + else : + prob = self._process_sys_probs(sys_probs) + return prob + + def get_batch (self, sys_idx = None, sys_probs = None, @@ -187,17 +200,7 @@ def get_batch (self, if sys_idx is not None : self.pick_idx = sys_idx else : - if sys_probs is None : - if auto_prob_style == "prob_uniform" : - prob = None - elif auto_prob_style == "prob_sys_size" : - prob = self.prob_nbatches - elif auto_prob_style[:14] == "prob_sys_size;" : - prob = self._prob_sys_size_ext(auto_prob_style) - else : - raise RuntimeError("unkown style " + auto_prob_style ) - else : - prob = self._process_sys_probs(sys_probs) + prob = self._get_sys_probs(sys_probs, auto_prob_style) self.pick_idx = np.random.choice(np.arange(self.nsystems), p = prob) b_data = self.data_systems[self.pick_idx].get_batch(self.batch_size[self.pick_idx]) b_data["natoms_vec"] = self.natoms_vec[self.pick_idx] @@ -249,21 +252,26 @@ def _format_name_length(self, name, width) : name = '-- ' + name return name - def print_summary(self, run_opt) : + def print_summary(self, + run_opt, + sys_probs = None, + auto_prob_style = "prob_sys_size") : + prob = self._get_sys_probs(sys_probs, auto_prob_style) tmp_msg = "" # width 65 sys_width = 42 - tmp_msg += "---Summary of DataSystem-----------------------------------------\n" + tmp_msg += "---Summary of DataSystem------------------------------------------------\n" tmp_msg += "find %d system(s):\n" % self.nsystems tmp_msg += "%s " % self._format_name_length('system', sys_width) - tmp_msg += "%s %s %s\n" % ('natoms', 'bch_sz', 'n_bch') + tmp_msg += "%s %s %s %5s\n" % ('natoms', 'bch_sz', 'n_bch', 'prob') for ii in range(self.nsystems) : - tmp_msg += ("%s %6d %6d %5d\n" % + tmp_msg += ("%s %6d %6d %5d %5.3f\n" % (self._format_name_length(self.system_dirs[ii], sys_width), self.natoms[ii], self.batch_size[ii], - self.nbatches[ii]) ) - tmp_msg += "-----------------------------------------------------------------\n" + self.nbatches[ii], + prob[ii]) ) + tmp_msg += "------------------------------------------------------------------------\n" run_opt.message(tmp_msg) diff --git a/source/train/Trainer.py b/source/train/Trainer.py index a9731089b8..50db1adfbc 100644 --- a/source/train/Trainer.py +++ b/source/train/Trainer.py @@ -179,7 +179,7 @@ def _init_param(self, jdata): .add('profiling', bool, default = False)\ .add('profiling_file',str, default = 'timeline.json')\ .add('sys_probs', list )\ - .add('auto_sys_prob_style', str, default = "prob_sys_size") + .add('auto_prob_style', str, default = "prob_sys_size") tr_data = tr_args.parse(training_param) self.numb_test = tr_data['numb_test'] self.disp_file = tr_data['disp_file'] @@ -191,7 +191,7 @@ def _init_param(self, jdata): self.profiling = tr_data['profiling'] self.profiling_file = tr_data['profiling_file'] self.sys_probs = tr_data['sys_probs'] - self.auto_sys_prob_style = tr_data['auto_sys_prob_style'] + self.auto_prob_style = tr_data['auto_prob_style'] self.useBN = False if fitting_type == 'ener' and self.fitting.get_numb_fparam() > 0 : self.numb_fparam = self.fitting.get_numb_fparam() @@ -394,7 +394,7 @@ def train (self, train_time = 0 while cur_batch < stop_batch : batch_data = data.get_batch (sys_probs = self.sys_probs, - auto_prob_style = self.auto_sys_prob_style + auto_prob_style = self.auto_prob_style ) feed_dict_batch = {} for kk in batch_data.keys(): diff --git a/source/train/train.py b/source/train/train.py index 3349115992..65eb4ee3ea 100755 --- a/source/train/train.py +++ b/source/train/train.py @@ -106,6 +106,8 @@ def _do_work(jdata, run_opt): batch_size = j_must_have(jdata['training'], 'batch_size') test_size = j_must_have(jdata['training'], 'numb_test') stop_batch = j_must_have(jdata['training'], 'stop_batch') + sys_probs = jdata['training'].get('sys_probs') + auto_prob_style = jdata['training'].get('auto_prob_style', 'prob_sys_size') if len(type_map) == 0: # empty type_map ipt_type_map = None @@ -129,9 +131,11 @@ def _do_work(jdata, run_opt): test_size, rcut, set_prefix=set_pfx, - run_opt=run_opt, type_map = ipt_type_map, modifier = modifier) + data.print_summary(run_opt, + sys_probs = sys_probs, + auto_prob_style = auto_prob_style) data.add_dict(data_requirement) # build the model with stats from the first system model.build (data, stop_batch) From f04b47b668bfbac906a60962370b6ce8d831a715 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Thu, 6 Feb 2020 14:45:56 -0500 Subject: [PATCH 085/147] set CMAKE_LINK_WHAT_YOU_USE flag (fix #163) Co-authored-by: Linfeng Zhang --- source/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 4af2ee9934..586a0b1472 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.7) project(DeePMD) +set(CMAKE_LINK_WHAT_YOU_USE TRUE) # build cpp or python interfaces if (NOT DEFINED BUILD_CPP_IF) From 9ce5527ee53d7e635a6e8f6ec7fd398fd8aea09d Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Fri, 7 Feb 2020 17:36:36 -0500 Subject: [PATCH 086/147] change the key name; supprot DescrptSeR --- source/train/DescrptSeA.py | 14 +++---- source/train/DescrptSeR.py | 76 ++++++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index f80a3c64b1..fee64e21b6 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -17,7 +17,7 @@ def __init__ (self, jdata): .add('resnet_dt',bool, default = False) \ .add('trainable',bool, default = True) \ .add('seed', int) \ - .add('no_inter_types', list, default = []) \ + .add('exclude_types', list, default = []) \ .add('set_davg_zero', bool, default = False) class_data = args.parse(jdata) self.sel_a = class_data['sel'] @@ -28,12 +28,12 @@ def __init__ (self, jdata): self.filter_resnet_dt = class_data['resnet_dt'] self.seed = class_data['seed'] self.trainable = class_data['trainable'] - no_inter_types = class_data['no_inter_types'] - self.no_inter_types = set() - for tt in no_inter_types: + exclude_types = class_data['exclude_types'] + self.exclude_types = set() + for tt in exclude_types: assert(len(tt) == 2) - self.no_inter_types.add((tt[0], tt[1])) - self.no_inter_types.add((tt[1], tt[0])) + self.exclude_types.add((tt[0], tt[1])) + self.exclude_types.add((tt[1], tt[0])) self.set_davg_zero = class_data['set_davg_zero'] # descrpt config @@ -337,7 +337,7 @@ def _filter(self, # with (natom x nei_type_i) x 4 inputs_reshape = tf.reshape(inputs_i, [-1, 4]) xyz_scatter = tf.reshape(tf.slice(inputs_reshape, [0,0],[-1,1]),[-1,1]) - if (type_input, type_i) not in self.no_inter_types: + if (type_input, type_i) not in self.exclude_types: for ii in range(1, len(outputs_size)): w = tf.get_variable('matrix_'+str(ii)+'_'+str(type_i), [outputs_size[ii - 1], outputs_size[ii]], diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index 7a2d2125e5..4c6e44459c 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -15,7 +15,9 @@ def __init__ (self, jdata): .add('neuron', list, default = [10, 20, 40]) \ .add('resnet_dt',bool, default = False) \ .add('trainable',bool, default = True) \ - .add('seed', int) + .add('seed', int) \ + .add('exclude_types', list, default = []) \ + .add('set_davg_zero', bool, default = False) class_data = args.parse(jdata) self.sel_r = class_data['sel'] self.rcut = class_data['rcut'] @@ -24,6 +26,12 @@ def __init__ (self, jdata): self.filter_resnet_dt = class_data['resnet_dt'] self.seed = class_data['seed'] self.trainable = class_data['trainable'] + self.exclude_types = set() + for tt in exclude_types: + assert(len(tt) == 2) + self.exclude_types.add((tt[0], tt[1])) + self.exclude_types.add((tt[1], tt[0])) + self.set_davg_zero = class_data['set_davg_zero'] # descrpt config self.sel_a = [ 0 for ii in range(len(self.sel_r)) ] @@ -104,7 +112,8 @@ def compute_input_stats (self, all_davg.append(davg) all_dstd.append(dstd) - self.davg = np.array(all_davg) + if not self.set_davg_zero: + self.davg = np.array(all_davg) self.dstd = np.array(all_dstd) @@ -194,7 +203,7 @@ def _pass_filter(self, [ 0, start_index* self.ndescrpt], [-1, natoms[2+type_i]* self.ndescrpt] ) inputs_i = tf.reshape(inputs_i, [-1, self.ndescrpt]) - layer = self._filter_r(inputs_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable) + layer = self._filter_r(inputs_i, type_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable) layer = tf.reshape(layer, [tf.shape(inputs)[0], natoms[2+type_i] * self.get_dim_out()]) output.append(layer) start_index += natoms[2+type_i] @@ -248,6 +257,7 @@ def _compute_std (self,sumv2, sumv, sumn) : def _filter_r(self, inputs, + type_input, natoms, activation_fn=tf.nn.tanh, stddev=1.0, @@ -271,35 +281,39 @@ def _filter_r(self, shape_i = inputs_i.get_shape().as_list() # with (natom x nei_type_i) x 1 xyz_scatter = tf.reshape(inputs_i, [-1, 1]) - for ii in range(1, len(outputs_size)): - w = tf.get_variable('matrix_'+str(ii)+'_'+str(type_i), - [outputs_size[ii - 1], outputs_size[ii]], - global_tf_float_precision, - tf.random_normal_initializer(stddev=stddev/np.sqrt(outputs_size[ii]+outputs_size[ii-1]), seed = seed), - trainable = trainable) - b = tf.get_variable('bias_'+str(ii)+'_'+str(type_i), - [1, outputs_size[ii]], - global_tf_float_precision, - tf.random_normal_initializer(stddev=stddev, mean = bavg, seed = seed), - trainable = trainable) - if self.filter_resnet_dt : - idt = tf.get_variable('idt_'+str(ii)+'_'+str(type_i), - [1, outputs_size[ii]], - global_tf_float_precision, - tf.random_normal_initializer(stddev=0.001, mean = 1.0, seed = seed), - trainable = trainable) - if outputs_size[ii] == outputs_size[ii-1]: + if (type_input, type_i) not in self.exclude_types: + for ii in range(1, len(outputs_size)): + w = tf.get_variable('matrix_'+str(ii)+'_'+str(type_i), + [outputs_size[ii - 1], outputs_size[ii]], + global_tf_float_precision, + tf.random_normal_initializer(stddev=stddev/np.sqrt(outputs_size[ii]+outputs_size[ii-1]), seed = seed), + trainable = trainable) + b = tf.get_variable('bias_'+str(ii)+'_'+str(type_i), + [1, outputs_size[ii]], + global_tf_float_precision, + tf.random_normal_initializer(stddev=stddev, mean = bavg, seed = seed), + trainable = trainable) if self.filter_resnet_dt : - xyz_scatter += activation_fn(tf.matmul(xyz_scatter, w) + b) * idt - else : - xyz_scatter += activation_fn(tf.matmul(xyz_scatter, w) + b) - elif outputs_size[ii] == outputs_size[ii-1] * 2: - if self.filter_resnet_dt : - xyz_scatter = tf.concat([xyz_scatter,xyz_scatter], 1) + activation_fn(tf.matmul(xyz_scatter, w) + b) * idt - else : - xyz_scatter = tf.concat([xyz_scatter,xyz_scatter], 1) + activation_fn(tf.matmul(xyz_scatter, w) + b) - else: - xyz_scatter = activation_fn(tf.matmul(xyz_scatter, w) + b) + idt = tf.get_variable('idt_'+str(ii)+'_'+str(type_i), + [1, outputs_size[ii]], + global_tf_float_precision, + tf.random_normal_initializer(stddev=0.001, mean = 1.0, seed = seed), + trainable = trainable) + if outputs_size[ii] == outputs_size[ii-1]: + if self.filter_resnet_dt : + xyz_scatter += activation_fn(tf.matmul(xyz_scatter, w) + b) * idt + else : + xyz_scatter += activation_fn(tf.matmul(xyz_scatter, w) + b) + elif outputs_size[ii] == outputs_size[ii-1] * 2: + if self.filter_resnet_dt : + xyz_scatter = tf.concat([xyz_scatter,xyz_scatter], 1) + activation_fn(tf.matmul(xyz_scatter, w) + b) * idt + else : + xyz_scatter = tf.concat([xyz_scatter,xyz_scatter], 1) + activation_fn(tf.matmul(xyz_scatter, w) + b) + else: + xyz_scatter = activation_fn(tf.matmul(xyz_scatter, w) + b) + else: + w = tf.zeros((outputs_size[0], outputs_size[-1]), dtype=global_tf_float_precision) + xyz_scatter = tf.matmul(xyz_scatter, w) # natom x nei_type_i x out_size xyz_scatter = tf.reshape(xyz_scatter, (-1, shape_i[1], outputs_size[-1])) xyz_scatter_total.append(xyz_scatter) From 7268d485ec842e541f992868d2bddcf0065e062a Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Fri, 7 Feb 2020 17:40:24 -0500 Subject: [PATCH 087/147] loss_pf do not needs to be divided by atom number --- source/train/Loss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/Loss.py b/source/train/Loss.py index 4b38a3b1ba..d939273f26 100644 --- a/source/train/Loss.py +++ b/source/train/Loss.py @@ -169,7 +169,7 @@ def print_on_training(self, if self.has_v : print_str += prop_fmt % (np.sqrt(error_v_test) / natoms[0], np.sqrt(error_v_train) / natoms[0]) if self.has_pf: - print_str += prop_fmt % (np.sqrt(error_pf_test) / natoms[0], np.sqrt(error_pf_train) / natoms[0]) + print_str += prop_fmt % (np.sqrt(error_pf_test), np.sqrt(error_pf_train)) return print_str From be68d1619d41f002891a83af3a5ad0a4570951b1 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Sat, 8 Feb 2020 07:55:10 -0500 Subject: [PATCH 088/147] miss a line --- source/train/DescrptSeR.py | 1 + 1 file changed, 1 insertion(+) diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index 4c6e44459c..45a521618b 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -26,6 +26,7 @@ def __init__ (self, jdata): self.filter_resnet_dt = class_data['resnet_dt'] self.seed = class_data['seed'] self.trainable = class_data['trainable'] + exclude_types = class_data['exclude_types'] self.exclude_types = set() for tt in exclude_types: assert(len(tt) == 2) From 0f8c6c35f557ea44fe532eb3113e2c2a88cee445 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Wed, 12 Feb 2020 13:40:02 -0500 Subject: [PATCH 089/147] add the missing line for install-tf.1.14.md thanks Manyi Yang, who pointed out the issue --- doc/install-tf.1.14.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/install-tf.1.14.md b/doc/install-tf.1.14.md index bfb5fe6717..b863a50cb6 100644 --- a/doc/install-tf.1.14.md +++ b/doc/install-tf.1.14.md @@ -42,6 +42,7 @@ Now, copy the libraries to the tensorflow's installation directory: mkdir $tensorflow_root/lib cp -d bazel-bin/tensorflow/libtensorflow_cc.so* $tensorflow_root/lib/ cp -d bazel-bin/tensorflow/libtensorflow_framework.so* $tensorflow_root/lib/ +cp -d $tensorflow_root/lib/libtensorflow_framework.so.1 $tensorflow_root/lib/libtensorflow_framework.so ``` Then copy the headers ```bash From 741d0a97bd65f9a9670f368a842762c7a89d229a Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Thu, 13 Feb 2020 23:45:52 +0800 Subject: [PATCH 090/147] Update common.py --- source/train/common.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/train/common.py b/source/train/common.py index 5534fca20c..dd6a1aa298 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -1,8 +1,9 @@ import warnings import numpy as np +from deepmd.env import tf data_requirement = {} - +activation_fn_dict = {'tf.nn.relu':tf.nn.relu,'tf.nn.relu6':tf.nn.relu6,"tf.nn.softplus":tf.nn.softplus,"tf.sigmoid":tf.sigmoid,"tf.tanh":tf.tanh,"tf.nn.tanh":tf.nn.tanh} def add_data_requirement(key, ndof, atomic = False, @@ -139,4 +140,9 @@ def j_must_have_d (jdata, key, deprecated_key) : def j_have (jdata, key) : return key in jdata.keys() + +def j_whether_in_dict(activation_fn): + if activation_fn not in activation_fn_dict: + raise RuntimeError(activation_fn+" is not a valid activation function") + return activation_fn_dict[activation_fn] From 2863799a4e6d6eed7195daacd3f59403f95f711b Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Thu, 13 Feb 2020 23:49:02 +0800 Subject: [PATCH 091/147] Update DescrptSeA.py --- source/train/DescrptSeA.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index fee64e21b6..0851e55ddf 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -1,6 +1,6 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg +from deepmd.common import ClassArg, j_whether_in_dict from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module @@ -18,7 +18,8 @@ def __init__ (self, jdata): .add('trainable',bool, default = True) \ .add('seed', int) \ .add('exclude_types', list, default = []) \ - .add('set_davg_zero', bool, default = False) + .add('set_davg_zero', bool, default = False) \ + .add('activation_function', str, default = 'tf.nn.tanh') class_data = args.parse(jdata) self.sel_a = class_data['sel'] self.rcut_r = class_data['rcut'] @@ -28,6 +29,7 @@ def __init__ (self, jdata): self.filter_resnet_dt = class_data['resnet_dt'] self.seed = class_data['seed'] self.trainable = class_data['trainable'] + self.filter_activation_fn = j_whether_in_dict(class_data['activation_function']) exclude_types = class_data['exclude_types'] self.exclude_types = set() for tt in exclude_types: @@ -319,6 +321,7 @@ def _filter(self, reuse=None, seed=None, trainable = True): + activation_fn = self.filter_activation_fn # natom x (nei x 4) shape = inputs.get_shape().as_list() outputs_size = [1] + self.filter_neuron @@ -406,6 +409,7 @@ def _filter_type_ext(self, reuse=None, seed=None, trainable = True): + activation_fn = self.filter.activation_fn # natom x (nei x 4) outputs_size = [1] + self.filter_neuron outputs_size_2 = self.n_axis_neuron From 2aeaaa7699b73826efa8ab8ac57f48699ee57197 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Thu, 13 Feb 2020 23:50:57 +0800 Subject: [PATCH 092/147] Update DescrptSeR.py --- source/train/DescrptSeR.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index 45a521618b..bd9abe01df 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -1,6 +1,6 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg +from deepmd.common import ClassArg, j_whether_in_dict from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module @@ -17,7 +17,8 @@ def __init__ (self, jdata): .add('trainable',bool, default = True) \ .add('seed', int) \ .add('exclude_types', list, default = []) \ - .add('set_davg_zero', bool, default = False) + .add('set_davg_zero', bool, default = False) \ + .add("activation_function", str, default = "tf.nn.tanh") class_data = args.parse(jdata) self.sel_r = class_data['sel'] self.rcut = class_data['rcut'] @@ -26,6 +27,7 @@ def __init__ (self, jdata): self.filter_resnet_dt = class_data['resnet_dt'] self.seed = class_data['seed'] self.trainable = class_data['trainable'] + self.filter_activation_fn = j_whether_in_dict(class_data["activation_function"]) exclude_types = class_data['exclude_types'] self.exclude_types = set() for tt in exclude_types: @@ -267,6 +269,7 @@ def _filter_r(self, reuse=None, seed=None, trainable = True): + activation_fn = self.filter_activation_fn # natom x nei outputs_size = [1] + self.filter_neuron with tf.variable_scope(name, reuse=reuse): From 61a1950acb436cf6a79b68284f59b611822fa854 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Thu, 13 Feb 2020 23:59:04 +0800 Subject: [PATCH 093/147] Update Fitting.py --- source/train/Fitting.py | 42 +++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 5532777257..370d6b17b5 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -2,7 +2,7 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, add_data_requirement +from deepmd.common import ClassArg, add_data_requirement, j_whether_in_dict from deepmd.Network import one_layer from deepmd.DescrptLocFrame import DescrptLocFrame from deepmd.DescrptSeA import DescrptSeA @@ -21,7 +21,8 @@ def __init__ (self, jdata, descrpt): .add('resnet_dt', bool, default = True)\ .add('rcond', float, default = 1e-3) \ .add('seed', int) \ - .add('atom_ener', list, default = []) + .add('atom_ener', list, default = [])\ + .add("activation_function", str, default = "tf.nn.tanh") class_data = args.parse(jdata) self.numb_fparam = class_data['numb_fparam'] self.numb_aparam = class_data['numb_aparam'] @@ -29,6 +30,7 @@ def __init__ (self, jdata, descrpt): self.resnet_dt = class_data['resnet_dt'] self.rcond = class_data['rcond'] self.seed = class_data['seed'] + self.fitting_activation_fn = j_whether_in_dict(class_data["activation_function"]) self.atom_ener = [] for at, ae in enumerate(class_data['atom_ener']): if ae is not None: @@ -201,10 +203,10 @@ def build (self, for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn) else : layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) - final_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + final_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn) if type_i < len(self.atom_ener) and self.atom_ener[type_i] is not None: inputs_zero = tf.zeros_like(inputs_i, dtype=global_tf_float_precision) @@ -243,13 +245,15 @@ def __init__ (self, jdata, descrpt) : .add('resnet_dt', bool, default = True)\ .add('wfc_numb', int, must = True)\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'wfc_type')\ - .add('seed', int) + .add('seed', int)\ + .add("activation_function", str, defalut = "tf.nn.tanh") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] self.wfc_numb = class_data['wfc_numb'] self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] + self.fitting_activation_fn = j_whether_in_dict(class_data["activation_function"]) self.useBN = False @@ -289,9 +293,9 @@ def build (self, layer = inputs_i for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn) # (nframes x natoms) x (nwfc x 3) final_layer = one_layer(layer, self.wfc_numb * 3, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) # (nframes x natoms) x nwfc(wc) x 3(coord_local) @@ -322,12 +326,14 @@ def __init__ (self, jdata, descrpt) : .add('neuron', list, default = [120,120,120], alias = 'n_neuron')\ .add('resnet_dt', bool, default = True)\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'pol_type')\ - .add('seed', int) + .add('seed', int)\ + .add("activation_function", str, default = "tf.nn.tanh") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] + self.fitting_activation_fn = j_whether_in_dict(class_data["activation_function"]) self.useBN = False def get_sel_type(self): @@ -363,9 +369,9 @@ def build (self, layer = inputs_i for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn) # (nframes x natoms) x 9 final_layer = one_layer(layer, 9, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) # (nframes x natoms) x 3 x 3 @@ -402,7 +408,8 @@ def __init__ (self, jdata, descrpt) : .add('diag_shift', [list,float], default = [0.0 for ii in range(self.ntypes)])\ .add('scale', [list,float], default = [1.0 for ii in range(self.ntypes)])\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'pol_type')\ - .add('seed', int) + .add('seed', int)\ + .add("activation_function", str , default = "tf.nn.tanh") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] @@ -411,6 +418,7 @@ def __init__ (self, jdata, descrpt) : self.seed = class_data['seed'] self.diag_shift = class_data['diag_shift'] self.scale = class_data['scale'] + self.fitting_activation_fn = j_whether_in_dict(class_data["activation_function"]) if type(self.sel_type) is not list: self.sel_type = [self.sel_type] if type(self.diag_shift) is not list: @@ -471,9 +479,9 @@ def build (self, layer = inputs_i for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn) if self.fit_diag : bavg = np.zeros(self.dim_rot_mat_1) # bavg[0] = self.avgeig[0] @@ -555,12 +563,14 @@ def __init__ (self, jdata, descrpt) : .add('neuron', list, default = [120,120,120], alias = 'n_neuron')\ .add('resnet_dt', bool, default = True)\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'dipole_type')\ - .add('seed', int) + .add('seed', int)\ + .add("activation_function", str, default = "tf.nn.tanh") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] + self.fitting_activation_fn = j_whether_in_dict(class_data["activation_function"]) self.dim_rot_mat_1 = descrpt.get_dim_rot_mat_1() self.dim_rot_mat = self.dim_rot_mat_1 * 3 self.useBN = False @@ -598,9 +608,9 @@ def build (self, layer = inputs_i for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn) # (nframes x natoms) x naxis final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) # (nframes x natoms) x 1 * naxis From c26c30b0f2ad202d0ece3f64d15f76b590e12cee Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Fri, 14 Feb 2020 01:09:27 +0800 Subject: [PATCH 094/147] Update Fitting.py --- source/train/Fitting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 370d6b17b5..1ea4df5897 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -206,7 +206,7 @@ def build (self, layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn) else : layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) - final_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn) + final_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) if type_i < len(self.atom_ener) and self.atom_ener[type_i] is not None: inputs_zero = tf.zeros_like(inputs_i, dtype=global_tf_float_precision) From ba3349aa5283d0abf178b94b148f0a71820283d5 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Fri, 14 Feb 2020 01:24:46 +0800 Subject: [PATCH 095/147] Update Fitting.py --- source/train/Fitting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 1ea4df5897..f67af4d5be 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -246,7 +246,7 @@ def __init__ (self, jdata, descrpt) : .add('wfc_numb', int, must = True)\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'wfc_type')\ .add('seed', int)\ - .add("activation_function", str, defalut = "tf.nn.tanh") + .add("activation_function", str, default = "tf.nn.tanh") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] From e1bf0d083e7b6a22b0e8310453f4537af5f69864 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Fri, 14 Feb 2020 23:23:36 +0800 Subject: [PATCH 096/147] Update common.py --- source/train/common.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/train/common.py b/source/train/common.py index dd6a1aa298..cda32435c2 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -3,7 +3,13 @@ from deepmd.env import tf data_requirement = {} -activation_fn_dict = {'tf.nn.relu':tf.nn.relu,'tf.nn.relu6':tf.nn.relu6,"tf.nn.softplus":tf.nn.softplus,"tf.sigmoid":tf.sigmoid,"tf.tanh":tf.tanh,"tf.nn.tanh":tf.nn.tanh} +activation_fn_dict = { + "relu": tf.nn.relu, + "relu6": tf.nn.relu6, + "softplus": tf.nn.softplus, + "sigmoid": tf.sigmoid, + "tanh": tf.nn.tanh +} def add_data_requirement(key, ndof, atomic = False, From ab8118fc84ea6317384eeb812d527a3e9f3555c6 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Fri, 14 Feb 2020 23:33:13 +0800 Subject: [PATCH 097/147] Update DescrptSeA.py --- source/train/DescrptSeA.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 0851e55ddf..f3aae714ff 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -19,7 +19,7 @@ def __init__ (self, jdata): .add('seed', int) \ .add('exclude_types', list, default = []) \ .add('set_davg_zero', bool, default = False) \ - .add('activation_function', str, default = 'tf.nn.tanh') + .add('activation_function', str, default = 'tanh') class_data = args.parse(jdata) self.sel_a = class_data['sel'] self.rcut_r = class_data['rcut'] From a53cb5226c2e73ef05fd12073a1616b9f5f0b940 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Fri, 14 Feb 2020 23:33:45 +0800 Subject: [PATCH 098/147] Update DescrptSeR.py --- source/train/DescrptSeR.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index bd9abe01df..b967d38c13 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -18,7 +18,7 @@ def __init__ (self, jdata): .add('seed', int) \ .add('exclude_types', list, default = []) \ .add('set_davg_zero', bool, default = False) \ - .add("activation_function", str, default = "tf.nn.tanh") + .add("activation_function", str, default = "tanh") class_data = args.parse(jdata) self.sel_r = class_data['sel'] self.rcut = class_data['rcut'] From ff5e25d9f377bcd610cc2c76292b072cede7b312 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Fri, 14 Feb 2020 23:35:58 +0800 Subject: [PATCH 099/147] Update Fitting.py --- source/train/Fitting.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index f67af4d5be..24d64ea05a 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -22,7 +22,7 @@ def __init__ (self, jdata, descrpt): .add('rcond', float, default = 1e-3) \ .add('seed', int) \ .add('atom_ener', list, default = [])\ - .add("activation_function", str, default = "tf.nn.tanh") + .add("activation_function", str, default = "tanh") class_data = args.parse(jdata) self.numb_fparam = class_data['numb_fparam'] self.numb_aparam = class_data['numb_aparam'] @@ -246,7 +246,7 @@ def __init__ (self, jdata, descrpt) : .add('wfc_numb', int, must = True)\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'wfc_type')\ .add('seed', int)\ - .add("activation_function", str, default = "tf.nn.tanh") + .add("activation_function", str, default = "tanh") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] @@ -327,7 +327,7 @@ def __init__ (self, jdata, descrpt) : .add('resnet_dt', bool, default = True)\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'pol_type')\ .add('seed', int)\ - .add("activation_function", str, default = "tf.nn.tanh") + .add("activation_function", str, default = "tanh") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] @@ -409,7 +409,7 @@ def __init__ (self, jdata, descrpt) : .add('scale', [list,float], default = [1.0 for ii in range(self.ntypes)])\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'pol_type')\ .add('seed', int)\ - .add("activation_function", str , default = "tf.nn.tanh") + .add("activation_function", str , default = "tanh") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] @@ -564,7 +564,7 @@ def __init__ (self, jdata, descrpt) : .add('resnet_dt', bool, default = True)\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'dipole_type')\ .add('seed', int)\ - .add("activation_function", str, default = "tf.nn.tanh") + .add("activation_function", str, default = "tanh") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] From 7c91ec15f67e92da8918b1c9bf017d87a781f305 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sat, 15 Feb 2020 00:01:03 +0800 Subject: [PATCH 100/147] Update common.py --- source/train/common.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/train/common.py b/source/train/common.py index cda32435c2..3c3a664dcf 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -8,7 +8,8 @@ "relu6": tf.nn.relu6, "softplus": tf.nn.softplus, "sigmoid": tf.sigmoid, - "tanh": tf.nn.tanh + "tanh": tf.nn.tanh, + "tf.nn.tanh": tf.nn.tanh } def add_data_requirement(key, ndof, From dab2927caec0c0187d0191c93210fd642c618bf9 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 16 Feb 2020 12:29:41 +0800 Subject: [PATCH 101/147] Update DescrptSeA.py --- source/train/DescrptSeA.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index f3aae714ff..2705d4b9a8 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -247,7 +247,7 @@ def _pass_filter(self, [ 0, start_index* self.ndescrpt], [-1, natoms[2+type_i]* self.ndescrpt] ) inputs_i = tf.reshape(inputs_i, [-1, self.ndescrpt]) - layer, qmat = self._filter(inputs_i, type_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable) + layer, qmat = self._filter(inputs_i, type_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable, activation_fn = self.filter_activation_fn) layer = tf.reshape(layer, [tf.shape(inputs)[0], natoms[2+type_i] * self.get_dim_out()]) qmat = tf.reshape(qmat, [tf.shape(inputs)[0], natoms[2+type_i] * self.get_dim_rot_mat_1() * 3]) output.append(layer) @@ -321,7 +321,6 @@ def _filter(self, reuse=None, seed=None, trainable = True): - activation_fn = self.filter_activation_fn # natom x (nei x 4) shape = inputs.get_shape().as_list() outputs_size = [1] + self.filter_neuron @@ -409,7 +408,6 @@ def _filter_type_ext(self, reuse=None, seed=None, trainable = True): - activation_fn = self.filter.activation_fn # natom x (nei x 4) outputs_size = [1] + self.filter_neuron outputs_size_2 = self.n_axis_neuron From afd422ee278c39d8347c5b18bfa268c2f547e00a Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 16 Feb 2020 12:31:09 +0800 Subject: [PATCH 102/147] Update DescrptSeR.py --- source/train/DescrptSeR.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index b967d38c13..df03d472b8 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -206,7 +206,7 @@ def _pass_filter(self, [ 0, start_index* self.ndescrpt], [-1, natoms[2+type_i]* self.ndescrpt] ) inputs_i = tf.reshape(inputs_i, [-1, self.ndescrpt]) - layer = self._filter_r(inputs_i, type_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable) + layer = self._filter_r(inputs_i, type_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable, activation_fn = self.filter_activation_fn) layer = tf.reshape(layer, [tf.shape(inputs)[0], natoms[2+type_i] * self.get_dim_out()]) output.append(layer) start_index += natoms[2+type_i] @@ -269,7 +269,6 @@ def _filter_r(self, reuse=None, seed=None, trainable = True): - activation_fn = self.filter_activation_fn # natom x nei outputs_size = [1] + self.filter_neuron with tf.variable_scope(name, reuse=reuse): From d49895de6f70cb1c9d72e28ffb6523a6459b3a4c Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 16 Feb 2020 13:23:00 +0800 Subject: [PATCH 103/147] Update common.py --- source/train/common.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/train/common.py b/source/train/common.py index 3c3a664dcf..c976deffa2 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -8,8 +8,7 @@ "relu6": tf.nn.relu6, "softplus": tf.nn.softplus, "sigmoid": tf.sigmoid, - "tanh": tf.nn.tanh, - "tf.nn.tanh": tf.nn.tanh + "tanh": tf.nn.tanh } def add_data_requirement(key, ndof, @@ -153,3 +152,8 @@ def j_whether_in_dict(activation_fn): raise RuntimeError(activation_fn+" is not a valid activation function") return activation_fn_dict[activation_fn] +def get_activation_func(activation_fn): + if activation_fn not in activation_fn_dict: + raise RuntimeError(activation_fn+" is not a valid activation function") + return activation_fn_dict[activation_fn] + From df22289d7ea929b0da35cf3f5a09567962e42b30 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 16 Feb 2020 13:59:11 +0800 Subject: [PATCH 104/147] Update Fitting.py --- source/train/Fitting.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 24d64ea05a..497ee67ef5 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -2,7 +2,7 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, add_data_requirement, j_whether_in_dict +from deepmd.common import ClassArg, add_data_requirement, get_activation_func from deepmd.Network import one_layer from deepmd.DescrptLocFrame import DescrptLocFrame from deepmd.DescrptSeA import DescrptSeA @@ -30,7 +30,7 @@ def __init__ (self, jdata, descrpt): self.resnet_dt = class_data['resnet_dt'] self.rcond = class_data['rcond'] self.seed = class_data['seed'] - self.fitting_activation_fn = j_whether_in_dict(class_data["activation_function"]) + self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) self.atom_ener = [] for at, ae in enumerate(class_data['atom_ener']): if ae is not None: @@ -253,7 +253,7 @@ def __init__ (self, jdata, descrpt) : self.wfc_numb = class_data['wfc_numb'] self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] - self.fitting_activation_fn = j_whether_in_dict(class_data["activation_function"]) + self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) self.useBN = False @@ -333,7 +333,7 @@ def __init__ (self, jdata, descrpt) : self.resnet_dt = class_data['resnet_dt'] self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] - self.fitting_activation_fn = j_whether_in_dict(class_data["activation_function"]) + self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) self.useBN = False def get_sel_type(self): @@ -418,7 +418,7 @@ def __init__ (self, jdata, descrpt) : self.seed = class_data['seed'] self.diag_shift = class_data['diag_shift'] self.scale = class_data['scale'] - self.fitting_activation_fn = j_whether_in_dict(class_data["activation_function"]) + self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) if type(self.sel_type) is not list: self.sel_type = [self.sel_type] if type(self.diag_shift) is not list: @@ -570,7 +570,7 @@ def __init__ (self, jdata, descrpt) : self.resnet_dt = class_data['resnet_dt'] self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] - self.fitting_activation_fn = j_whether_in_dict(class_data["activation_function"]) + self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) self.dim_rot_mat_1 = descrpt.get_dim_rot_mat_1() self.dim_rot_mat = self.dim_rot_mat_1 * 3 self.useBN = False From 272953079f400bf4105f83f0c127d2c2c9171ea9 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 16 Feb 2020 14:00:50 +0800 Subject: [PATCH 105/147] Update DescrptSeA.py --- source/train/DescrptSeA.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 2705d4b9a8..33b0aa3fb1 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -1,6 +1,6 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, j_whether_in_dict +from deepmd.common import ClassArg, get_activation_func from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module @@ -29,7 +29,7 @@ def __init__ (self, jdata): self.filter_resnet_dt = class_data['resnet_dt'] self.seed = class_data['seed'] self.trainable = class_data['trainable'] - self.filter_activation_fn = j_whether_in_dict(class_data['activation_function']) + self.filter_activation_fn = get_activation_func(class_data['activation_function']) exclude_types = class_data['exclude_types'] self.exclude_types = set() for tt in exclude_types: From 15ca413459ea362d3218a66bfde90017d23b26d3 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 16 Feb 2020 14:01:23 +0800 Subject: [PATCH 106/147] Update DescrptSeR.py --- source/train/DescrptSeR.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index df03d472b8..1acdfc9b63 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -1,6 +1,6 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, j_whether_in_dict +from deepmd.common import ClassArg, get_activation_func from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module @@ -27,7 +27,7 @@ def __init__ (self, jdata): self.filter_resnet_dt = class_data['resnet_dt'] self.seed = class_data['seed'] self.trainable = class_data['trainable'] - self.filter_activation_fn = j_whether_in_dict(class_data["activation_function"]) + self.filter_activation_fn = get_activation_func(class_data["activation_function"]) exclude_types = class_data['exclude_types'] self.exclude_types = set() for tt in exclude_types: From dbe4e9710cc6c08f586e4477ede0840ab88200bc Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 16 Feb 2020 14:31:43 +0800 Subject: [PATCH 107/147] Update common.py --- source/train/common.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source/train/common.py b/source/train/common.py index c976deffa2..b80fdfb0dc 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -147,11 +147,6 @@ def j_must_have_d (jdata, key, deprecated_key) : def j_have (jdata, key) : return key in jdata.keys() -def j_whether_in_dict(activation_fn): - if activation_fn not in activation_fn_dict: - raise RuntimeError(activation_fn+" is not a valid activation function") - return activation_fn_dict[activation_fn] - def get_activation_func(activation_fn): if activation_fn not in activation_fn_dict: raise RuntimeError(activation_fn+" is not a valid activation function") From 850ffce8aae398a7994fbc286d9a8c9abfbd792e Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 17 Feb 2020 20:02:59 +0800 Subject: [PATCH 108/147] following the symlinks to find system dirs --- source/train/common.py | 8 +++++++- source/train/test.py | 6 ++---- source/train/train.py | 9 +-------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/source/train/common.py b/source/train/common.py index b80fdfb0dc..c36534afe7 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -1,4 +1,4 @@ -import warnings +import os,warnings,fnmatch import numpy as np from deepmd.env import tf @@ -152,3 +152,9 @@ def get_activation_func(activation_fn): raise RuntimeError(activation_fn+" is not a valid activation function") return activation_fn_dict[activation_fn] +def expand_sys_str(root_dir): + matches = [] + for root, dirnames, filenames in os.walk(root_dir, followlinks=True): + for filename in fnmatch.filter(filenames, 'type.raw'): + matches.append(root) + return matches diff --git a/source/train/test.py b/source/train/test.py index 6269947758..c5d1302ff4 100644 --- a/source/train/test.py +++ b/source/train/test.py @@ -7,6 +7,7 @@ import numpy as np from deepmd.Data import DeepmdData +from deepmd.common import expand_sys_str from deepmd import DeepEval from deepmd import DeepPot from deepmd import DeepDipole @@ -16,10 +17,7 @@ def test (args): de = DeepEval(args.model) - all_sys = [] - from pathlib import Path - for filename in Path(args.system).rglob('type.raw'): - all_sys.append(os.path.dirname(filename)) + all_sys = expand_sys_str(args.system) for ii in all_sys: args.system = ii print ("# ---------------output of dp test--------------- ") diff --git a/source/train/train.py b/source/train/train.py index 65eb4ee3ea..c89760fa4d 100755 --- a/source/train/train.py +++ b/source/train/train.py @@ -10,7 +10,7 @@ from deepmd.RunOptions import RunOptions from deepmd.DataSystem import DeepmdDataSystem from deepmd.Trainer import NNPTrainer -from deepmd.common import data_requirement +from deepmd.common import data_requirement, expand_sys_str from deepmd.DataModifier import DipoleChargeModifier def create_done_queue(cluster_spec, task_index): @@ -80,13 +80,6 @@ def train (args) : # serial training _do_work(jdata, run_opt) -def expand_sys_str(root_dir): - all_sys = [] - from pathlib import Path - for filename in Path(root_dir).rglob('type.raw'): - all_sys.append(os.path.dirname(filename)) - return all_sys - def _do_work(jdata, run_opt): # init the model model = NNPTrainer (jdata, run_opt = run_opt) From 12fdcf4dcb2d651a8c359b382175599837a308fa Mon Sep 17 00:00:00 2001 From: Han Wang Date: Tue, 18 Feb 2020 18:22:40 +0800 Subject: [PATCH 109/147] compute averaged testing error for many systems --- source/train/test.py | 66 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/source/train/test.py b/source/train/test.py index c5d1302ff4..18c84ea29b 100644 --- a/source/train/test.py +++ b/source/train/test.py @@ -18,18 +18,37 @@ def test (args): de = DeepEval(args.model) all_sys = expand_sys_str(args.system) + err_coll = [] + siz_coll = [] for ii in all_sys: args.system = ii print ("# ---------------output of dp test--------------- ") print ("# testing system : " + ii) if de.model_type == 'ener': - test_ener(args) + err, siz = test_ener(args) elif de.model_type == 'dipole': - test_dipole(args) + err, siz = test_dipole(args) elif de.model_type == 'polar': - test_polar(args) + err, siz = test_polar(args) elif de.model_type == 'wfc': - test_wfc(args) + err, siz = test_wfc(args) + else : + raise RuntimeError('unknow model type '+de.model_type) + print ("# ----------------------------------------------- ") + err_coll.append(err) + siz_coll.append(siz) + avg_err = weighted_average(err_coll, siz_coll) + if len(all_sys) > 1: + print ("# ----------weighted average of errors----------- ") + print ("# number of systems : %d" % len(all_sys)) + if de.model_type == 'ener': + print_ener_sys_avg(avg_err) + elif de.model_type == 'dipole': + print_dipole_sys_avg(avg_err) + elif de.model_type == 'polar': + print_polar_sys_avg(avg_err) + elif de.model_type == 'wfc': + print_wfc_sys_avg(avg_err) else : raise RuntimeError('unknow model type '+de.model_type) print ("# ----------------------------------------------- ") @@ -39,6 +58,23 @@ def l2err (diff) : return np.sqrt(np.average (diff*diff)) +def weighted_average(err_coll, siz_coll): + nsys = len(err_coll) + nitems = len(err_coll[0]) + assert(len(err_coll) == len(siz_coll)) + sum_err = np.zeros(nitems) + sum_siz = np.zeros(nitems) + for sys_error, sys_size in zip(err_coll, siz_coll): + for ii in range(nitems): + ee = sys_error[ii] + ss = sys_size [ii] + sum_err[ii] += ee * ee * ss + sum_siz[ii] += ss + for ii in range(nitems): + sum_err[ii] = np.sqrt(sum_err[ii] / sum_siz[ii]) + return sum_err + + def test_ener (args) : if args.rand_seed is not None : np.random.seed(args.rand_seed % (2**32)) @@ -121,6 +157,13 @@ def test_ener (args) : axis = 1) np.savetxt(detail_file+".v.out", pv, header = 'data_vxx data_vxy data_vxz data_vyx data_vyy data_vyz data_vzx data_vzy data_vzz pred_vxx pred_vxy pred_vxz pred_vyx pred_vyy pred_vyz pred_vzx pred_vzy pred_vzz') + return [l2ea, l2f, l2va], [energy.size, force.size, virial.size] + + +def print_ener_sys_avg(avg): + print ("Energy L2err/Natoms : %e eV" % avg[0]) + print ("Force L2err : %e eV/A" % avg[1]) + print ("Virial L2err/Natoms : %e eV" % avg[2]) def test_wfc (args) : @@ -154,6 +197,11 @@ def test_wfc (args) : axis = 1) np.savetxt(detail_file+".out", pe, header = 'ref_wfc(12 dofs) predicted_wfc(12 dofs)') + return [l2f], [wfc.size] + + +def print_wfc_sys_avg(avg): + print ("WFC L2err : %e eV/A" % avg[0]) def test_polar (args) : @@ -187,6 +235,11 @@ def test_polar (args) : axis = 1) np.savetxt(detail_file+".out", pe, header = 'data_pxx data_pxy data_pxz data_pyx data_pyy data_pyz data_pzx data_pzy data_pzz pred_pxx pred_pxy pred_pxz pred_pyx pred_pyy pred_pyz pred_pzx pred_pzy pred_pzz') + return [l2f], [polar.size] + + +def print_polar_sys_avg(avg): + print ("Polarizability L2err : %e eV/A" % avg[0]) def test_dipole (args) : @@ -220,3 +273,8 @@ def test_dipole (args) : axis = 1) np.savetxt(detail_file+".out", pe, header = 'data_x data_y data_z pred_x pred_y pred_z') + return [l2f], [dipole.size] + + +def print_dipole_sys_avg(avg): + print ("Dipole L2err : %e eV/A" % avg[0]) From 6a1b1fbcbc710121e2a3e1405a52f536996420d0 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Wed, 19 Feb 2020 17:25:26 +0800 Subject: [PATCH 110/147] Update common.py --- source/train/common.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/source/train/common.py b/source/train/common.py index c36534afe7..4e034d7ca7 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -1,14 +1,28 @@ import os,warnings,fnmatch import numpy as np +import math from deepmd.env import tf +def gelu(x): + """Gaussian Error Linear Unit. + This is a smoother version of the RELU. + Original paper: https://arxiv.org/abs/1606.08415 + Args: + x: float Tensor to perform activation. + Returns: + `x` with the GELU activation applied. + """ + cdf = 0.5 * (1.0 + tf.tanh((math.sqrt(2 / math.pi) * (x + 0.044715 * tf.pow(x, 3))))) + return x * cdf + data_requirement = {} activation_fn_dict = { "relu": tf.nn.relu, "relu6": tf.nn.relu6, "softplus": tf.nn.softplus, "sigmoid": tf.sigmoid, - "tanh": tf.nn.tanh + "tanh": tf.nn.tanh, + "gelu": gelu } def add_data_requirement(key, ndof, From dd1bf21e1a381e5d30cfa47ce5149aad6ebb1806 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 20 Feb 2020 11:13:29 +0800 Subject: [PATCH 111/147] solve the efficiency problem when testing multiple systems --- source/train/test.py | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/source/train/test.py b/source/train/test.py index 18c84ea29b..2674e9c01e 100644 --- a/source/train/test.py +++ b/source/train/test.py @@ -18,26 +18,40 @@ def test (args): de = DeepEval(args.model) all_sys = expand_sys_str(args.system) + if len(all_sys) == 0: + print('Did not find valid system') err_coll = [] siz_coll = [] + if de.model_type == 'ener': + dp = DeepPot(args.model) + elif de.model_type == 'dipole': + dp = DeepDipole(args.model) + elif de.model_type == 'polar': + dp = DeepPolar(args.model) + elif de.model_type == 'wfc': + dp = DeepWFC(args.model) + else : + raise RuntimeError('unknow model type '+de.model_type) for ii in all_sys: args.system = ii print ("# ---------------output of dp test--------------- ") print ("# testing system : " + ii) if de.model_type == 'ener': - err, siz = test_ener(args) + err, siz = test_ener(dp, args) elif de.model_type == 'dipole': - err, siz = test_dipole(args) + err, siz = test_dipole(dp, args) elif de.model_type == 'polar': - err, siz = test_polar(args) + err, siz = test_polar(dp, args) elif de.model_type == 'wfc': - err, siz = test_wfc(args) + err, siz = test_wfc(dp, args) else : raise RuntimeError('unknow model type '+de.model_type) print ("# ----------------------------------------------- ") err_coll.append(err) siz_coll.append(siz) avg_err = weighted_average(err_coll, siz_coll) + if len(all_sys) != len(err): + print('Not all systems are tested! Check if the systems are valid') if len(all_sys) > 1: print ("# ----------weighted average of errors----------- ") print ("# number of systems : %d" % len(all_sys)) @@ -75,11 +89,10 @@ def weighted_average(err_coll, siz_coll): return sum_err -def test_ener (args) : +def test_ener (dp, args) : if args.rand_seed is not None : np.random.seed(args.rand_seed % (2**32)) - dp = DeepPot(args.model) data = DeepmdData(args.system, args.set_prefix, shuffle_test = args.shuffle_test, type_map = dp.get_type_map()) data.add('energy', 1, atomic=False, must=False, high_prec=True) data.add('force', 3, atomic=True, must=False, high_prec=False) @@ -166,11 +179,10 @@ def print_ener_sys_avg(avg): print ("Virial L2err/Natoms : %e eV" % avg[2]) -def test_wfc (args) : +def test_wfc (dp, args) : if args.rand_seed is not None : np.random.seed(args.rand_seed % (2**32)) - dp = DeepWFC(args.model) data = DeepmdData(args.system, args.set_prefix, shuffle_test = args.shuffle_test) data.add('wfc', 12, atomic=True, must=True, high_prec=False, type_sel = dp.get_sel_type()) test_data = data.get_test () @@ -204,11 +216,10 @@ def print_wfc_sys_avg(avg): print ("WFC L2err : %e eV/A" % avg[0]) -def test_polar (args) : +def test_polar (dp, args) : if args.rand_seed is not None : np.random.seed(args.rand_seed % (2**32)) - dp = DeepPolar(args.model) data = DeepmdData(args.system, args.set_prefix, shuffle_test = args.shuffle_test) data.add('polarizability', 9, atomic=True, must=True, high_prec=False, type_sel = dp.get_sel_type()) test_data = data.get_test () @@ -242,11 +253,10 @@ def print_polar_sys_avg(avg): print ("Polarizability L2err : %e eV/A" % avg[0]) -def test_dipole (args) : +def test_dipole (dp, args) : if args.rand_seed is not None : np.random.seed(args.rand_seed % (2**32)) - dp = DeepDipole(args.model) data = DeepmdData(args.system, args.set_prefix, shuffle_test = args.shuffle_test) data.add('dipole', 3, atomic=True, must=True, high_prec=False, type_sel = dp.get_sel_type()) test_data = data.get_test () From c09cdcb25e5b144c736da83d1b796828623f495f Mon Sep 17 00:00:00 2001 From: haidi Date: Fri, 21 Feb 2020 19:10:23 +0800 Subject: [PATCH 112/147] update calculator type_dict --- source/train/calculator.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/train/calculator.py b/source/train/calculator.py index 1179eef891..02f2c77a09 100644 --- a/source/train/calculator.py +++ b/source/train/calculator.py @@ -35,7 +35,10 @@ class DP(Calculator): def __init__(self, model, label="DP", **kwargs): Calculator.__init__(self, label=label, **kwargs) self.dp = DeepPot(model) - self.type_dict = dict(zip(self.dp.get_type_map(), range(self.dp.get_ntypes()))) + try: + self.type_dict=kwargs['type_dict'] + except: + self.type_dict = dict(zip(self.dp.get_type_map(), range(self.dp.get_ntypes()))) def calculate(self, atoms=None, properties=["energy", "forces", "stress"], system_changes=all_changes): coord = atoms.get_positions().reshape([1, -1]) From 05a84784d6c8da5574b23890b76bd401ec6138dc Mon Sep 17 00:00:00 2001 From: haidi Date: Sat, 22 Feb 2020 10:09:37 +0800 Subject: [PATCH 113/147] Update calculator.py --- source/train/calculator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/train/calculator.py b/source/train/calculator.py index 02f2c77a09..37fb7ad412 100644 --- a/source/train/calculator.py +++ b/source/train/calculator.py @@ -32,12 +32,12 @@ class DP(Calculator): name = "DP" implemented_properties = ["energy", "forces", "stress"] - def __init__(self, model, label="DP", **kwargs): + def __init__(self, model, label="DP", type_dict=None, **kwargs): Calculator.__init__(self, label=label, **kwargs) self.dp = DeepPot(model) - try: - self.type_dict=kwargs['type_dict'] - except: + if type_dict: + self.type_dict=type_dict + else: self.type_dict = dict(zip(self.dp.get_type_map(), range(self.dp.get_ntypes()))) def calculate(self, atoms=None, properties=["energy", "forces", "stress"], system_changes=all_changes): From 1dae1bc9ace5419deffa250f648378ea7700f93b Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sat, 22 Feb 2020 23:35:44 +0800 Subject: [PATCH 114/147] Update common.py --- source/train/common.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/train/common.py b/source/train/common.py index 4e034d7ca7..7da5a750c1 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -2,6 +2,7 @@ import numpy as np import math from deepmd.env import tf +from deepmd.RunOptions import global_tf_float_precision def gelu(x): """Gaussian Error Linear Unit. @@ -172,3 +173,16 @@ def expand_sys_str(root_dir): for filename in fnmatch.filter(filenames, 'type.raw'): matches.append(root) return matches + +def get_precision_func(precision): + if precision == 0: + return global_tf_float_precision + elif precision == 16: + return tf.float16 + elif precision == 32: + return tf.float32 + elif precision == 64: + return tf.float64 + else: + raise RuntimeError("%d is not a valid precision" % precision) + From edd415521082a846764587000fd0b4b5d3616466 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sat, 22 Feb 2020 23:41:30 +0800 Subject: [PATCH 115/147] Update DescrptSeA.py --- source/train/DescrptSeA.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 33b0aa3fb1..001941306c 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -1,6 +1,6 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, get_activation_func +from deepmd.common import ClassArg, get_activation_func, get_precision_func from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module @@ -19,7 +19,8 @@ def __init__ (self, jdata): .add('seed', int) \ .add('exclude_types', list, default = []) \ .add('set_davg_zero', bool, default = False) \ - .add('activation_function', str, default = 'tanh') + .add('activation_function', str, default = 'tanh') \ + .add('precision', int, default = 0) class_data = args.parse(jdata) self.sel_a = class_data['sel'] self.rcut_r = class_data['rcut'] @@ -30,6 +31,7 @@ def __init__ (self, jdata): self.seed = class_data['seed'] self.trainable = class_data['trainable'] self.filter_activation_fn = get_activation_func(class_data['activation_function']) + self.filter_precision = get_precision_func(class_data['precision']) exclude_types = class_data['exclude_types'] self.exclude_types = set() for tt in exclude_types: @@ -322,6 +324,7 @@ def _filter(self, seed=None, trainable = True): # natom x (nei x 4) + inputs = tf.cast(inputs, self.filter_precision) shape = inputs.get_shape().as_list() outputs_size = [1] + self.filter_neuron outputs_size_2 = self.n_axis_neuron @@ -343,18 +346,18 @@ def _filter(self, for ii in range(1, len(outputs_size)): w = tf.get_variable('matrix_'+str(ii)+'_'+str(type_i), [outputs_size[ii - 1], outputs_size[ii]], - global_tf_float_precision, + self.filter_precision, tf.random_normal_initializer(stddev=stddev/np.sqrt(outputs_size[ii]+outputs_size[ii-1]), seed = seed), trainable = trainable) b = tf.get_variable('bias_'+str(ii)+'_'+str(type_i), [1, outputs_size[ii]], - global_tf_float_precision, + self.filter_precision, tf.random_normal_initializer(stddev=stddev, mean = bavg, seed = seed), trainable = trainable) if self.filter_resnet_dt : idt = tf.get_variable('idt_'+str(ii)+'_'+str(type_i), [1, outputs_size[ii]], - global_tf_float_precision, + self.filter_precision, tf.random_normal_initializer(stddev=0.001, mean = 1.0, seed = seed), trainable = trainable) if outputs_size[ii] == outputs_size[ii-1]: @@ -409,6 +412,7 @@ def _filter_type_ext(self, seed=None, trainable = True): # natom x (nei x 4) + inputs = tf.cast(inputs, self.filter_precision) outputs_size = [1] + self.filter_neuron outputs_size_2 = self.n_axis_neuron with tf.variable_scope(name, reuse=reuse): @@ -430,18 +434,18 @@ def _filter_type_ext(self, for ii in range(1, len(outputs_size)): w = tf.get_variable('matrix_'+str(ii)+'_'+str(type_i), [outputs_size[ii - 1], outputs_size[ii]], - global_tf_float_precision, + self.filter_precision, tf.random_normal_initializer(stddev=stddev/np.sqrt(outputs_size[ii]+outputs_size[ii-1]), seed = seed), trainable = trainable) b = tf.get_variable('bias_'+str(ii)+'_'+str(type_i), [1, outputs_size[ii]], - global_tf_float_precision, + self.filter_precision, tf.random_normal_initializer(stddev=stddev, mean = bavg, seed = seed), trainable = trainable) if self.filter_resnet_dt : idt = tf.get_variable('idt_'+str(ii)+'_'+str(type_i), [1, outputs_size[ii]], - global_tf_float_precision, + self.filter_precision, tf.random_normal_initializer(stddev=0.001, mean = 1.0, seed = seed), trainable = trainable) if outputs_size[ii] == outputs_size[ii-1]: From 71650380ed8bab40c5fd18ecca9f38e5117d04b9 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sat, 22 Feb 2020 23:49:42 +0800 Subject: [PATCH 116/147] Update DescrptSeR.py --- source/train/DescrptSeR.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index 1acdfc9b63..642feb0e90 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -1,6 +1,6 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, get_activation_func +from deepmd.common import ClassArg, get_activation_func, get_precision_func from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module @@ -18,7 +18,8 @@ def __init__ (self, jdata): .add('seed', int) \ .add('exclude_types', list, default = []) \ .add('set_davg_zero', bool, default = False) \ - .add("activation_function", str, default = "tanh") + .add("activation_function", str, default = "tanh") \ + .add("precision", int, default = 0) class_data = args.parse(jdata) self.sel_r = class_data['sel'] self.rcut = class_data['rcut'] @@ -27,7 +28,8 @@ def __init__ (self, jdata): self.filter_resnet_dt = class_data['resnet_dt'] self.seed = class_data['seed'] self.trainable = class_data['trainable'] - self.filter_activation_fn = get_activation_func(class_data["activation_function"]) + self.filter_activation_fn = get_activation_func(class_data["activation_function"]) + self.filter_precision = get_precision_func(class_data['precision']) exclude_types = class_data['exclude_types'] self.exclude_types = set() for tt in exclude_types: @@ -206,7 +208,7 @@ def _pass_filter(self, [ 0, start_index* self.ndescrpt], [-1, natoms[2+type_i]* self.ndescrpt] ) inputs_i = tf.reshape(inputs_i, [-1, self.ndescrpt]) - layer = self._filter_r(inputs_i, type_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable, activation_fn = self.filter_activation_fn) + layer = self._filter_r(tf.cast(inputs_i, self.filter_precision), type_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable, activation_fn = self.filter_activation_fn) layer = tf.reshape(layer, [tf.shape(inputs)[0], natoms[2+type_i] * self.get_dim_out()]) output.append(layer) start_index += natoms[2+type_i] @@ -288,18 +290,18 @@ def _filter_r(self, for ii in range(1, len(outputs_size)): w = tf.get_variable('matrix_'+str(ii)+'_'+str(type_i), [outputs_size[ii - 1], outputs_size[ii]], - global_tf_float_precision, + self.filter_precision, tf.random_normal_initializer(stddev=stddev/np.sqrt(outputs_size[ii]+outputs_size[ii-1]), seed = seed), trainable = trainable) b = tf.get_variable('bias_'+str(ii)+'_'+str(type_i), [1, outputs_size[ii]], - global_tf_float_precision, + self.filter_precision, tf.random_normal_initializer(stddev=stddev, mean = bavg, seed = seed), trainable = trainable) if self.filter_resnet_dt : idt = tf.get_variable('idt_'+str(ii)+'_'+str(type_i), [1, outputs_size[ii]], - global_tf_float_precision, + self.filter_precision, tf.random_normal_initializer(stddev=0.001, mean = 1.0, seed = seed), trainable = trainable) if outputs_size[ii] == outputs_size[ii-1]: From 0c4ea37bb04fc4f8d46b1b5c9714ad769b9b8266 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sat, 22 Feb 2020 23:51:45 +0800 Subject: [PATCH 117/147] Update DescrptSeA.py --- source/train/DescrptSeA.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 001941306c..1d2427c983 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -249,7 +249,7 @@ def _pass_filter(self, [ 0, start_index* self.ndescrpt], [-1, natoms[2+type_i]* self.ndescrpt] ) inputs_i = tf.reshape(inputs_i, [-1, self.ndescrpt]) - layer, qmat = self._filter(inputs_i, type_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable, activation_fn = self.filter_activation_fn) + layer, qmat = self._filter(tf.cast(inputs_i, self.filter_precision), type_i, name='filter_type_'+str(type_i)+suffix, natoms=natoms, reuse=reuse, seed = self.seed, trainable = trainable, activation_fn = self.filter_activation_fn) layer = tf.reshape(layer, [tf.shape(inputs)[0], natoms[2+type_i] * self.get_dim_out()]) qmat = tf.reshape(qmat, [tf.shape(inputs)[0], natoms[2+type_i] * self.get_dim_rot_mat_1() * 3]) output.append(layer) @@ -324,7 +324,6 @@ def _filter(self, seed=None, trainable = True): # natom x (nei x 4) - inputs = tf.cast(inputs, self.filter_precision) shape = inputs.get_shape().as_list() outputs_size = [1] + self.filter_neuron outputs_size_2 = self.n_axis_neuron @@ -412,7 +411,6 @@ def _filter_type_ext(self, seed=None, trainable = True): # natom x (nei x 4) - inputs = tf.cast(inputs, self.filter_precision) outputs_size = [1] + self.filter_neuron outputs_size_2 = self.n_axis_neuron with tf.variable_scope(name, reuse=reuse): From e0d3fc91d7b34f0cf192b553318de942b318e199 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sat, 22 Feb 2020 23:53:02 +0800 Subject: [PATCH 118/147] Update Network.py --- source/train/Network.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/train/Network.py b/source/train/Network.py index 1adc1e1b31..fb87075942 100644 --- a/source/train/Network.py +++ b/source/train/Network.py @@ -6,6 +6,7 @@ def one_layer(inputs, outputs_size, activation_fn=tf.nn.tanh, + precision = global_tf_float_precision, stddev=1.0, bavg=0.0, name='linear', @@ -17,17 +18,17 @@ def one_layer(inputs, shape = inputs.get_shape().as_list() w = tf.get_variable('matrix', [shape[1], outputs_size], - global_tf_float_precision, + precision, tf.random_normal_initializer(stddev=stddev/np.sqrt(shape[1]+outputs_size), seed = seed)) b = tf.get_variable('bias', [outputs_size], - global_tf_float_precision, + precision, tf.random_normal_initializer(stddev=stddev, mean = bavg, seed = seed)) hidden = tf.matmul(inputs, w) + b if activation_fn != None and use_timestep : idt = tf.get_variable('idt', [outputs_size], - global_tf_float_precision, + precision, tf.random_normal_initializer(stddev=0.001, mean = 0.1, seed = seed)) if activation_fn != None: if useBN: From dec7a7ec7ffca4427396ad6073613b2e14460827 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 23 Feb 2020 00:13:13 +0800 Subject: [PATCH 119/147] Update Fitting.py --- source/train/Fitting.py | 80 +++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 497ee67ef5..4fbfb9f8e1 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -2,7 +2,7 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, add_data_requirement, get_activation_func +from deepmd.common import ClassArg, add_data_requirement, get_activation_func, get_precision_func from deepmd.Network import one_layer from deepmd.DescrptLocFrame import DescrptLocFrame from deepmd.DescrptSeA import DescrptSeA @@ -22,7 +22,8 @@ def __init__ (self, jdata, descrpt): .add('rcond', float, default = 1e-3) \ .add('seed', int) \ .add('atom_ener', list, default = [])\ - .add("activation_function", str, default = "tanh") + .add("activation_function", str, default = "tanh")\ + .add("precision", int, default = 0) class_data = args.parse(jdata) self.numb_fparam = class_data['numb_fparam'] self.numb_aparam = class_data['numb_aparam'] @@ -31,6 +32,7 @@ def __init__ (self, jdata, descrpt): self.rcond = class_data['rcond'] self.seed = class_data['seed'] self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) + self.fitting_precision = get_precision_func(class_data['precision']) self.atom_ener = [] for at, ae in enumerate(class_data['atom_ener']): if ae is not None: @@ -162,7 +164,7 @@ def build (self, initializer = tf.constant_initializer(self.aparam_inv_std)) start_index = 0 - inputs = tf.reshape(inputs, [-1, self.dim_descrpt * natoms[0]]) + inputs = tf.cast(tf.reshape(inputs, [-1, self.dim_descrpt * natoms[0]]), self.fitting_precision) if bias_atom_e is not None : assert(len(bias_atom_e) == self.ntypes) @@ -203,10 +205,10 @@ def build (self, for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) - final_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision) + final_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision) if type_i < len(self.atom_ener) and self.atom_ener[type_i] is not None: inputs_zero = tf.zeros_like(inputs_i, dtype=global_tf_float_precision) @@ -217,10 +219,10 @@ def build (self, layer = tf.concat([layer, ext_aparam], axis = 1) for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, use_timestep = self.resnet_dt) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, use_timestep = self.resnet_dt, precision = self.fitting_precision) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed) - zero_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=True, seed = self.seed) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, precision = self.fitting_precision) + zero_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, precision = self.fitting_precision) final_layer += self.atom_ener[type_i] - zero_layer final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms[2+type_i]]) @@ -231,7 +233,7 @@ def build (self, else: outs = tf.concat([outs, final_layer], axis = 1) - return tf.reshape(outs, [-1]) + return tf.cast(tf.reshape(outs, [-1]), self.fitting_precision) class WFCFitting () : @@ -246,7 +248,8 @@ def __init__ (self, jdata, descrpt) : .add('wfc_numb', int, must = True)\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'wfc_type')\ .add('seed', int)\ - .add("activation_function", str, default = "tanh") + .add("activation_function", str, default = "tanh")\ + .add('precision', int, default = 0) class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] @@ -254,6 +257,7 @@ def __init__ (self, jdata, descrpt) : self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) + self.fitting_precision = get_precision_func(class_data['precision']) self.useBN = False @@ -273,7 +277,7 @@ def build (self, reuse = None, suffix = '') : start_index = 0 - inputs = tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]) + inputs = tf.cast(tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]), self.fitting_precision) rot_mat = tf.reshape(rot_mat, [-1, 9 * natoms[0]]) count = 0 @@ -293,11 +297,11 @@ def build (self, layer = inputs_i for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) # (nframes x natoms) x (nwfc x 3) - final_layer = one_layer(layer, self.wfc_numb * 3, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + final_layer = one_layer(layer, self.wfc_numb * 3, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision) # (nframes x natoms) x nwfc(wc) x 3(coord_local) final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], self.wfc_numb, 3]) # (nframes x natoms) x nwfc(wc) x 3(coord) @@ -312,7 +316,7 @@ def build (self, outs = tf.concat([outs, final_layer], axis = 1) count += 1 - return tf.reshape(outs, [-1]) + return tf.cast(tf.reshape(outs, [-1]), self.fitting_precision) @@ -327,13 +331,15 @@ def __init__ (self, jdata, descrpt) : .add('resnet_dt', bool, default = True)\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'pol_type')\ .add('seed', int)\ - .add("activation_function", str, default = "tanh") + .add("activation_function", str, default = "tanh")\ + .add('precision', int, default = 0) class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) + self.fitting_precision = get_precision_func(class_data['precision']) self.useBN = False def get_sel_type(self): @@ -349,7 +355,7 @@ def build (self, reuse = None, suffix = '') : start_index = 0 - inputs = tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]) + inputs = tf.cast(tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]), self.fitting_precision) rot_mat = tf.reshape(rot_mat, [-1, 9 * natoms[0]]) count = 0 @@ -369,11 +375,11 @@ def build (self, layer = inputs_i for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) # (nframes x natoms) x 9 - final_layer = one_layer(layer, 9, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + final_layer = one_layer(layer, 9, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision) # (nframes x natoms) x 3 x 3 final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], 3, 3]) # (nframes x natoms) x 3 x 3 @@ -392,7 +398,7 @@ def build (self, outs = tf.concat([outs, final_layer], axis = 1) count += 1 - return tf.reshape(outs, [-1]) + return tf.cast(tf.reshape(outs, [-1]), self.fitting_precision) class PolarFittingSeA () : @@ -409,7 +415,8 @@ def __init__ (self, jdata, descrpt) : .add('scale', [list,float], default = [1.0 for ii in range(self.ntypes)])\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'pol_type')\ .add('seed', int)\ - .add("activation_function", str , default = "tanh") + .add("activation_function", str , default = "tanh")\ + .add('precision', int, default = 0) class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] @@ -419,6 +426,7 @@ def __init__ (self, jdata, descrpt) : self.diag_shift = class_data['diag_shift'] self.scale = class_data['scale'] self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) + self.fitting_precision = get_precision_func(class_data['precision']) if type(self.sel_type) is not list: self.sel_type = [self.sel_type] if type(self.diag_shift) is not list: @@ -459,7 +467,7 @@ def build (self, reuse = None, suffix = '') : start_index = 0 - inputs = tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]) + inputs = tf.cast(tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]), self.fitting_precision) rot_mat = tf.reshape(rot_mat, [-1, self.dim_rot_mat * natoms[0]]) count = 0 @@ -479,16 +487,16 @@ def build (self, layer = inputs_i for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) if self.fit_diag : bavg = np.zeros(self.dim_rot_mat_1) # bavg[0] = self.avgeig[0] # bavg[1] = self.avgeig[1] # bavg[2] = self.avgeig[2] # (nframes x natoms) x naxis - final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, bavg = bavg) + final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, bavg = bavg, precision = self.fitting_precision) # (nframes x natoms) x naxis final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], self.dim_rot_mat_1]) # (nframes x natoms) x naxis x naxis @@ -499,7 +507,7 @@ def build (self, # bavg[1*self.dim_rot_mat_1+1] = self.avgeig[1] # bavg[2*self.dim_rot_mat_1+2] = self.avgeig[2] # (nframes x natoms) x (naxis x naxis) - final_layer = one_layer(layer, self.dim_rot_mat_1*self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, bavg = bavg) + final_layer = one_layer(layer, self.dim_rot_mat_1*self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, bavg = bavg, precision = self.fitting_precision) # (nframes x natoms) x naxis x naxis final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], self.dim_rot_mat_1, self.dim_rot_mat_1]) # (nframes x natoms) x naxis x naxis @@ -522,7 +530,7 @@ def build (self, outs = tf.concat([outs, final_layer], axis = 1) count += 1 - return tf.reshape(outs, [-1]) + return tf.cast(tf.reshape(outs, [-1]), self.fitting_precision) class GlobalPolarFittingSeA () : @@ -564,13 +572,15 @@ def __init__ (self, jdata, descrpt) : .add('resnet_dt', bool, default = True)\ .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'dipole_type')\ .add('seed', int)\ - .add("activation_function", str, default = "tanh") + .add("activation_function", str, default = "tanh")\ + .add('precision', int, default = 0) class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) + self.fitting_precision = get_precision_func(class_data['precision']) self.dim_rot_mat_1 = descrpt.get_dim_rot_mat_1() self.dim_rot_mat = self.dim_rot_mat_1 * 3 self.useBN = False @@ -588,7 +598,7 @@ def build (self, reuse = None, suffix = '') : start_index = 0 - inputs = tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]) + inputs = tf.cast(tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]), self.fitting_precision) rot_mat = tf.reshape(rot_mat, [-1, self.dim_rot_mat * natoms[0]]) count = 0 @@ -608,11 +618,11 @@ def build (self, layer = inputs_i for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) # (nframes x natoms) x naxis - final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed) + final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision) # (nframes x natoms) x 1 * naxis final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], 1, self.dim_rot_mat_1]) # (nframes x natoms) x 1 x 3(coord) @@ -627,5 +637,5 @@ def build (self, outs = tf.concat([outs, final_layer], axis = 1) count += 1 - return tf.reshape(outs, [-1]) + return tf.cast(tf.reshape(outs, [-1]), self.fitting_precision) # return tf.reshape(outs, [tf.shape(inputs)[0] * natoms[0] * 3 // 3]) From 8d6fc08254ab762c9ec34bd01b6c619481cc063d Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 23 Feb 2020 00:24:44 +0800 Subject: [PATCH 120/147] Update Fitting.py --- source/train/Fitting.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 4fbfb9f8e1..9cc2b6f7ec 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -233,7 +233,7 @@ def build (self, else: outs = tf.concat([outs, final_layer], axis = 1) - return tf.cast(tf.reshape(outs, [-1]), self.fitting_precision) + return tf.cast(tf.reshape(outs, [-1]), global_tf_float_precision) class WFCFitting () : @@ -316,7 +316,7 @@ def build (self, outs = tf.concat([outs, final_layer], axis = 1) count += 1 - return tf.cast(tf.reshape(outs, [-1]), self.fitting_precision) + return tf.cast(tf.reshape(outs, [-1]), global_tf_float_precision) @@ -398,7 +398,7 @@ def build (self, outs = tf.concat([outs, final_layer], axis = 1) count += 1 - return tf.cast(tf.reshape(outs, [-1]), self.fitting_precision) + return tf.cast(tf.reshape(outs, [-1]), global_tf_float_precision) class PolarFittingSeA () : @@ -530,7 +530,7 @@ def build (self, outs = tf.concat([outs, final_layer], axis = 1) count += 1 - return tf.cast(tf.reshape(outs, [-1]), self.fitting_precision) + return tf.cast(tf.reshape(outs, [-1]), global_tf_float_precision) class GlobalPolarFittingSeA () : @@ -637,5 +637,5 @@ def build (self, outs = tf.concat([outs, final_layer], axis = 1) count += 1 - return tf.cast(tf.reshape(outs, [-1]), self.fitting_precision) + return tf.cast(tf.reshape(outs, [-1]), global_tf_float_precision) # return tf.reshape(outs, [tf.shape(inputs)[0] * natoms[0] * 3 // 3]) From 886ca0970f5baf49280bb6b1b1cc2ac08c4408ac Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 23 Feb 2020 00:30:09 +0800 Subject: [PATCH 121/147] Update DescrptSeA.py --- source/train/DescrptSeA.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 1d2427c983..3c3bc75944 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -1,6 +1,6 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, get_activation_func, get_precision_func +from deepmd.common import ClassArg, get_activation_func, get_precision_func from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module From afca35f1b0c747eb4ed7adb1507b261af39dfcee Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 23 Feb 2020 22:15:57 +0800 Subject: [PATCH 122/147] Update common.py --- source/train/common.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/train/common.py b/source/train/common.py index 7da5a750c1..9eee0a814f 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -175,13 +175,13 @@ def expand_sys_str(root_dir): return matches def get_precision_func(precision): - if precision == 0: + if precision == "default": return global_tf_float_precision - elif precision == 16: + elif precision == "float16": return tf.float16 - elif precision == 32: + elif precision == "float32": return tf.float32 - elif precision == 64: + elif precision == "float64": return tf.float64 else: raise RuntimeError("%d is not a valid precision" % precision) From 03bc29a2e4fb2dcadb1cecff2433811e21511e80 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 23 Feb 2020 22:16:26 +0800 Subject: [PATCH 123/147] Update common.py --- source/train/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/common.py b/source/train/common.py index 9eee0a814f..c250e4cdfc 100644 --- a/source/train/common.py +++ b/source/train/common.py @@ -174,7 +174,7 @@ def expand_sys_str(root_dir): matches.append(root) return matches -def get_precision_func(precision): +def get_precision(precision): if precision == "default": return global_tf_float_precision elif precision == "float16": From 4f0f54d511e79c61389d6b5825dc8c2246cea01d Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 23 Feb 2020 22:20:48 +0800 Subject: [PATCH 124/147] Update Fitting.py --- source/train/Fitting.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 9cc2b6f7ec..0e32ed71af 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -2,7 +2,7 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, add_data_requirement, get_activation_func, get_precision_func +from deepmd.common import ClassArg, add_data_requirement, get_activation_func, get_precision from deepmd.Network import one_layer from deepmd.DescrptLocFrame import DescrptLocFrame from deepmd.DescrptSeA import DescrptSeA @@ -23,7 +23,7 @@ def __init__ (self, jdata, descrpt): .add('seed', int) \ .add('atom_ener', list, default = [])\ .add("activation_function", str, default = "tanh")\ - .add("precision", int, default = 0) + .add("precision", str, default = "default") class_data = args.parse(jdata) self.numb_fparam = class_data['numb_fparam'] self.numb_aparam = class_data['numb_aparam'] @@ -32,7 +32,7 @@ def __init__ (self, jdata, descrpt): self.rcond = class_data['rcond'] self.seed = class_data['seed'] self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) - self.fitting_precision = get_precision_func(class_data['precision']) + self.fitting_precision = get_precision(class_data['precision']) self.atom_ener = [] for at, ae in enumerate(class_data['atom_ener']): if ae is not None: @@ -249,7 +249,7 @@ def __init__ (self, jdata, descrpt) : .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'wfc_type')\ .add('seed', int)\ .add("activation_function", str, default = "tanh")\ - .add('precision', int, default = 0) + .add('precision', str, default = "default") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] @@ -257,7 +257,7 @@ def __init__ (self, jdata, descrpt) : self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) - self.fitting_precision = get_precision_func(class_data['precision']) + self.fitting_precision = get_precision(class_data['precision']) self.useBN = False @@ -332,14 +332,14 @@ def __init__ (self, jdata, descrpt) : .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'pol_type')\ .add('seed', int)\ .add("activation_function", str, default = "tanh")\ - .add('precision', int, default = 0) + .add('precision', str, default = "default") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) - self.fitting_precision = get_precision_func(class_data['precision']) + self.fitting_precision = get_precision(class_data['precision']) self.useBN = False def get_sel_type(self): @@ -416,7 +416,7 @@ def __init__ (self, jdata, descrpt) : .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'pol_type')\ .add('seed', int)\ .add("activation_function", str , default = "tanh")\ - .add('precision', int, default = 0) + .add('precision', str, default = "default") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] @@ -426,7 +426,7 @@ def __init__ (self, jdata, descrpt) : self.diag_shift = class_data['diag_shift'] self.scale = class_data['scale'] self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) - self.fitting_precision = get_precision_func(class_data['precision']) + self.fitting_precision = get_precision(class_data['precision']) if type(self.sel_type) is not list: self.sel_type = [self.sel_type] if type(self.diag_shift) is not list: @@ -573,14 +573,14 @@ def __init__ (self, jdata, descrpt) : .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'dipole_type')\ .add('seed', int)\ .add("activation_function", str, default = "tanh")\ - .add('precision', int, default = 0) + .add('precision', str, default = "default") class_data = args.parse(jdata) self.n_neuron = class_data['neuron'] self.resnet_dt = class_data['resnet_dt'] self.sel_type = class_data['sel_type'] self.seed = class_data['seed'] self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) - self.fitting_precision = get_precision_func(class_data['precision']) + self.fitting_precision = get_precision(class_data['precision']) self.dim_rot_mat_1 = descrpt.get_dim_rot_mat_1() self.dim_rot_mat = self.dim_rot_mat_1 * 3 self.useBN = False From f19a06fe625d6fc6132dc60ae8eaff321c889eed Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 23 Feb 2020 22:23:01 +0800 Subject: [PATCH 125/147] Update DescrptSeA.py --- source/train/DescrptSeA.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/train/DescrptSeA.py b/source/train/DescrptSeA.py index 3c3bc75944..d409f7134f 100644 --- a/source/train/DescrptSeA.py +++ b/source/train/DescrptSeA.py @@ -1,6 +1,6 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, get_activation_func, get_precision_func +from deepmd.common import ClassArg, get_activation_func, get_precision from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module @@ -20,7 +20,7 @@ def __init__ (self, jdata): .add('exclude_types', list, default = []) \ .add('set_davg_zero', bool, default = False) \ .add('activation_function', str, default = 'tanh') \ - .add('precision', int, default = 0) + .add('precision', str, default = "default") class_data = args.parse(jdata) self.sel_a = class_data['sel'] self.rcut_r = class_data['rcut'] @@ -31,7 +31,7 @@ def __init__ (self, jdata): self.seed = class_data['seed'] self.trainable = class_data['trainable'] self.filter_activation_fn = get_activation_func(class_data['activation_function']) - self.filter_precision = get_precision_func(class_data['precision']) + self.filter_precision = get_precision(class_data['precision']) exclude_types = class_data['exclude_types'] self.exclude_types = set() for tt in exclude_types: From c87cfe873d215e653e19e51fd35738a9ebbd3cf4 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 23 Feb 2020 22:25:20 +0800 Subject: [PATCH 126/147] Update DescrptSeR.py --- source/train/DescrptSeR.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/train/DescrptSeR.py b/source/train/DescrptSeR.py index 642feb0e90..ed53a3bcd4 100644 --- a/source/train/DescrptSeR.py +++ b/source/train/DescrptSeR.py @@ -1,6 +1,6 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, get_activation_func, get_precision_func +from deepmd.common import ClassArg, get_activation_func, get_precision from deepmd.RunOptions import global_tf_float_precision from deepmd.RunOptions import global_np_float_precision from deepmd.env import op_module @@ -19,7 +19,7 @@ def __init__ (self, jdata): .add('exclude_types', list, default = []) \ .add('set_davg_zero', bool, default = False) \ .add("activation_function", str, default = "tanh") \ - .add("precision", int, default = 0) + .add("precision", str, default = "default") class_data = args.parse(jdata) self.sel_r = class_data['sel'] self.rcut = class_data['rcut'] @@ -29,7 +29,7 @@ def __init__ (self, jdata): self.seed = class_data['seed'] self.trainable = class_data['trainable'] self.filter_activation_fn = get_activation_func(class_data["activation_function"]) - self.filter_precision = get_precision_func(class_data['precision']) + self.filter_precision = get_precision(class_data['precision']) exclude_types = class_data['exclude_types'] self.exclude_types = set() for tt in exclude_types: From 0721f60277c10219458dca4796b957fa72038713 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Sun, 23 Feb 2020 22:27:18 +0800 Subject: [PATCH 127/147] Update Fitting.py --- source/train/Fitting.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 0e32ed71af..5daaf386c3 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -219,9 +219,9 @@ def build (self, layer = tf.concat([layer, ext_aparam], axis = 1) for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, use_timestep = self.resnet_dt, precision = self.fitting_precision) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, precision = self.fitting_precision) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) zero_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, precision = self.fitting_precision) final_layer += self.atom_ener[type_i] - zero_layer From 276a489d0d667315690c189ebcf0f11d5102285b Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Tue, 25 Feb 2020 16:29:26 -0500 Subject: [PATCH 128/147] find pthreads when compiling --- source/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 586a0b1472..6b18cb95ac 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -49,6 +49,9 @@ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-ignored-attributes") # find tensorflow, I need tf abi info find_package(tensorflow REQUIRED) +# find threads +find_package(Threads) + # auto op_cxx_abi if (NOT DEFINED OP_CXX_ABI) if (BUILD_PY_IF) From 25a7f8a8560c6bd3df83d5476e6a5af877314a59 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sun, 1 Mar 2020 13:14:39 +0800 Subject: [PATCH 129/147] fix the bug of loading dp model to the default tf graph --- source/train/DataModifier.py | 5 ++++- source/train/DeepDipole.py | 5 +++-- source/train/DeepEval.py | 16 +++++++++------- source/train/DeepPolar.py | 10 ++++++---- source/train/DeepPot.py | 5 +++-- source/train/DeepWFC.py | 5 +++-- 6 files changed, 28 insertions(+), 18 deletions(-) diff --git a/source/train/DataModifier.py b/source/train/DataModifier.py index fbbfff60bc..0afa5f1c4d 100644 --- a/source/train/DataModifier.py +++ b/source/train/DataModifier.py @@ -22,7 +22,10 @@ def __init__(self, # the dipole model is loaded with prefix 'dipole_charge' self.modifier_prefix = 'dipole_charge' # init dipole model - DeepDipole.__init__(self, model_name, load_prefix = self.modifier_prefix) + DeepDipole.__init__(self, + model_name, + load_prefix = self.modifier_prefix, + default_tf_graph = True) self.model_name = model_name self.model_charge_map = model_charge_map self.sys_charge_map = sys_charge_map diff --git a/source/train/DeepDipole.py b/source/train/DeepDipole.py index e7cb65d693..1183486624 100644 --- a/source/train/DeepDipole.py +++ b/source/train/DeepDipole.py @@ -5,6 +5,7 @@ class DeepDipole (DeepTensor) : def __init__(self, model_file, - load_prefix = 'load') : - DeepTensor.__init__(self, model_file, 'dipole', 3, load_prefix = load_prefix) + load_prefix = 'load', + default_tf_graph = False) : + DeepTensor.__init__(self, model_file, 'dipole', 3, load_prefix = load_prefix, default_tf_graph = default_tf_graph) diff --git a/source/train/DeepEval.py b/source/train/DeepEval.py index f0cefe6355..3a6e5624bc 100644 --- a/source/train/DeepEval.py +++ b/source/train/DeepEval.py @@ -13,17 +13,18 @@ class DeepEval(): """ def __init__(self, model_file, - load_prefix = 'load') : - self.graph = self._load_graph (model_file, prefix = load_prefix) + load_prefix = 'load', + default_tf_graph = False) : + self.graph = self._load_graph (model_file, prefix = load_prefix, default_tf_graph = default_tf_graph) t_mt = self.graph.get_tensor_by_name(os.path.join(load_prefix, 'model_attr/model_type:0')) sess = tf.Session (graph = self.graph, config=default_tf_session_config) [mt] = sess.run([t_mt], feed_dict = {}) self.model_type = mt.decode('utf-8') def _load_graph(self, - frozen_graph_filename, - prefix = 'load', - default_tf_graph = True): + frozen_graph_filename, + prefix = 'load', + default_tf_graph = False): # We load the protobuf file from the disk and parse it to retrieve the # unserialized graph_def with tf.gfile.GFile(frozen_graph_filename, "rb") as f: @@ -102,8 +103,9 @@ def __init__(self, model_file, variable_name, variable_dof, - load_prefix = 'load') : - DeepEval.__init__(self, model_file, load_prefix = load_prefix) + load_prefix = 'load', + default_tf_graph = False) : + DeepEval.__init__(self, model_file, load_prefix = load_prefix, default_tf_graph = default_tf_graph) # self.model_file = model_file # self.graph = self.load_graph (self.model_file) self.variable_name = variable_name diff --git a/source/train/DeepPolar.py b/source/train/DeepPolar.py index e0821443e6..705eacfe62 100644 --- a/source/train/DeepPolar.py +++ b/source/train/DeepPolar.py @@ -4,14 +4,16 @@ class DeepPolar (DeepTensor) : def __init__(self, - model_file) : - DeepTensor.__init__(self, model_file, 'polar', 9) + model_file, + default_tf_graph = False) : + DeepTensor.__init__(self, model_file, 'polar', 9, default_tf_graph = default_tf_graph) class DeepGlobalPolar (DeepTensor) : def __init__(self, - model_file) : - DeepTensor.__init__(self, model_file, 'global_polar', 9) + model_file, + default_tf_graph = False) : + DeepTensor.__init__(self, model_file, 'global_polar', 9, default_tf_graph = default_tf_graph) def eval(self, coords, diff --git a/source/train/DeepPot.py b/source/train/DeepPot.py index 2a75bb7388..bd46ee5578 100644 --- a/source/train/DeepPot.py +++ b/source/train/DeepPot.py @@ -9,8 +9,9 @@ class DeepPot (DeepEval) : def __init__(self, - model_file) : - DeepEval.__init__(self, model_file) + model_file, + default_tf_graph = False) : + DeepEval.__init__(self, model_file, default_tf_graph = default_tf_graph) # self.model_file = model_file # self.graph = self.load_graph (self.model_file) # checkout input/output tensors from graph diff --git a/source/train/DeepWFC.py b/source/train/DeepWFC.py index ee329628da..0fff8947da 100644 --- a/source/train/DeepWFC.py +++ b/source/train/DeepWFC.py @@ -4,6 +4,7 @@ class DeepWFC (DeepTensor) : def __init__(self, - model_file) : - DeepTensor.__init__(self, model_file, 'wfc', 12) + model_file, + default_tf_graph = False) : + DeepTensor.__init__(self, model_file, 'wfc', 12, default_tf_graph = default_tf_graph) From 634a7d3bd983921d374fac71a6e64e8cb83f83c0 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Wed, 4 Mar 2020 18:11:14 -0500 Subject: [PATCH 130/147] Call LAMMPS builtin citeme function log.cite file will be generated when running LAMMPS... --- source/lmp/pair_nnp.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/source/lmp/pair_nnp.cpp b/source/lmp/pair_nnp.cpp index 0b74dd38eb..ba3dcd3286 100644 --- a/source/lmp/pair_nnp.cpp +++ b/source/lmp/pair_nnp.cpp @@ -15,6 +15,7 @@ #include "neigh_request.h" #include "modify.h" #include "fix.h" +#include "citeme.h" #ifdef USE_TTM #include "fix_ttm_mod.h" #endif @@ -24,6 +25,22 @@ using namespace LAMMPS_NS; using namespace std; +static const char cite_user_deepmd_package[] = + "USER-DEEPMD package:\n\n" + "@article{Wang_ComputPhysCommun_2018_v228_p178,\n" + " author = {Wang, Han and Zhang, Linfeng and Han, Jiequn and E, Weinan},\n" + " doi = {10.1016/j.cpc.2018.03.016},\n" + " url = {https://doi.org/10.1016/j.cpc.2018.03.016},\n" + " year = 2018,\n" + " month = {jul},\n" + " publisher = {Elsevier {BV}},\n" + " volume = 228,\n" + " journal = {Comput. Phys. Commun.},\n" + " title = {{DeePMD-kit: A deep learning package for many-body potential energy representation and molecular dynamics}},\n" + " pages = {178--184}\n" + "}\n\n"; + + static int stringCmp(const void *a, const void* b) { char* m = (char*)a; @@ -185,6 +202,7 @@ PairNNP::PairNNP(LAMMPS *lmp) : Pair(lmp) { + if (lmp->citeme) lmp->citeme->add(cite_user_deepmd_package); if (strcmp(update->unit_style,"metal") != 0) { error->all(FLERR,"Pair deepmd requires metal unit, please set it by \"units metal\""); } From d928618493cc60958fd5b3e62bf231d541824bdd Mon Sep 17 00:00:00 2001 From: Han Wang Date: Tue, 24 Mar 2020 16:11:22 +0800 Subject: [PATCH 131/147] fix bug of getting ntypes from data --- source/train/Data.py | 3 +++ source/train/DataSystem.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/train/Data.py b/source/train/Data.py index db151d79cb..fb8cb25052 100644 --- a/source/train/Data.py +++ b/source/train/Data.py @@ -144,6 +144,9 @@ def get_test (self, ntests = -1) : self.modifier.modify_data(ret) return ret + def get_ntypes(self) : + return len(self.type_map) + def get_type_map(self) : return self.type_map diff --git a/source/train/DataSystem.py b/source/train/DataSystem.py index aca8994535..61d59f5cea 100644 --- a/source/train/DataSystem.py +++ b/source/train/DataSystem.py @@ -52,7 +52,7 @@ def __init__ (self, # natoms, nbatches ntypes = [] for ii in self.data_systems : - ntypes.append(np.max(ii.get_atom_type()) + 1) + ntypes.append(ii.get_ntypes()) self.sys_ntypes = max(ntypes) self.natoms = [] self.natoms_vec = [] From 7918287692055e4e8ef0ddb794c5bc518492febd Mon Sep 17 00:00:00 2001 From: Han Wang Date: Wed, 25 Mar 2020 17:33:36 +0800 Subject: [PATCH 132/147] fix bug of getting ntypes from data --- source/train/Data.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/train/Data.py b/source/train/Data.py index fb8cb25052..f3ecaeeb62 100644 --- a/source/train/Data.py +++ b/source/train/Data.py @@ -145,7 +145,10 @@ def get_test (self, ntests = -1) : return ret def get_ntypes(self) : - return len(self.type_map) + if self.type_map is not None: + return len(self.type_map) + else: + return max(self.get_atom_type()) + 1 def get_type_map(self) : return self.type_map From ba3ed02145174728f7539735abbca92bff3398f5 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Mon, 30 Mar 2020 15:00:25 +0800 Subject: [PATCH 133/147] set trainable of fitting layers --- source/train/Fitting.py | 21 +++++++++++++-------- source/train/Network.py | 10 +++++++--- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 5daaf386c3..960ff64e12 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -23,7 +23,8 @@ def __init__ (self, jdata, descrpt): .add('seed', int) \ .add('atom_ener', list, default = [])\ .add("activation_function", str, default = "tanh")\ - .add("precision", str, default = "default") + .add("precision", str, default = "default")\ + .add("trainable", [list, bool], default = True) class_data = args.parse(jdata) self.numb_fparam = class_data['numb_fparam'] self.numb_aparam = class_data['numb_aparam'] @@ -32,7 +33,11 @@ def __init__ (self, jdata, descrpt): self.rcond = class_data['rcond'] self.seed = class_data['seed'] self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) - self.fitting_precision = get_precision(class_data['precision']) + self.fitting_precision = get_precision(class_data['precision']) + self.trainable = class_data['trainable'] + if type(self.trainable) is bool: + self.trainable = [self.trainable] * (len(self.n_neuron)+1) + assert(len(self.trainable) == len(self.n_neuron) + 1), 'length of trainable should be that of n_neuron + 1' self.atom_ener = [] for at, ae in enumerate(class_data['atom_ener']): if ae is not None: @@ -205,10 +210,10 @@ def build (self, for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision, trainable = self.trainable[ii]) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision) - final_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision, trainable = self.trainable[ii]) + final_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision, trainable = self.trainable[-1]) if type_i < len(self.atom_ener) and self.atom_ener[type_i] is not None: inputs_zero = tf.zeros_like(inputs_i, dtype=global_tf_float_precision) @@ -219,10 +224,10 @@ def build (self, layer = tf.concat([layer, ext_aparam], axis = 1) for ii in range(0,len(self.n_neuron)) : if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) + layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision, trainable = self.trainable[ii]) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) - zero_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, precision = self.fitting_precision) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision, trainable = self.trainable[ii]) + zero_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=True, seed = self.seed, precision = self.fitting_precision, trainable = self.trainable[-1]) final_layer += self.atom_ener[type_i] - zero_layer final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms[2+type_i]]) diff --git a/source/train/Network.py b/source/train/Network.py index fb87075942..ed188c085d 100644 --- a/source/train/Network.py +++ b/source/train/Network.py @@ -13,23 +13,27 @@ def one_layer(inputs, reuse=None, seed=None, use_timestep = False, + trainable = True, useBN = False): with tf.variable_scope(name, reuse=reuse): shape = inputs.get_shape().as_list() w = tf.get_variable('matrix', [shape[1], outputs_size], precision, - tf.random_normal_initializer(stddev=stddev/np.sqrt(shape[1]+outputs_size), seed = seed)) + tf.random_normal_initializer(stddev=stddev/np.sqrt(shape[1]+outputs_size), seed = seed), + trainable = trainable) b = tf.get_variable('bias', [outputs_size], precision, - tf.random_normal_initializer(stddev=stddev, mean = bavg, seed = seed)) + tf.random_normal_initializer(stddev=stddev, mean = bavg, seed = seed), + trainable = trainable) hidden = tf.matmul(inputs, w) + b if activation_fn != None and use_timestep : idt = tf.get_variable('idt', [outputs_size], precision, - tf.random_normal_initializer(stddev=0.001, mean = 0.1, seed = seed)) + tf.random_normal_initializer(stddev=0.001, mean = 0.1, seed = seed), + trainable = trainable) if activation_fn != None: if useBN: None From 6ed141419e23d6936560b5758baf9b06ba025132 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Mon, 30 Mar 2020 22:56:28 +0800 Subject: [PATCH 134/147] Update main.py --- source/train/main.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/train/main.py b/source/train/main.py index 49aea59084..f76c714086 100644 --- a/source/train/main.py +++ b/source/train/main.py @@ -4,6 +4,7 @@ from .freeze import freeze from .config import config from .test import test +from .transform import transform def main () : parser = argparse.ArgumentParser( @@ -15,6 +16,13 @@ def main () : # help="the output json file") default_num_inter_threads = 0 + parser_transform = subparsers.add_parser('transform', help='pass parameters to another model') + parser_transform.add_argument('-r', "--raw-model", default = "raw_frozen_model.pb", type=str, + help = "the model receiving parameters") + parser_transform.add_argument("-o","--old-model", default = "old_frozen_model.pb", type=str, + help='the model providing parameters') + parser_transform.add_argument("-n", "--output", default = "frozen_model.pb", type=str, + help = "the model after passing parameters") parser_train = subparsers.add_parser('train', help='train a model') parser_train.add_argument('INPUT', help='the input parameter file in json format') @@ -62,5 +70,7 @@ def main () : config(args) elif args.command == 'test' : test(args) + elif args.command == 'transform' : + transform(args) else : raise RuntimeError('unknown command ' + args.command) From edb1ce9e532545bca0abf18f522617189b49ff08 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Mon, 30 Mar 2020 22:57:12 +0800 Subject: [PATCH 135/147] Create transform.py --- source/train/transform.py | 59 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 source/train/transform.py diff --git a/source/train/transform.py b/source/train/transform.py new file mode 100644 index 0000000000..4656393ed9 --- /dev/null +++ b/source/train/transform.py @@ -0,0 +1,59 @@ +from deepmd.env import tf +def transform(args): + new_graph = load_graph(args.raw_model) + old_graph = load_graph(args.old_model) + print("%d ops in the raw graph\n%d ops in the old graph" %(len(new_graph.node),len(old_graph.node))) + transform_node = load_data(new_graph,old_graph) + for node in new_graph.node: + if node.name in transform_node: + print("%s is passed from old graph to raw graph" % node.name) + node.attr["value"].tensor.CopyFrom(transform_node[node.name].attr["value"].tensor) + with tf.gfile.GFile(args.output, mode='wb') as f: + f.write(new_graph.SerializeToString()) + print("the output model is saved in %s" % args.output) + +def load_graph(graphName): + graph_def = tf.GraphDef() + with open(graphName,"rb") as f: + graph_def.ParseFromString(f.read()) + with tf.Graph().as_default() as graph: + tf.import_graph_def(graph_def,name = "") + return graph_def + +def load_data(new_graph,old_graph): + new_graph_node = load_transform_node(new_graph) + old_graph_node = load_transform_node(old_graph) + if len(new_graph_node) != len(old_graph_node): + raise RuntimeError("New graph and original graph has different network structure\n") + for nodeName in old_graph_node.keys(): + check_dim(new_graph_node, old_graph_node, nodeName) + check_precision(new_graph_node, old_graph_node, nodeName) + return old_graph_node + + +def check_precision(new_graph_node, old_graph_node, nodeName): + new_graph_precision = new_graph_node[nodeName].attr["value"].tensor.dtype + old_graph_precision = old_graph_node[nodeName].attr["value"].tensor.dtype + if new_graph_precision != old_graph_precision: + raise RuntimeError("New graph and original graph has different"+nodeName+" precision\n") + +def check_dim(new_graph_node, old_graph_node, nodeName): + new_graph_dim = new_graph_node[nodeName].attr["value"].tensor.tensor_shape + old_graph_dim = old_graph_node[nodeName].attr["value"].tensor.tensor_shape + if new_graph_dim != old_graph_dim: + raise RuntimeError("New graph and original graph has different"+nodeName+" dim\n") + + +def load_transform_node(graph): + transform_node = {} + filter_w = ["filter_type_0/matrix_{}_0".format(i) for i in range(1,10)] + filter_b = ["filter_type_0/bias_{}_0".format(i) for i in range(1,10)] + fitting_w = ["layer_{}_type_0/matrix".format(i) for i in range(0,10)] + fitting_b = ["layer_{}_type_0/bias".format(i) for i in range(0,10)] + fitting_idt = ["layer_{}_type_0/idt".format(i) for i in range(0,10)] + final_layer = ["final_layer_type_0/bias","final_layer_type_0/matrix"] + transform_node_list = filter_w + filter_b + fitting_w + fitting_b + fitting_idt + final_layer + for node in graph.node: + if node.name in transform_node_list: + transform_node[node.name] = node + return transform_node From 959dbfdbd92350c2fdc72345aa4c924137462bc1 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Mon, 30 Mar 2020 22:59:55 +0800 Subject: [PATCH 136/147] Update Fitting.py fix bug --- source/train/Fitting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/Fitting.py b/source/train/Fitting.py index 960ff64e12..49ca40b2c7 100644 --- a/source/train/Fitting.py +++ b/source/train/Fitting.py @@ -212,7 +212,7 @@ def build (self, if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision, trainable = self.trainable[ii]) else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision, trainable = self.trainable[ii]) + layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision, trainable = self.trainable[ii]) final_layer = one_layer(layer, 1, activation_fn = None, bavg = type_bias_ae, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision, trainable = self.trainable[-1]) if type_i < len(self.atom_ener) and self.atom_ener[type_i] is not None: From df5f3a69e4025bec934824c4473655da3185bcb6 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Mon, 30 Mar 2020 23:03:11 +0800 Subject: [PATCH 137/147] Update main.py --- source/train/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/main.py b/source/train/main.py index f76c714086..1e35d3bf17 100644 --- a/source/train/main.py +++ b/source/train/main.py @@ -71,6 +71,6 @@ def main () : elif args.command == 'test' : test(args) elif args.command == 'transform' : - transform(args) + transform(args) else : raise RuntimeError('unknown command ' + args.command) From 8385272e3abb815732fef7610a614857aa916b21 Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Tue, 31 Mar 2020 13:18:58 +0800 Subject: [PATCH 138/147] Update transform.py --- source/train/transform.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/source/train/transform.py b/source/train/transform.py index 4656393ed9..66ff871aad 100644 --- a/source/train/transform.py +++ b/source/train/transform.py @@ -1,4 +1,5 @@ from deepmd.env import tf +import re def transform(args): new_graph = load_graph(args.raw_model) old_graph = load_graph(args.old_model) @@ -46,14 +47,17 @@ def check_dim(new_graph_node, old_graph_node, nodeName): def load_transform_node(graph): transform_node = {} - filter_w = ["filter_type_0/matrix_{}_0".format(i) for i in range(1,10)] - filter_b = ["filter_type_0/bias_{}_0".format(i) for i in range(1,10)] - fitting_w = ["layer_{}_type_0/matrix".format(i) for i in range(0,10)] - fitting_b = ["layer_{}_type_0/bias".format(i) for i in range(0,10)] - fitting_idt = ["layer_{}_type_0/idt".format(i) for i in range(0,10)] - final_layer = ["final_layer_type_0/bias","final_layer_type_0/matrix"] - transform_node_list = filter_w + filter_b + fitting_w + fitting_b + fitting_idt + final_layer + transform_node_pattern = "\ +filter_type_\d+/matrix_\d+_\d+|\ +filter_type_\d+/bias_\d+_\d+|\ +filter_type_\d+/idt_\d+_\d+\ +layer_\d+_type_\d+/matrix|\ +layer_\d+_type_\d+/bias|\ +layer_\d+_type_\d+/idt|\ +final_layer_type_\d+/bias|\ +final_layer_type_\d+/matrix\ +" for node in graph.node: - if node.name in transform_node_list: + if re.fullmatch(transform_node_pattern,node.name) != None: transform_node[node.name] = node return transform_node From 288f61dfe2e9cd73023545e664b9973db877e61d Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Tue, 31 Mar 2020 21:54:02 +0800 Subject: [PATCH 139/147] Update transform.py --- source/train/transform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/transform.py b/source/train/transform.py index 66ff871aad..e9f4f020e0 100644 --- a/source/train/transform.py +++ b/source/train/transform.py @@ -50,7 +50,7 @@ def load_transform_node(graph): transform_node_pattern = "\ filter_type_\d+/matrix_\d+_\d+|\ filter_type_\d+/bias_\d+_\d+|\ -filter_type_\d+/idt_\d+_\d+\ +filter_type_\d+/idt_\d+_\d+|\ layer_\d+_type_\d+/matrix|\ layer_\d+_type_\d+/bias|\ layer_\d+_type_\d+/idt|\ From 8f6dea17694c6f1de2458e40d611ed49dfc0875f Mon Sep 17 00:00:00 2001 From: GeiduanLiu <61015788+GeiduanLiu@users.noreply.github.com> Date: Tue, 31 Mar 2020 23:34:36 +0800 Subject: [PATCH 140/147] Update transform.py --- source/train/transform.py | 89 ++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 33 deletions(-) diff --git a/source/train/transform.py b/source/train/transform.py index e9f4f020e0..6ae7723f7e 100644 --- a/source/train/transform.py +++ b/source/train/transform.py @@ -1,16 +1,13 @@ from deepmd.env import tf import re +import numpy as np def transform(args): - new_graph = load_graph(args.raw_model) + raw_graph = load_graph(args.raw_model) old_graph = load_graph(args.old_model) - print("%d ops in the raw graph\n%d ops in the old graph" %(len(new_graph.node),len(old_graph.node))) - transform_node = load_data(new_graph,old_graph) - for node in new_graph.node: - if node.name in transform_node: - print("%s is passed from old graph to raw graph" % node.name) - node.attr["value"].tensor.CopyFrom(transform_node[node.name].attr["value"].tensor) + print("%d ops in the raw graph\n%d ops in the old graph" %(len(raw_graph.as_graph_def().node),len(old_graph.as_graph_def().node))) + new_graph_def = transform_graph(raw_graph,old_graph) with tf.gfile.GFile(args.output, mode='wb') as f: - f.write(new_graph.SerializeToString()) + f.write(new_graph_def.SerializeToString()) print("the output model is saved in %s" % args.output) def load_graph(graphName): @@ -19,30 +16,56 @@ def load_graph(graphName): graph_def.ParseFromString(f.read()) with tf.Graph().as_default() as graph: tf.import_graph_def(graph_def,name = "") - return graph_def - -def load_data(new_graph,old_graph): - new_graph_node = load_transform_node(new_graph) - old_graph_node = load_transform_node(old_graph) - if len(new_graph_node) != len(old_graph_node): - raise RuntimeError("New graph and original graph has different network structure\n") - for nodeName in old_graph_node.keys(): - check_dim(new_graph_node, old_graph_node, nodeName) - check_precision(new_graph_node, old_graph_node, nodeName) - return old_graph_node - - -def check_precision(new_graph_node, old_graph_node, nodeName): - new_graph_precision = new_graph_node[nodeName].attr["value"].tensor.dtype - old_graph_precision = old_graph_node[nodeName].attr["value"].tensor.dtype - if new_graph_precision != old_graph_precision: - raise RuntimeError("New graph and original graph has different"+nodeName+" precision\n") - -def check_dim(new_graph_node, old_graph_node, nodeName): - new_graph_dim = new_graph_node[nodeName].attr["value"].tensor.tensor_shape - old_graph_dim = old_graph_node[nodeName].attr["value"].tensor.tensor_shape - if new_graph_dim != old_graph_dim: - raise RuntimeError("New graph and original graph has different"+nodeName+" dim\n") + return graph + +def transform_graph(raw_graph,old_graph): + precision_dict = {\ + 1:(np.float32, "float32"),\ + 2:(np.float64, "float64"),\ + 19:(np.float16, "float16")\ + } + old_graph_def = old_graph.as_graph_def() + raw_graph_def = raw_graph.as_graph_def() + raw_graph_node = load_transform_node(raw_graph_def) + old_graph_node = load_transform_node(old_graph_def) + + if len(raw_graph_node) != len(old_graph_node): + raise RuntimeError("raw graph and old graph has different network structure") + + for node in raw_graph_def.node: + if node.name in raw_graph_node.keys(): + if precision_dict[old_graph_node[node.name].dtype][1] == "float16" or precision_dict[raw_graph_node[node.name].dtype][1] == "float16": + raise RuntimeError("float16 conversions not currently supported") + + check_dim(raw_graph_node, old_graph_node, node.name) + + if re.fullmatch("final_layer_type_\d+/bias",node.name) == None: + tensor_value = np.frombuffer(old_graph_node[node.name].tensor_content,dtype = precision_dict[old_graph_node[node.name].dtype][0]) + tensor_value = tensor_value.astype(dtype=precision_dict[raw_graph_node[node.name].dtype][0]) + node.attr["value"].tensor.tensor_content = tensor_value.tostring() + + else: + if precision_dict[old_graph_node[node.name].dtype][1] == "float64": + tensor_value = (np.array(old_graph_node[node.name].double_val)).astype(precision_dict[raw_graph_node[node.name].dtype][0]) + node.attr["value"].CopyFrom(tf.AttrValue(tensor=tf.make_tensor_proto(tensor_value,precision_dict[raw_graph_node[node.name].dtype][0], [1]))) + + elif precision_dict[old_graph_node[node.name].dtype][1] == "float32": + tensor_value = (np.array(old_graph_node[node.name].float_val)).astype(precision_dict[raw_graph_node[node.name].dtype][0]) + node.attr["value"].CopyFrom(tf.AttrValue(tensor=tf.make_tensor_proto(tensor_value, precision_dict[raw_graph_node[node.name].dtype][0], [1]))) + + elif precision_dict[old_graph_node[node.name].dtype][1] == "float16": + tensor_value = (np.array(old_graph_node[node.name].half_val)).astype(precision_dict[raw_graph_node[node.name].dtype][0]) + node.attr["value"].CopyFrom(tf.AttrValue(tensor=tf.make_tensor_proto(tensor_value, precision_dict[raw_graph_node[node.name].dtype][0], [1]))) + + print("%s is passed from old graph(%s) to raw graph(%s)" % (node.name,precision_dict[old_graph_node[node.name].dtype][1],precision_dict[raw_graph_node[node.name].dtype][1])) + + return raw_graph_def + +def check_dim(raw_graph_node, old_graph_node, node_name): + raw_graph_dim = raw_graph_node[node_name].tensor_shape + old_graph_dim = old_graph_node[node_name].tensor_shape + if raw_graph_dim != old_graph_dim: + raise RuntimeError("old graph and raw graph has different"+node_name+" dim") def load_transform_node(graph): @@ -59,5 +82,5 @@ def load_transform_node(graph): " for node in graph.node: if re.fullmatch(transform_node_pattern,node.name) != None: - transform_node[node.name] = node + transform_node[node.name] = node.attr["value"].tensor return transform_node From 4c2439be9e6054ac9ddecaddda7526f18aec70be Mon Sep 17 00:00:00 2001 From: Lu Date: Wed, 1 Apr 2020 15:55:14 +0800 Subject: [PATCH 141/147] fix bug of load transform --- source/train/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/CMakeLists.txt b/source/train/CMakeLists.txt index 8be6b6c819..84a0848a77 100644 --- a/source/train/CMakeLists.txt +++ b/source/train/CMakeLists.txt @@ -2,7 +2,7 @@ configure_file("RunOptions.py.in" "${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py" @ONLY) -file(GLOB LIB_PY main.py common.py env.py compat.py calculator.py Network.py Deep*.py Data.py DataSystem.py Model*.py Descrpt*.py Fitting.py Loss.py LearningRate.py Trainer.py TabInter.py EwaldRecp.py DataModifier.py ${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py) +file(GLOB LIB_PY main.py common.py env.py compat.py calculator.py Network.py Deep*.py Data.py DataModifier.py DataSystem.py Model*.py Descrpt*.py Fitting.py Loss.py LearningRate.py Trainer.py TabInter.py EwaldRecp.py DataModifier.py ${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py transform.py print_old_model.py) file(GLOB CLS_PY Local.py Slurm.py) From 0e42066b8852856c02aea6af8f570cc1ab577d1d Mon Sep 17 00:00:00 2001 From: Lu Date: Thu, 2 Apr 2020 11:01:18 +0800 Subject: [PATCH 142/147] Increase the max neighbor size of an atom from 256 to 1024 --- source/lib/src/NNPInter.cc | 2 +- source/op/cuda/descrpt_se_a.cu | 4 ++-- source/op/descrpt_se_a_gpu.cc | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/source/lib/src/NNPInter.cc b/source/lib/src/NNPInter.cc index 58042019c7..f4f39945ff 100644 --- a/source/lib/src/NNPInter.cc +++ b/source/lib/src/NNPInter.cc @@ -3,7 +3,7 @@ #include "SimulationRegion.h" #include -#define MAGIC_NUMBER 256 +#define MAGIC_NUMBER 1024 #ifdef USE_CUDA_TOOLKIT #include "cuda_runtime.h" diff --git a/source/op/cuda/descrpt_se_a.cu b/source/op/cuda/descrpt_se_a.cu index 39434306f2..4b309522fa 100644 --- a/source/op/cuda/descrpt_se_a.cu +++ b/source/op/cuda/descrpt_se_a.cu @@ -18,7 +18,7 @@ limitations under the License. #include #include -#define MAGIC_NUMBER 256 +#define MAGIC_NUMBER 1024 #ifdef HIGH_PREC typedef double VALUETYPE; @@ -326,7 +326,7 @@ void DescrptSeALauncher(const VALUETYPE* coord, i_idx ); const int ITEMS_PER_THREAD = 4; - const int BLOCK_THREADS = 64; + const int BLOCK_THREADS = MAGIC_NUMBER / ITEMS_PER_THREAD; // BlockSortKernel<<>> ( BlockSortKernel <<>> (key, key + nloc * MAGIC_NUMBER); diff --git a/source/op/descrpt_se_a_gpu.cc b/source/op/descrpt_se_a_gpu.cc index 93c83016fb..a4b6b3512a 100644 --- a/source/op/descrpt_se_a_gpu.cc +++ b/source/op/descrpt_se_a_gpu.cc @@ -7,7 +7,6 @@ #include "tensorflow/core/framework/shape_inference.h" using namespace tensorflow; // NOLINT(build/namespaces) -#define MAGIC_NUMBER 256 #ifdef HIGH_PREC typedef double VALUETYPE ; @@ -201,7 +200,6 @@ class DescrptSeAOp : public OpKernel { cudaErrcheck(cudaMemcpy(&(array_longlong), 20 + mesh_tensor.flat().data(), sizeof(unsigned long long *), cudaMemcpyDeviceToHost)); cudaErrcheck(cudaMemcpy(&(array_double), 24 + mesh_tensor.flat().data(), sizeof(compute_t *), cudaMemcpyDeviceToHost)); - // cudaErrcheck(cudaMemcpy(jlist, host_jlist, sizeof(int) * nloc * MAGIC_NUMBER, cudaMemcpyHostToDevice)); // Launch computation for (int II = 0; II < nsamples; II++) { DescrptSeALauncher(coord_tensor.matrix().data() + II * (nall * 3), // related to the kk argument From 62cc79a0bb9e6583b7d686367adf39b357f75e4b Mon Sep 17 00:00:00 2001 From: Lu Date: Thu, 2 Apr 2020 16:54:12 +0800 Subject: [PATCH 143/147] Add boundary check if nnei is larger than 1024 --- source/op/descrpt_se_a_gpu.cc | 3 ++- source/train/CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/op/descrpt_se_a_gpu.cc b/source/op/descrpt_se_a_gpu.cc index a4b6b3512a..09e23d010d 100644 --- a/source/op/descrpt_se_a_gpu.cc +++ b/source/op/descrpt_se_a_gpu.cc @@ -158,7 +158,8 @@ class DescrptSeAOp : public OpKernel { OP_REQUIRES (context, (ntypes == int(sel_a.size())), errors::InvalidArgument ("number of types should match the length of sel array")); OP_REQUIRES (context, (ntypes == int(sel_r.size())), errors::InvalidArgument ("number of types should match the length of sel array")); - + OP_REQUIRES (context, (nnei > 1024), errors::InvalidArgument ("Assert failed, max neighbor size of atom(nnei) " + std::to_string(nnei) + " is larger than 1024!, which currently is not supported by deepmd-kit.")); + // Create output tensors TensorShape descrpt_shape ; descrpt_shape.AddDim (nsamples); diff --git a/source/train/CMakeLists.txt b/source/train/CMakeLists.txt index 84a0848a77..1875d2097c 100644 --- a/source/train/CMakeLists.txt +++ b/source/train/CMakeLists.txt @@ -2,7 +2,7 @@ configure_file("RunOptions.py.in" "${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py" @ONLY) -file(GLOB LIB_PY main.py common.py env.py compat.py calculator.py Network.py Deep*.py Data.py DataModifier.py DataSystem.py Model*.py Descrpt*.py Fitting.py Loss.py LearningRate.py Trainer.py TabInter.py EwaldRecp.py DataModifier.py ${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py transform.py print_old_model.py) +file(GLOB LIB_PY main.py common.py env.py compat.py calculator.py Network.py Deep*.py Data.py DataSystem.py Model*.py Descrpt*.py Fitting.py Loss.py LearningRate.py Trainer.py TabInter.py EwaldRecp.py DataModifier.py ${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py transform.py) file(GLOB CLS_PY Local.py Slurm.py) From 3a38dc4737c264fa513ed4c8d6572848da47a8c7 Mon Sep 17 00:00:00 2001 From: Lu Date: Thu, 2 Apr 2020 16:57:18 +0800 Subject: [PATCH 144/147] Add boundary check if nnei is larger than 1024 --- source/op/descrpt_se_a_gpu.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/op/descrpt_se_a_gpu.cc b/source/op/descrpt_se_a_gpu.cc index 09e23d010d..70dd9c7751 100644 --- a/source/op/descrpt_se_a_gpu.cc +++ b/source/op/descrpt_se_a_gpu.cc @@ -158,7 +158,7 @@ class DescrptSeAOp : public OpKernel { OP_REQUIRES (context, (ntypes == int(sel_a.size())), errors::InvalidArgument ("number of types should match the length of sel array")); OP_REQUIRES (context, (ntypes == int(sel_r.size())), errors::InvalidArgument ("number of types should match the length of sel array")); - OP_REQUIRES (context, (nnei > 1024), errors::InvalidArgument ("Assert failed, max neighbor size of atom(nnei) " + std::to_string(nnei) + " is larger than 1024!, which currently is not supported by deepmd-kit.")); + OP_REQUIRES (context, (nnei <= 1024), errors::InvalidArgument ("Assert failed, max neighbor size of atom(nnei) " + std::to_string(nnei) + " is larger than 1024!, which currently is not supported by deepmd-kit.")); // Create output tensors TensorShape descrpt_shape ; From 708370bac4bcdc0c6afedd1b19eaa98884d58035 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 10 Apr 2020 15:21:39 +0800 Subject: [PATCH 145/147] cmake find tensorflow: handel the case that headers are installed to different dirs lib and lib64 --- source/cmake/Findtensorflow.cmake | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/cmake/Findtensorflow.cmake b/source/cmake/Findtensorflow.cmake index b9cf247e22..61c4b6ebcc 100644 --- a/source/cmake/Findtensorflow.cmake +++ b/source/cmake/Findtensorflow.cmake @@ -10,9 +10,13 @@ # TensorFlowFramework_LIBRARY # TensorFlowFramework_LIBRARY_PATH +string(REPLACE "lib64" "lib" TENSORFLOW_ROOT_NO64 ${TENSORFLOW_ROOT}) + # define the search path list(APPEND TensorFlow_search_PATHS ${TENSORFLOW_ROOT}) list(APPEND TensorFlow_search_PATHS "${TENSORFLOW_ROOT}/../tensorflow_core") +list(APPEND TensorFlow_search_PATHS ${TENSORFLOW_ROOT_NO64}) +list(APPEND TensorFlow_search_PATHS "${TENSORFLOW_ROOT_NO64}/../tensorflow_core") list(APPEND TensorFlow_search_PATHS "/usr/") list(APPEND TensorFlow_search_PATHS "/usr/local/") @@ -28,6 +32,15 @@ find_path(TensorFlow_INCLUDE_DIRS PATH_SUFFIXES "/include" NO_DEFAULT_PATH ) +find_path(TensorFlow_INCLUDE_DIRS_GOOGLE + NAMES + google/protobuf/port.h + PATHS ${TensorFlow_search_PATHS} + PATH_SUFFIXES "/include" + NO_DEFAULT_PATH + ) +list(APPEND TensorFlow_INCLUDE_DIRS ${TensorFlow_INCLUDE_DIRS_GOOGLE}) + if (NOT TensorFlow_INCLUDE_DIRS AND tensorflow_FIND_REQUIRED) message(FATAL_ERROR "Not found 'include/tensorflow/core/public/session.h' directory in path '${TensorFlow_search_PATHS}' " From 25b5ada015f0fddb1a6294fe93023aa347924020 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sat, 11 Apr 2020 10:36:32 +0800 Subject: [PATCH 146/147] fix bug in finding protobuf --- source/cmake/Findtensorflow.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/cmake/Findtensorflow.cmake b/source/cmake/Findtensorflow.cmake index 61c4b6ebcc..708b8e86d5 100644 --- a/source/cmake/Findtensorflow.cmake +++ b/source/cmake/Findtensorflow.cmake @@ -34,7 +34,7 @@ find_path(TensorFlow_INCLUDE_DIRS ) find_path(TensorFlow_INCLUDE_DIRS_GOOGLE NAMES - google/protobuf/port.h + google/protobuf/type.pb.h PATHS ${TensorFlow_search_PATHS} PATH_SUFFIXES "/include" NO_DEFAULT_PATH @@ -43,7 +43,7 @@ list(APPEND TensorFlow_INCLUDE_DIRS ${TensorFlow_INCLUDE_DIRS_GOOGLE}) if (NOT TensorFlow_INCLUDE_DIRS AND tensorflow_FIND_REQUIRED) message(FATAL_ERROR - "Not found 'include/tensorflow/core/public/session.h' directory in path '${TensorFlow_search_PATHS}' " + "Not found 'tensorflow/core/public/session.h' directory in path '${TensorFlow_search_PATHS}' " "You can manually set the tensorflow install path by -DTENSORFLOW_ROOT ") endif () From e015eac083f6c4628fd79626e5e212493c48b1fe Mon Sep 17 00:00:00 2001 From: Han Wang Date: Sat, 23 May 2020 21:44:35 +0800 Subject: [PATCH 147/147] fix bug in test --- source/train/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/train/test.py b/source/train/test.py index 2674e9c01e..ef71b684da 100644 --- a/source/train/test.py +++ b/source/train/test.py @@ -50,7 +50,7 @@ def test (args): err_coll.append(err) siz_coll.append(siz) avg_err = weighted_average(err_coll, siz_coll) - if len(all_sys) != len(err): + if len(all_sys) != len(err_coll): print('Not all systems are tested! Check if the systems are valid') if len(all_sys) > 1: print ("# ----------weighted average of errors----------- ")