@@ -16,6 +16,8 @@ date: 2021-12-6
1616
1717*/
1818
19+ #include < cstring>
20+
1921#include " coord.h"
2022#include " custom_op.h"
2123#include " errors.h"
@@ -112,28 +114,29 @@ static void _map_nei_info_cpu(int* nlist,
112114 const bool & b_nlist_map);
113115
114116template <typename FPTYPE >
115- static void _prepare_coord_nlist_cpu (OpKernelContext* context,
116- FPTYPE const ** coord,
117- std::vector<FPTYPE >& coord_cpy,
118- int const ** type,
119- std::vector<int >& type_cpy,
120- std::vector<int >& idx_mapping,
121- deepmd::InputNlist& inlist,
122- std::vector<int >& ilist,
123- std::vector<int >& numneigh,
124- std::vector<int *>& firstneigh,
125- std::vector<std::vector<int >>& jlist,
126- int & new_nall,
127- int & mem_cpy,
128- int & mem_nnei,
129- int & max_nbor_size,
130- const FPTYPE * box,
131- const int * mesh_tensor_data,
132- const int & nloc,
133- const int & nei_mode,
134- const float & rcut_r,
135- const int & max_cpy_trial,
136- const int & max_nnei_trial);
117+ static tensorflow::Status _prepare_coord_nlist_cpu (
118+ FPTYPE const ** coord,
119+ std::vector<FPTYPE >& coord_cpy,
120+ int const ** type,
121+ std::vector<int >& type_cpy,
122+ std::vector<int >& idx_mapping,
123+ deepmd::InputNlist& inlist,
124+ std::vector<int >& ilist,
125+ std::vector<int >& numneigh,
126+ std::vector<int *>& firstneigh,
127+ std::vector<std::vector<int >>& jlist,
128+ int & new_nall,
129+ int & mem_cpy,
130+ int & mem_nnei,
131+ int & max_nbor_size,
132+ const FPTYPE * box,
133+ const int * mesh_tensor_data,
134+ const int_64 mesh_tensor_size,
135+ const int & nloc,
136+ const int & nei_mode,
137+ const float & rcut_r,
138+ const int & max_cpy_trial,
139+ const int & max_nnei_trial);
137140
138141// instance of function
139142
@@ -228,58 +231,132 @@ static void _map_nei_info_cpu(int* nlist,
228231 ntypes, b_nlist_map);
229232}
230233
234+ static tensorflow::Status _prepare_mesh_nlist_cpu (
235+ deepmd::InputNlist& inlist,
236+ std::vector<int >& ilist,
237+ std::vector<int >& numneigh,
238+ std::vector<int *>& firstneigh,
239+ std::vector<std::vector<int >>& jlist,
240+ int & max_nbor_size,
241+ const int * mesh_tensor_data,
242+ const int_64 mesh_tensor_size,
243+ const int nloc,
244+ const int nall) {
245+ // Tensor-stored lists use a 16-int header followed by ilist, numneigh,
246+ // and the concatenated neighbor rows. Validate every offset before copying
247+ // because this input can be constructed directly by callers.
248+ const int_64 header_size = 16 + static_cast <int_64>(2 ) * nloc;
249+ if (mesh_tensor_size < header_size) {
250+ return errors::InvalidArgument (" invalid mesh tensor" );
251+ }
252+
253+ const int * ilist_in = mesh_tensor_data + 16 ;
254+ const int * numneigh_in = mesh_tensor_data + 16 + nloc;
255+ const int * neighbors_in = mesh_tensor_data + header_size;
256+ std::vector<int_64> neighbor_offset (nloc + 1 , 0 );
257+ int supplied_max_nbor_size = 0 ;
258+ for (int ii = 0 ; ii < nloc; ++ii) {
259+ const int_64 neighbor_count = numneigh_in[ii];
260+ if (neighbor_count < 0 ||
261+ neighbor_offset[ii] > mesh_tensor_size - header_size - neighbor_count) {
262+ return errors::InvalidArgument (" invalid mesh tensor" );
263+ }
264+ neighbor_offset[ii + 1 ] = neighbor_offset[ii] + neighbor_count;
265+ supplied_max_nbor_size = std::max (supplied_max_nbor_size, numneigh_in[ii]);
266+ }
267+
268+ std::vector<unsigned char > seen (static_cast <size_t >(nloc), 0 );
269+ for (int ii = 0 ; ii < nloc; ++ii) {
270+ const int i_idx = ilist_in[ii];
271+ if (i_idx < 0 || i_idx >= nloc || seen[static_cast <size_t >(i_idx)]) {
272+ return errors::InvalidArgument (" invalid mesh tensor" );
273+ }
274+ seen[static_cast <size_t >(i_idx)] = 1 ;
275+ for (int_64 jj = neighbor_offset[ii]; jj < neighbor_offset[ii + 1 ]; ++jj) {
276+ // Downstream environment-matrix kernels index both coordinates and
277+ // atom types with this value, so accept only live frame atoms.
278+ if (neighbors_in[jj] < 0 || neighbors_in[jj] >= nall) {
279+ return errors::InvalidArgument (" invalid mesh tensor" );
280+ }
281+ }
282+ }
283+
284+ for (int ii = 0 ; ii < nloc; ++ii) {
285+ ilist[ii] = ilist_in[ii];
286+ numneigh[ii] = numneigh_in[ii];
287+ jlist[ii].assign (neighbors_in + neighbor_offset[ii],
288+ neighbors_in + neighbor_offset[ii + 1 ]);
289+ firstneigh[ii] = jlist[ii].data ();
290+ }
291+ inlist = deepmd::InputNlist (nloc, ilist.data (), numneigh.data (),
292+ firstneigh.data ());
293+ max_nbor_size = std::max (max_nbor_size, supplied_max_nbor_size);
294+ return tensorflow::Status ();
295+ }
296+
231297template <typename FPTYPE >
232- static void _prepare_coord_nlist_cpu (OpKernelContext* context,
233- FPTYPE const ** coord,
234- std::vector<FPTYPE >& coord_cpy,
235- int const ** type,
236- std::vector<int >& type_cpy,
237- std::vector<int >& idx_mapping,
238- deepmd::InputNlist& inlist,
239- std::vector<int >& ilist,
240- std::vector<int >& numneigh,
241- std::vector<int *>& firstneigh,
242- std::vector<std::vector<int >>& jlist,
243- int & new_nall,
244- int & mem_cpy,
245- int & mem_nnei,
246- int & max_nbor_size,
247- const FPTYPE * box,
248- const int * mesh_tensor_data,
249- const int & nloc,
250- const int & nei_mode,
251- const float & rcut_r,
252- const int & max_cpy_trial,
253- const int & max_nnei_trial) {
298+ static tensorflow::Status _prepare_coord_nlist_cpu (
299+ FPTYPE const ** coord,
300+ std::vector<FPTYPE >& coord_cpy,
301+ int const ** type,
302+ std::vector<int >& type_cpy,
303+ std::vector<int >& idx_mapping,
304+ deepmd::InputNlist& inlist,
305+ std::vector<int >& ilist,
306+ std::vector<int >& numneigh,
307+ std::vector<int *>& firstneigh,
308+ std::vector<std::vector<int >>& jlist,
309+ int & new_nall,
310+ int & mem_cpy,
311+ int & mem_nnei,
312+ int & max_nbor_size,
313+ const FPTYPE * box,
314+ const int * mesh_tensor_data,
315+ const int_64 mesh_tensor_size,
316+ const int & nloc,
317+ const int & nei_mode,
318+ const float & rcut_r,
319+ const int & max_cpy_trial,
320+ const int & max_nnei_trial) {
254321 inlist.inum = nloc;
255- if (nei_mode != 3 ) {
322+ if (nei_mode != 3 && nei_mode != 4 ) {
256323 // build nlist by myself
257324 // normalize and copy coord
258325 if (nei_mode == 1 ) {
259326 int copy_ok = _norm_copy_coord_cpu (coord_cpy, type_cpy, idx_mapping,
260327 new_nall, mem_cpy, *coord, box, *type,
261328 nloc, max_cpy_trial, rcut_r);
262- OP_REQUIRES (context, copy_ok,
263- errors::Aborted (" cannot allocate mem for copied coords" ));
329+ if (!copy_ok) {
330+ return errors::Aborted (" cannot allocate mem for copied coords" );
331+ }
264332 *coord = &coord_cpy[0 ];
265333 *type = &type_cpy[0 ];
266334 }
267335 // build nlist
268336 int build_ok = _build_nlist_cpu (ilist, numneigh, firstneigh, jlist,
269337 max_nbor_size, mem_nnei, *coord, nloc,
270338 new_nall, max_nnei_trial, rcut_r);
271- OP_REQUIRES (context, build_ok,
272- errors::Aborted (" cannot allocate mem for nlist" ));
339+ if (!build_ok) {
340+ return errors::Aborted (" cannot allocate mem for nlist" );
341+ }
273342 inlist.ilist = &ilist[0 ];
274343 inlist.numneigh = &numneigh[0 ];
275344 inlist.firstneigh = &firstneigh[0 ];
345+ } else if (nei_mode == 4 ) {
346+ tensorflow::Status status = _prepare_mesh_nlist_cpu (
347+ inlist, ilist, numneigh, firstneigh, jlist, max_nbor_size,
348+ mesh_tensor_data, mesh_tensor_size, nloc, new_nall);
349+ if (!status.ok ()) {
350+ return status;
351+ }
276352 } else {
277353 // copy pointers to nlist data
278354 memcpy (&inlist.ilist , 4 + mesh_tensor_data, sizeof (int *));
279355 memcpy (&inlist.numneigh , 8 + mesh_tensor_data, sizeof (int *));
280356 memcpy (&inlist.firstneigh , 12 + mesh_tensor_data, sizeof (int **));
281357 max_nbor_size = max_numneigh (inlist);
282358 }
359+ return tensorflow::Status ();
283360}
284361
285362/*
@@ -506,11 +583,14 @@ class ProdEnvMatANvnmdQuantizeOp : public OpKernel {
506583 std::vector<int > type_cpy;
507584 int frame_nall = nall;
508585 // prepare coord and nlist
509- _prepare_coord_nlist_cpu<FPTYPE >(
510- context, &coord, coord_cpy, &type, type_cpy, idx_mapping, inlist,
511- ilist, numneigh, firstneigh, jlist, frame_nall, mem_cpy, mem_nnei,
512- max_nbor_size, box, mesh_tensor.flat <int >().data (), nloc, nei_mode,
513- rcut_r, max_cpy_trial, max_nnei_trial);
586+ OP_REQUIRES_OK (
587+ context,
588+ _prepare_coord_nlist_cpu<FPTYPE >(
589+ &coord, coord_cpy, &type, type_cpy, idx_mapping, inlist, ilist,
590+ numneigh, firstneigh, jlist, frame_nall, mem_cpy, mem_nnei,
591+ max_nbor_size, box, mesh_tensor.flat <int >().data (),
592+ mesh_tensor.NumElements (), nloc, nei_mode, rcut_r,
593+ max_cpy_trial, max_nnei_trial));
514594 // launch the cpu compute function
515595 deepmd::prod_env_mat_a_nvnmd_quantize_cpu (
516596 em, em_deriv, rij, nlist, coord, type, inlist, max_nbor_size, avg,
@@ -789,11 +869,14 @@ class ProdEnvMatAMixNvnmdQuantizeOp : public OpKernel {
789869 std::vector<int > type_cpy;
790870 int frame_nall = nall;
791871 // prepare coord and nlist
792- _prepare_coord_nlist_cpu<FPTYPE >(
793- context, &coord, coord_cpy, &f_type, type_cpy, idx_mapping, inlist,
794- ilist, numneigh, firstneigh, jlist, frame_nall, mem_cpy, mem_nnei,
795- max_nbor_size, box, mesh_tensor.flat <int >().data (), nloc, nei_mode,
796- rcut_r, max_cpy_trial, max_nnei_trial);
872+ OP_REQUIRES_OK (
873+ context,
874+ _prepare_coord_nlist_cpu<FPTYPE >(
875+ &coord, coord_cpy, &f_type, type_cpy, idx_mapping, inlist,
876+ ilist, numneigh, firstneigh, jlist, frame_nall, mem_cpy,
877+ mem_nnei, max_nbor_size, box, mesh_tensor.flat <int >().data (),
878+ mesh_tensor.NumElements (), nloc, nei_mode, rcut_r,
879+ max_cpy_trial, max_nnei_trial));
797880 // launch the cpu compute function
798881 deepmd::prod_env_mat_a_nvnmd_quantize_cpu (
799882 em, em_deriv, rij, nlist, coord, type, inlist, max_nbor_size, avg,
0 commit comments