From c1891dca8258482d9b226edc48e91ea0755c83ee Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 9 May 2021 05:58:20 -0400 Subject: [PATCH 01/32] explicitly set vstring to None in case of exceptions --- python/lammps/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/python/lammps/__init__.py b/python/lammps/__init__.py index 2c0e7a6fe3..3e538d3e49 100644 --- a/python/lammps/__init__.py +++ b/python/lammps/__init__.py @@ -28,12 +28,15 @@ def get_version_number(): from importlib.metadata import version try: vstring = version('lammps') - except: pass + except: + vstring = None + else: from pkg_resources import get_distribution try: vstring = get_distribution('lammps').version - except: pass + except: + vstring = None if not vstring: return 0 From 6cf85e0ae3703c61df944a80b1ef263f2c1567e4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 9 May 2021 05:58:46 -0400 Subject: [PATCH 02/32] replace variable length array with explicit new/delete --- src/SNAP/pair_snap.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SNAP/pair_snap.cpp b/src/SNAP/pair_snap.cpp index 0d1964e73c..314bb7ca37 100644 --- a/src/SNAP/pair_snap.cpp +++ b/src/SNAP/pair_snap.cpp @@ -504,7 +504,7 @@ void PairSNAP::read_files(char *coefffilename, char *paramfilename) // initialize checklist for all required nelements - int elementflags[nelements]; + int *elementflags = new int[nelements]; for (int jelem = 0; jelem < nelements; jelem++) elementflags[jelem] = 0; @@ -601,6 +601,7 @@ void PairSNAP::read_files(char *coefffilename, char *paramfilename) error->all(FLERR,"Element {} not found in SNAP coefficient " "file", elements[jelem]); } + delete[] elementflags; // set flags for required keywords From 48a425718a8a52fc0488f9de7fdbfc79b47e53da Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 9 May 2021 05:58:54 -0400 Subject: [PATCH 03/32] remove dead code --- src/USER-PACE/pair_pace.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/USER-PACE/pair_pace.cpp b/src/USER-PACE/pair_pace.cpp index dc3473b991..3d0fafad30 100644 --- a/src/USER-PACE/pair_pace.cpp +++ b/src/USER-PACE/pair_pace.cpp @@ -131,7 +131,6 @@ void PairPACE::compute(int eflag, int vflag) { double **x = atom->x; double **f = atom->f; - tagint *tag = atom->tag; int *type = atom->type; // number of atoms in cell @@ -139,9 +138,6 @@ void PairPACE::compute(int eflag, int vflag) { int newton_pair = force->newton_pair; - // number of atoms including ghost atoms - int nall = nlocal + atom->nghost; - // inum: length of the neighborlists list inum = list->inum; From c9470c6baf2ac01c54b3b735d58e949899d7046b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 9 May 2021 11:33:53 -0400 Subject: [PATCH 04/32] update includes --- src/fix_deform.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/fix_deform.cpp b/src/fix_deform.cpp index 2624b30181..e37dce0e88 100644 --- a/src/fix_deform.cpp +++ b/src/fix_deform.cpp @@ -16,21 +16,23 @@ ------------------------------------------------------------------------- */ #include "fix_deform.h" -#include -#include + #include "atom.h" -#include "update.h" #include "comm.h" -#include "irregular.h" #include "domain.h" -#include "lattice.h" -#include "force.h" -#include "modify.h" -#include "math_const.h" -#include "kspace.h" -#include "input.h" -#include "variable.h" #include "error.h" +#include "force.h" +#include "input.h" +#include "irregular.h" +#include "kspace.h" +#include "lattice.h" +#include "math_const.h" +#include "modify.h" +#include "update.h" +#include "variable.h" + +#include +#include using namespace LAMMPS_NS; using namespace FixConst; From bffee8dd6a42207ec9c7bc7bdaa7492dfe02a24c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 9 May 2021 17:44:12 -0400 Subject: [PATCH 05/32] silence compiler warning --- src/USER-MISC/pair_dpd_ext.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/USER-MISC/pair_dpd_ext.cpp b/src/USER-MISC/pair_dpd_ext.cpp index ee03a6d1b9..9d59a167e9 100644 --- a/src/USER-MISC/pair_dpd_ext.cpp +++ b/src/USER-MISC/pair_dpd_ext.cpp @@ -12,12 +12,10 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Kurt Smith (U Pittsburgh) + Contributing authors: Martin Svoboda (ICPF, UJEP), Martin Lísal (ICPF, UJEP) + based on pair style dpd by: Kurt Smith (U Pittsburgh) ------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------- - Contributing authors: Martin Svoboda (ICPF, UJEP), Martin Lísal (ICPF, UJEP) -------------------------------------------------------------------------- */ #include "pair_dpd_ext.h" #include "atom.h" @@ -476,8 +474,8 @@ void PairDPDExt::write_data_all(FILE *fp) /* ---------------------------------------------------------------------- */ -double PairDPDExt::single(int i, int j, int itype, int jtype, double rsq, - double factor_coul, double factor_dpd, double &fforce) +double PairDPDExt::single(int /*i*/, int /*j*/, int itype, int jtype, double rsq, + double /*factor_coul*/, double factor_dpd, double &fforce) { double r,rinv,wd,phi; From 6d9309b76d03b3140cccee47318fe6d1c9452790 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 9 May 2021 17:44:23 -0400 Subject: [PATCH 06/32] remove dead code --- src/GPU/pair_lj_charmm_coul_charmm_gpu.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/GPU/pair_lj_charmm_coul_charmm_gpu.cpp b/src/GPU/pair_lj_charmm_coul_charmm_gpu.cpp index a40da25da8..a2b00b480f 100644 --- a/src/GPU/pair_lj_charmm_coul_charmm_gpu.cpp +++ b/src/GPU/pair_lj_charmm_coul_charmm_gpu.cpp @@ -133,16 +133,6 @@ void PairLJCharmmCoulCharmmGPU::init_style() error->all(FLERR, "Cannot use newton pair with lj/charmm/coul/long/gpu pair style"); - // Repeat cutsq calculation because done after call to init_style - - double cut; - for (int i = 1; i <= atom->ntypes; i++) { - for (int j = i; j <= atom->ntypes; j++) { - if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) - cut = init_one(i,j); - } - } - cut_lj_innersq = cut_lj_inner * cut_lj_inner; cut_coul_innersq = cut_coul_inner * cut_coul_inner; cut_ljsq = cut_lj * cut_lj; From 69a92a3e00334d9c9f3e87f1527bcb49af54fed5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 9 May 2021 19:52:31 -0400 Subject: [PATCH 07/32] apply some codeql recommendations - remove unused imports - avoid overlaps of variable names with keywords - make some exception processing more explicit --- python/lammps/core.py | 113 ++++++++++++++++----------------- python/lammps/formats.py | 2 +- python/lammps/numpy_wrapper.py | 72 ++++++++++----------- python/lammps/pylammps.py | 4 +- 4 files changed, 94 insertions(+), 97 deletions(-) diff --git a/python/lammps/core.py b/python/lammps/core.py index 1f606f67f4..cee7b107eb 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -18,9 +18,6 @@ from __future__ import print_function import os import sys -import traceback -import types -import warnings from ctypes import * from os.path import dirname,abspath,join from inspect import getsourcefile @@ -47,7 +44,7 @@ class ExceptionCheck: def __enter__(self): pass - def __exit__(self, type, value, traceback): + def __exit__(self, exc_type, exc_value, traceback): if self.lmp.has_exceptions and self.lmp.lib.lammps_has_error(self.lmp.lmp): raise self.lmp._lammps_exception @@ -310,7 +307,7 @@ class lammps(object): # tested to work with mpi4py versions 2 and 3 self.has_mpi4py = mpi4py_version.split('.')[0] in ['2','3'] except: - pass + self.has_mpi4py = None # if no ptr provided, create an instance of LAMMPS # don't know how to pass an MPI communicator from PyPar @@ -878,71 +875,71 @@ class lammps(object): # ------------------------------------------------------------------------- - def extract_compute(self,id,style,type): + def extract_compute(self,cid,cstyle,ctype): """Retrieve data from a LAMMPS compute This is a wrapper around the :cpp:func:`lammps_extract_compute` function of the C-library interface. This function returns ``None`` if either the compute id is not - recognized, or an invalid combination of :ref:`style ` - and :ref:`type ` constants is used. The + recognized, or an invalid combination of :ref:`cstyle ` + and :ref:`ctype ` constants is used. The names and functionality of the constants are the same as for the corresponding C-library function. For requests to return a scalar or a size, the value is returned, otherwise a pointer. - :param id: compute ID - :type id: string - :param style: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants` - :type style: int - :param type: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants` - :type type: int + :param cid: compute ID + :type cid: string + :param cstyle: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants` + :type cstyle: int + :param ctype: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants` + :type ctype: int :return: requested data as scalar, pointer to 1d or 2d double array, or None :rtype: c_double, ctypes.POINTER(c_double), ctypes.POINTER(ctypes.POINTER(c_double)), or NoneType """ - if id: id = id.encode() + if cid: cid = cid.encode() else: return None - if type == LMP_TYPE_SCALAR: + if ctype == LMP_TYPE_SCALAR: if style == LMP_STYLE_GLOBAL: self.lib.lammps_extract_compute.restype = POINTER(c_double) with ExceptionCheck(self): - ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type) + ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype) return ptr[0] elif style == LMP_STYLE_ATOM: return None elif style == LMP_STYLE_LOCAL: self.lib.lammps_extract_compute.restype = POINTER(c_int) with ExceptionCheck(self): - ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type) + ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype) return ptr[0] - elif type == LMP_TYPE_VECTOR: + elif ctype == LMP_TYPE_VECTOR: self.lib.lammps_extract_compute.restype = POINTER(c_double) with ExceptionCheck(self): - ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type) + ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype) return ptr - elif type == LMP_TYPE_ARRAY: + elif ctype == LMP_TYPE_ARRAY: self.lib.lammps_extract_compute.restype = POINTER(POINTER(c_double)) with ExceptionCheck(self): - ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type) + ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype) return ptr - elif type == LMP_SIZE_COLS: - if style == LMP_STYLE_GLOBAL \ - or style == LMP_STYLE_ATOM \ - or style == LMP_STYLE_LOCAL: + elif ctype == LMP_SIZE_COLS: + if cstyle == LMP_STYLE_GLOBAL \ + or cstyle == LMP_STYLE_ATOM \ + or cstyle == LMP_STYLE_LOCAL: self.lib.lammps_extract_compute.restype = POINTER(c_int) with ExceptionCheck(self): - ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type) + ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype) return ptr[0] - elif type == LMP_SIZE_VECTOR or type == LMP_SIZE_ROWS: - if style == LMP_STYLE_GLOBAL \ - or style == LMP_STYLE_LOCAL: + elif ctype == LMP_SIZE_VECTOR or ctype == LMP_SIZE_ROWS: + if cstyle == LMP_STYLE_GLOBAL \ + or cstyle == LMP_STYLE_LOCAL: self.lib.lammps_extract_compute.restype = POINTER(c_int) with ExceptionCheck(self): - ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type) + ptr = self.lib.lammps_extract_compute(self.lmp,cid,cstyle,ctype) return ptr[0] return None @@ -952,25 +949,25 @@ class lammps(object): # in case of global data, free memory for 1 double via lammps_free() # double was allocated by library interface function - def extract_fix(self,id,style,type,nrow=0,ncol=0): + def extract_fix(self,fid,fstyle,ftype,nrow=0,ncol=0): """Retrieve data from a LAMMPS fix This is a wrapper around the :cpp:func:`lammps_extract_fix` function of the C-library interface. This function returns ``None`` if either the fix id is not - recognized, or an invalid combination of :ref:`style ` - and :ref:`type ` constants is used. The + recognized, or an invalid combination of :ref:`fstyle ` + and :ref:`ftype ` constants is used. The names and functionality of the constants are the same as for the corresponding C-library function. For requests to return a scalar or a size, the value is returned, also when accessing global vectors or arrays, otherwise a pointer. - :param id: fix ID - :type id: string - :param style: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants` - :type style: int - :param type: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants` - :type type: int + :param fid: fix ID + :type fid: string + :param fstyle: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants` + :type fstyle: int + :param ftype: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants` + :type ftype: int :param nrow: index of global vector element or row index of global array element :type nrow: int :param ncol: column index of global array element @@ -979,53 +976,53 @@ class lammps(object): :rtype: c_double, ctypes.POINTER(c_double), ctypes.POINTER(ctypes.POINTER(c_double)), or NoneType """ - if id: id = id.encode() + if fid: fid = fid.encode() else: return None - if style == LMP_STYLE_GLOBAL: - if type in (LMP_TYPE_SCALAR, LMP_TYPE_VECTOR, LMP_TYPE_ARRAY): + if fstyle == LMP_STYLE_GLOBAL: + if ftype in (LMP_TYPE_SCALAR, LMP_TYPE_VECTOR, LMP_TYPE_ARRAY): self.lib.lammps_extract_fix.restype = POINTER(c_double) with ExceptionCheck(self): - ptr = self.lib.lammps_extract_fix(self.lmp,id,style,type,nrow,ncol) + ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol) result = ptr[0] self.lib.lammps_free(ptr) return result - elif type in (LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS): + elif ftype in (LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS): self.lib.lammps_extract_fix.restype = POINTER(c_int) with ExceptionCheck(self): - ptr = self.lib.lammps_extract_fix(self.lmp,id,style,type,nrow,ncol) + ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol) return ptr[0] else: return None - elif style == LMP_STYLE_ATOM: - if type == LMP_TYPE_VECTOR: + elif fstyle == LMP_STYLE_ATOM: + if ftype == LMP_TYPE_VECTOR: self.lib.lammps_extract_fix.restype = POINTER(c_double) - elif type == LMP_TYPE_ARRAY: + elif ftype == LMP_TYPE_ARRAY: self.lib.lammps_extract_fix.restype = POINTER(POINTER(c_double)) - elif type == LMP_SIZE_COLS: + elif ftype == LMP_SIZE_COLS: self.lib.lammps_extract_fix.restype = POINTER(c_int) else: return None with ExceptionCheck(self): - ptr = self.lib.lammps_extract_fix(self.lmp,id,style,type,nrow,ncol) - if type == LMP_SIZE_COLS: + ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol) + if ftype == LMP_SIZE_COLS: return ptr[0] else: return ptr - elif style == LMP_STYLE_LOCAL: - if type == LMP_TYPE_VECTOR: + elif fstyle == LMP_STYLE_LOCAL: + if ftype == LMP_TYPE_VECTOR: self.lib.lammps_extract_fix.restype = POINTER(c_double) - elif type == LMP_TYPE_ARRAY: + elif ftype == LMP_TYPE_ARRAY: self.lib.lammps_extract_fix.restype = POINTER(POINTER(c_double)) - elif type in (LMP_TYPE_SCALAR, LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS): + elif ftype in (LMP_TYPE_SCALAR, LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS): self.lib.lammps_extract_fix.restype = POINTER(c_int) else: return None with ExceptionCheck(self): - ptr = self.lib.lammps_extract_fix(self.lmp,id,style,type,nrow,ncol) - if type in (LMP_TYPE_VECTOR, LMP_TYPE_ARRAY): + ptr = self.lib.lammps_extract_fix(self.lmp,fid,fstyle,ftype,nrow,ncol) + if ftype in (LMP_TYPE_VECTOR, LMP_TYPE_ARRAY): return ptr else: return ptr[0] diff --git a/python/lammps/formats.py b/python/lammps/formats.py index 3ebc2e1bac..b5dc5d307c 100644 --- a/python/lammps/formats.py +++ b/python/lammps/formats.py @@ -176,7 +176,7 @@ class AvgChunkFile: current[data_column] = [value] chunks_read += 1 - assert (chunk == chunks_read) + assert chunk == chunks_read else: # do not support changing number of chunks if not (num_chunks == int(parts[1])): diff --git a/python/lammps/numpy_wrapper.py b/python/lammps/numpy_wrapper.py index b88c302166..4aca11cdc7 100644 --- a/python/lammps/numpy_wrapper.py +++ b/python/lammps/numpy_wrapper.py @@ -142,7 +142,7 @@ class numpy_wrapper: # ------------------------------------------------------------------------- - def extract_compute(self, cid, style, type): + def extract_compute(self, cid, cstyle, ctype): """Retrieve data from a LAMMPS compute This is a wrapper around the @@ -150,50 +150,50 @@ class numpy_wrapper: It behaves the same as the original method, but returns NumPy arrays instead of ``ctypes`` pointers. - :param id: compute ID - :type id: string - :param style: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants` - :type style: int - :param type: type of the returned data (scalar, vector, or array), see :ref:`py_type_constants` - :type type: int + :param cid: compute ID + :type cid: string + :param cstyle: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants` + :type cstyle: int + :param ctype: type of the returned data (scalar, vector, or array), see :ref:`py_type_constants` + :type ctype: int :return: requested data either as float, as NumPy array with direct access to C data, or None :rtype: float, numpy.array, or NoneType """ - value = self.lmp.extract_compute(cid, style, type) + value = self.lmp.extract_compute(cid, cstyle, ctype) - if style in (LMP_STYLE_GLOBAL, LMP_STYLE_LOCAL): - if type == LMP_TYPE_VECTOR: - nrows = self.lmp.extract_compute(cid, style, LMP_SIZE_VECTOR) + if cstyle in (LMP_STYLE_GLOBAL, LMP_STYLE_LOCAL): + if ctype == LMP_TYPE_VECTOR: + nrows = self.lmp.extract_compute(cid, cstyle, LMP_SIZE_VECTOR) return self.darray(value, nrows) - elif type == LMP_TYPE_ARRAY: - nrows = self.lmp.extract_compute(cid, style, LMP_SIZE_ROWS) - ncols = self.lmp.extract_compute(cid, style, LMP_SIZE_COLS) + elif ctype == LMP_TYPE_ARRAY: + nrows = self.lmp.extract_compute(cid, cstyle, LMP_SIZE_ROWS) + ncols = self.lmp.extract_compute(cid, cstyle, LMP_SIZE_COLS) return self.darray(value, nrows, ncols) - elif style == LMP_STYLE_ATOM: - if type == LMP_TYPE_VECTOR: + elif cstyle == LMP_STYLE_ATOM: + if ctype == LMP_TYPE_VECTOR: nlocal = self.lmp.extract_global("nlocal") return self.darray(value, nlocal) - elif type == LMP_TYPE_ARRAY: + elif ctype == LMP_TYPE_ARRAY: nlocal = self.lmp.extract_global("nlocal") - ncols = self.lmp.extract_compute(cid, style, LMP_SIZE_COLS) + ncols = self.lmp.extract_compute(cid, cstyle, LMP_SIZE_COLS) return self.darray(value, nlocal, ncols) return value # ------------------------------------------------------------------------- - def extract_fix(self, fid, style, type, nrow=0, ncol=0): + def extract_fix(self, fid, fstyle, ftype, nrow=0, ncol=0): """Retrieve data from a LAMMPS fix This is a wrapper around the :py:meth:`lammps.extract_fix() ` method. It behaves the same as the original method, but returns NumPy arrays instead of ``ctypes`` pointers. - :param id: fix ID - :type id: string - :param style: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants` - :type style: int - :param type: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants` - :type type: int + :param fid: fix ID + :type fid: string + :param fstyle: style of the data retrieve (global, atom, or local), see :ref:`py_style_constants` + :type fstyle: int + :param ftype: type or size of the returned data (scalar, vector, or array), see :ref:`py_type_constants` + :type ftype: int :param nrow: index of global vector element or row index of global array element :type nrow: int :param ncol: column index of global array element @@ -202,22 +202,22 @@ class numpy_wrapper: :rtype: integer or double value, pointer to 1d or 2d double array or None """ - value = self.lmp.extract_fix(fid, style, type, nrow, ncol) - if style == LMP_STYLE_ATOM: - if type == LMP_TYPE_VECTOR: + value = self.lmp.extract_fix(fid, fstyle, ftype, nrow, ncol) + if fstyle == LMP_STYLE_ATOM: + if ftype == LMP_TYPE_VECTOR: nlocal = self.lmp.extract_global("nlocal") return self.darray(value, nlocal) - elif type == LMP_TYPE_ARRAY: + elif ftype == LMP_TYPE_ARRAY: nlocal = self.lmp.extract_global("nlocal") - ncols = self.lmp.extract_fix(fid, style, LMP_SIZE_COLS, 0, 0) + ncols = self.lmp.extract_fix(fid, fstyle, LMP_SIZE_COLS, 0, 0) return self.darray(value, nlocal, ncols) - elif style == LMP_STYLE_LOCAL: - if type == LMP_TYPE_VECTOR: - nrows = self.lmp.extract_fix(fid, style, LMP_SIZE_ROWS, 0, 0) + elif fstyle == LMP_STYLE_LOCAL: + if ftype == LMP_TYPE_VECTOR: + nrows = self.lmp.extract_fix(fid, fstyle, LMP_SIZE_ROWS, 0, 0) return self.darray(value, nrows) - elif type == LMP_TYPE_ARRAY: - nrows = self.lmp.extract_fix(fid, style, LMP_SIZE_ROWS, 0, 0) - ncols = self.lmp.extract_fix(fid, style, LMP_SIZE_COLS, 0, 0) + elif ftype == LMP_TYPE_ARRAY: + nrows = self.lmp.extract_fix(fid, fstyle, LMP_SIZE_ROWS, 0, 0) + ncols = self.lmp.extract_fix(fid, fstyle, LMP_SIZE_COLS, 0, 0) return self.darray(value, nrows, ncols) return value diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index d3af62a588..be58df373e 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -23,7 +23,6 @@ from __future__ import print_function import os import re import select -import sys from collections import namedtuple from .core import lammps @@ -41,7 +40,7 @@ class OutputCapture(object): os.dup2(self.stdout_pipe_write, self.stdout_fd) return self - def __exit__(self, type, value, tracebac): + def __exit__(self, exc_type, exc_value, traceback): os.dup2(self.stdout, self.stdout_fd) os.close(self.stdout) os.close(self.stdout_pipe_read) @@ -351,6 +350,7 @@ def get_thermo_data(output): for i, col in enumerate(columns): current_run[col].append(values[i]) except ValueError: + # cannot convert. must be a non-thermo output. ignore. pass return runs From 92fe1373a52f6035cfdadbb922ca5663bae6a541 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 9 May 2021 20:24:22 -0400 Subject: [PATCH 08/32] fix bug --- python/lammps/core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/lammps/core.py b/python/lammps/core.py index cee7b107eb..36acde039a 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -307,7 +307,8 @@ class lammps(object): # tested to work with mpi4py versions 2 and 3 self.has_mpi4py = mpi4py_version.split('.')[0] in ['2','3'] except: - self.has_mpi4py = None + # ignore failing import + pass # if no ptr provided, create an instance of LAMMPS # don't know how to pass an MPI communicator from PyPar From 54b7baea7ba53e33ffb7ec66ab1b50e23afc4e18 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 9 May 2021 20:25:20 -0400 Subject: [PATCH 09/32] more codeql recommendations --- python/lammps/core.py | 71 ++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/python/lammps/core.py b/python/lammps/core.py index 36acde039a..1a8f62094b 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -777,6 +777,7 @@ class lammps(object): target_type = float elif dtype == LAMMPS_STRING: self.lib.lammps_extract_global.restype = c_char_p + target_type = str ptr = self.lib.lammps_extract_global(self.lmp, name) if ptr: @@ -1112,20 +1113,20 @@ class lammps(object): # return vector of atom properties gathered across procs # 3 variants to match src/library.cpp # name = atom property recognized by LAMMPS in atom->extract() - # type = 0 for integer values, 1 for double values + # dtype = 0 for integer values, 1 for double values # count = number of per-atom valus, 1 for type or charge, 3 for x or f # returned data is a 1d vector - doc how it is ordered? # NOTE: need to insure are converting to/from correct Python type # e.g. for Python list or NumPy or ctypes - def gather_atoms(self,name,type,count): + def gather_atoms(self,name,dtype,count): if name: name = name.encode() natoms = self.get_natoms() with ExceptionCheck(self): - if type == 0: + if dtype == 0: data = ((count*natoms)*c_int)() self.lib.lammps_gather_atoms(self.lmp,name,type,count,data) - elif type == 1: + elif dtype == 1: data = ((count*natoms)*c_double)() self.lib.lammps_gather_atoms(self.lmp,name,type,count,data) else: @@ -1134,29 +1135,29 @@ class lammps(object): # ------------------------------------------------------------------------- - def gather_atoms_concat(self,name,type,count): + def gather_atoms_concat(self,name,dtype,count): if name: name = name.encode() natoms = self.get_natoms() with ExceptionCheck(self): - if type == 0: + if dtype == 0: data = ((count*natoms)*c_int)() self.lib.lammps_gather_atoms_concat(self.lmp,name,type,count,data) - elif type == 1: + elif dtype == 1: data = ((count*natoms)*c_double)() self.lib.lammps_gather_atoms_concat(self.lmp,name,type,count,data) else: return None return data - def gather_atoms_subset(self,name,type,count,ndata,ids): + def gather_atoms_subset(self,name,dtype,count,ndata,ids): if name: name = name.encode() with ExceptionCheck(self): - if type == 0: + if dtype == 0: data = ((count*ndata)*c_int)() - self.lib.lammps_gather_atoms_subset(self.lmp,name,type,count,ndata,ids,data) - elif type == 1: + self.lib.lammps_gather_atoms_subset(self.lmp,name,dtype,count,ndata,ids,data) + elif dtype == 1: data = ((count*ndata)*c_double)() - self.lib.lammps_gather_atoms_subset(self.lmp,name,type,count,ndata,ids,data) + self.lib.lammps_gather_atoms_subset(self.lmp,name,dtype,count,ndata,ids,data) else: return None return data @@ -1172,17 +1173,17 @@ class lammps(object): # NOTE: need to insure are converting to/from correct Python type # e.g. for Python list or NumPy or ctypes - def scatter_atoms(self,name,type,count,data): + def scatter_atoms(self,name,dtype,count,data): if name: name = name.encode() with ExceptionCheck(self): - self.lib.lammps_scatter_atoms(self.lmp,name,type,count,data) + self.lib.lammps_scatter_atoms(self.lmp,name,dtype,count,data) # ------------------------------------------------------------------------- - def scatter_atoms_subset(self,name,type,count,ndata,ids,data): + def scatter_atoms_subset(self,name,dtype,count,ndata,ids,data): if name: name = name.encode() with ExceptionCheck(self): - self.lib.lammps_scatter_atoms_subset(self.lmp,name,type,count,ndata,ids,data) + self.lib.lammps_scatter_atoms_subset(self.lmp,name,dtype,count,ndata,ids,data) # return vector of atom/compute/fix properties gathered across procs # 3 variants to match src/library.cpp @@ -1192,43 +1193,43 @@ class lammps(object): # returned data is a 1d vector - doc how it is ordered? # NOTE: need to insure are converting to/from correct Python type # e.g. for Python list or NumPy or ctypes - def gather(self,name,type,count): + def gather(self,name,dtype,count): if name: name = name.encode() natoms = self.get_natoms() with ExceptionCheck(self): - if type == 0: + if dtype == 0: data = ((count*natoms)*c_int)() - self.lib.lammps_gather(self.lmp,name,type,count,data) - elif type == 1: + self.lib.lammps_gather(self.lmp,name,dtype,count,data) + elif dtype == 1: data = ((count*natoms)*c_double)() - self.lib.lammps_gather(self.lmp,name,type,count,data) + self.lib.lammps_gather(self.lmp,name,dtype,count,data) else: return None return data - def gather_concat(self,name,type,count): + def gather_concat(self,name,dtype,count): if name: name = name.encode() natoms = self.get_natoms() with ExceptionCheck(self): - if type == 0: + if dtype == 0: data = ((count*natoms)*c_int)() - self.lib.lammps_gather_concat(self.lmp,name,type,count,data) - elif type == 1: + self.lib.lammps_gather_concat(self.lmp,name,dtype,count,data) + elif dtype == 1: data = ((count*natoms)*c_double)() - self.lib.lammps_gather_concat(self.lmp,name,type,count,data) + self.lib.lammps_gather_concat(self.lmp,name,dtype,count,data) else: return None return data - def gather_subset(self,name,type,count,ndata,ids): + def gather_subset(self,name,dtype,count,ndata,ids): if name: name = name.encode() with ExceptionCheck(self): - if type == 0: + if dtype == 0: data = ((count*ndata)*c_int)() - self.lib.lammps_gather_subset(self.lmp,name,type,count,ndata,ids,data) - elif type == 1: + self.lib.lammps_gather_subset(self.lmp,name,dtype,count,ndata,ids,data) + elif dtype == 1: data = ((count*ndata)*c_double)() - self.lib.lammps_gather_subset(self.lmp,name,type,count,ndata,ids,data) + self.lib.lammps_gather_subset(self.lmp,name,dtype,count,ndata,ids,data) else: return None return data @@ -1242,15 +1243,15 @@ class lammps(object): # NOTE: need to insure are converting to/from correct Python type # e.g. for Python list or NumPy or ctypes - def scatter(self,name,type,count,data): + def scatter(self,name,dtype,count,data): if name: name = name.encode() with ExceptionCheck(self): - self.lib.lammps_scatter(self.lmp,name,type,count,data) + self.lib.lammps_scatter(self.lmp,name,dtype,count,data) - def scatter_subset(self,name,type,count,ndata,ids,data): + def scatter_subset(self,name,dtype,count,ndata,ids,data): if name: name = name.encode() with ExceptionCheck(self): - self.lib.lammps_scatter_subset(self.lmp,name,type,count,ndata,ids,data) + self.lib.lammps_scatter_subset(self.lmp,name,dtype,count,ndata,ids,data) # ------------------------------------------------------------------------- From 0a1c2b2a237b8b3f599e6b1a33eaee39e8eb5532 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 9 May 2021 23:11:20 -0400 Subject: [PATCH 10/32] update false positives --- doc/utils/sphinx-config/false_positives.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index e12767fb60..fc40ad004c 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1024,6 +1024,7 @@ fmag fmass fmm fmt +fmtlib fmx fmy fmz From c91563b797ca1be50d10c3c1f586d6e50aa6b68d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 10 May 2021 03:37:20 -0400 Subject: [PATCH 11/32] avoid uninitialized data issues detected by valgrind --- src/REPLICA/neb.cpp | 1 + src/REPLICA/tad.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/REPLICA/neb.cpp b/src/REPLICA/neb.cpp index 295e97dee8..3914e2b7d0 100644 --- a/src/REPLICA/neb.cpp +++ b/src/REPLICA/neb.cpp @@ -59,6 +59,7 @@ NEB::NEB(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, n1steps = n1steps_in; n2steps = n2steps_in; nevery = nevery_in; + verbose = false; // replica info diff --git a/src/REPLICA/tad.cpp b/src/REPLICA/tad.cpp index a849e7a242..f9ea044757 100644 --- a/src/REPLICA/tad.cpp +++ b/src/REPLICA/tad.cpp @@ -43,7 +43,10 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -TAD::TAD(LAMMPS *lmp) : Command(lmp) {} +TAD::TAD(LAMMPS *lmp) : Command(lmp) +{ + deltconf = deltstop = deltfirst = 0.0; +} /* ---------------------------------------------------------------------- */ From de3a49ac4f51ec7f019bd22e8d50dda8d6063938 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 10 May 2021 03:45:00 -0400 Subject: [PATCH 12/32] silence codeql warnings --- python/lammps/__init__.py | 6 ++++-- python/lammps/core.py | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/python/lammps/__init__.py b/python/lammps/__init__.py index 3e538d3e49..a51e0db207 100644 --- a/python/lammps/__init__.py +++ b/python/lammps/__init__.py @@ -29,14 +29,16 @@ def get_version_number(): try: vstring = version('lammps') except: - vstring = None + # nothing to do, ignore + pass else: from pkg_resources import get_distribution try: vstring = get_distribution('lammps').version except: - vstring = None + # nothing to do, ignore + pass if not vstring: return 0 diff --git a/python/lammps/core.py b/python/lammps/core.py index 1a8f62094b..c4d5bff591 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -778,6 +778,8 @@ class lammps(object): elif dtype == LAMMPS_STRING: self.lib.lammps_extract_global.restype = c_char_p target_type = str + else: + target_type = None ptr = self.lib.lammps_extract_global(self.lmp, name) if ptr: From fbdcfb2f7255e0813fe373bf0f9455441f9395e5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 10 May 2021 09:16:51 -0400 Subject: [PATCH 13/32] preliminary interface to detect whether a viable GPU is present --- lib/gpu/lal_device.cpp | 9 +++++++++ src/info.cpp | 12 ++++++++++++ src/info.h | 1 + 3 files changed, 22 insertions(+) diff --git a/lib/gpu/lal_device.cpp b/lib/gpu/lal_device.cpp index 1c19cf9186..cd38e9d959 100644 --- a/lib/gpu/lal_device.cpp +++ b/lib/gpu/lal_device.cpp @@ -1026,6 +1026,15 @@ Device global_device; } using namespace LAMMPS_AL; + +bool lmp_has_device() +{ + auto tmpgpu = new UCL_Device(); + int num = tmpgpu->num_platforms(); + delete tmpgpu; + return num > 0; +} + int lmp_init_device(MPI_Comm world, MPI_Comm replica, const int ngpu, const int first_gpu_id, const int gpu_mode, const double particle_split, const int t_per_atom, diff --git a/src/info.cpp b/src/info.cpp index 512858b9f2..a033d6608f 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -320,6 +320,7 @@ void Info::command(int narg, char **arg) if (flags & ACCELERATOR) { fmt::print(out,"\nAccelerator configuration:\n\n{}", get_accelerator_info()); + fmt::print(out,"\nGPU present: {}\n",has_gpu_device() ? "yes" : "no"); } if (flags & MEMORY) { @@ -1139,6 +1140,17 @@ bool Info::has_package(const std::string &package_name) { #if defined(LMP_GPU) extern bool lmp_gpu_config(const std::string &, const std::string &); +extern bool lmp_has_device(); + +bool Info::has_gpu_device() +{ + return lmp_has_device(); +} +#else +bool Info::has_gpu_device() +{ + return false; +} #endif #if defined(LMP_KOKKOS) diff --git a/src/info.h b/src/info.h index 9eb84d9312..ff649cc2bb 100644 --- a/src/info.h +++ b/src/info.h @@ -47,6 +47,7 @@ class Info : public Command { static bool has_accelerator_feature(const std::string &, const std::string &, const std::string &); + static bool has_gpu_device(); static std::string get_os_info(); static std::string get_compiler_info(); From a687868c69950283e81200ce113a4430c74856a6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 10 May 2021 16:34:27 -0400 Subject: [PATCH 14/32] finalize available GPU hardware introspection functions --- lib/gpu/lal_device.cpp | 18 +++++++++++++----- src/info.cpp | 17 ++++++++++++++--- src/info.h | 1 + src/lammps.cpp | 1 + 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/gpu/lal_device.cpp b/lib/gpu/lal_device.cpp index cd38e9d959..e2b5b9cdb5 100644 --- a/lib/gpu/lal_device.cpp +++ b/lib/gpu/lal_device.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #if (LAL_USE_OMP == 1) #include #endif @@ -1027,12 +1028,19 @@ Device global_device; using namespace LAMMPS_AL; -bool lmp_has_device() +bool lmp_has_gpu_device() { - auto tmpgpu = new UCL_Device(); - int num = tmpgpu->num_platforms(); - delete tmpgpu; - return num > 0; + UCL_Device gpu; + return (gpu.num_platforms() > 0); +} + +std::string lmp_gpu_device_info() +{ + std::ostringstream out; + UCL_Device gpu; + if (gpu.num_platforms() > 0) + gpu.print_all(out); + return out.str(); } int lmp_init_device(MPI_Comm world, MPI_Comm replica, const int ngpu, diff --git a/src/info.cpp b/src/info.cpp index a033d6608f..cae3865785 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -320,7 +320,8 @@ void Info::command(int narg, char **arg) if (flags & ACCELERATOR) { fmt::print(out,"\nAccelerator configuration:\n\n{}", get_accelerator_info()); - fmt::print(out,"\nGPU present: {}\n",has_gpu_device() ? "yes" : "no"); + if (Info::has_gpu_device()) + fmt::print(out,"\nAvailable GPU devices:\n{}\n",get_gpu_device_info()); } if (flags & MEMORY) { @@ -1140,17 +1141,27 @@ bool Info::has_package(const std::string &package_name) { #if defined(LMP_GPU) extern bool lmp_gpu_config(const std::string &, const std::string &); -extern bool lmp_has_device(); +extern bool lmp_has_gpu_device(); +extern std::string lmp_gpu_device_info(); bool Info::has_gpu_device() { - return lmp_has_device(); + return lmp_has_gpu_device(); +} + +std::string Info::get_gpu_device_info() +{ + return lmp_gpu_device_info(); } #else bool Info::has_gpu_device() { return false; } +std::string Info::get_gpu_device_info() +{ + return ""; +} #endif #if defined(LMP_KOKKOS) diff --git a/src/info.h b/src/info.h index ff649cc2bb..f376adf8dc 100644 --- a/src/info.h +++ b/src/info.h @@ -48,6 +48,7 @@ class Info : public Command { const std::string &, const std::string &); static bool has_gpu_device(); + static std::string get_gpu_device_info(); static std::string get_os_info(); static std::string get_compiler_info(); diff --git a/src/lammps.cpp b/src/lammps.cpp index 9e0aa1845d..85d56069bc 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -1328,6 +1328,7 @@ void LAMMPS::print_config(FILE *fp) fmt::print(fp,"Accelerator configuration:\n\n{}\n", Info::get_accelerator_info()); + fmt::print(fp,"GPU present: {}\n\n",Info::has_gpu_device() ? "yes" : "no"); fputs("Active compile time flags:\n\n",fp); if (Info::has_gzip_support()) fputs("-DLAMMPS_GZIP\n",fp); From 51847f70f2368d4f321eae96d01caefc7ac45484 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 10 May 2021 16:12:44 -0400 Subject: [PATCH 15/32] Use fmt::localtime() in info.cpp --- src/info.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/info.cpp b/src/info.cpp index cae3865785..4a91f41672 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -42,11 +42,11 @@ #include "text_file_reader.h" #include "update.h" #include "variable.h" +#include "fmt/chrono.h" #include #include #include -#include #include #ifdef _WIN32 @@ -265,8 +265,8 @@ void Info::command(int narg, char **arg) if (out == nullptr) return; fputs("\nInfo-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info\n",out); - time_t now = time(nullptr); - fmt::print(out,"Printed on {}\n",ctime(&now)); + std::time_t now = std::time(nullptr); + fmt::print(out,"Printed on {:%a %b %d %H:%M:%S %Y}\n", fmt::localtime(now)); if (flags & CONFIG) { fmt::print(out,"\nLAMMPS version: {} / {}\n", From feb0a49f2f7b66c004620c6f948e6097731b7261 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 10 May 2021 16:16:26 -0400 Subject: [PATCH 16/32] Python: Make NeighList a subclass of object --- python/lammps/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/lammps/data.py b/python/lammps/data.py index 892d628356..426da47ab2 100644 --- a/python/lammps/data.py +++ b/python/lammps/data.py @@ -16,7 +16,7 @@ # Written by Richard Berger ################################################################################ -class NeighList: +class NeighList(object): """This is a wrapper class that exposes the contents of a neighbor list. It can be used like a regular Python list. Each element is a tuple of: From f375aab2c5d7c10d2cc1b4105a7607e8e9f05cd1 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 10 May 2021 17:29:46 -0400 Subject: [PATCH 17/32] Correct test name --- unittest/python/python-open.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/python/python-open.py b/unittest/python/python-open.py index 5140ce9185..ad4cc24a24 100644 --- a/unittest/python/python-open.py +++ b/unittest/python/python-open.py @@ -78,7 +78,7 @@ class PythonOpen(unittest.TestCase): lmp.close() @unittest.skipIf(not has_exceptions,"Skipping death test since LAMMPS isn't compiled with exception support") - def testUnknownCommandInList(self): + def testUnknownCommandInString(self): lmp = lammps(name=self.machine) with self.assertRaisesRegex(Exception, "ERROR: Unknown command: write_paper"): From 38eb0fa29d5ce73e888252a678e07e45b4725155 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 10 May 2021 17:39:35 -0400 Subject: [PATCH 18/32] Python: add context manager implementation --- python/lammps/core.py | 20 +++++++++++++------- unittest/python/python-open.py | 10 ++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/python/lammps/core.py b/python/lammps/core.py index c4d5bff591..8610e85811 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -416,9 +416,16 @@ class lammps(object): # shut-down LAMMPS instance def __del__(self): - if self.lmp and self.opened: - self.lib.lammps_close(self.lmp) - self.opened = 0 + self.close() + + # ------------------------------------------------------------------------- + # context manager implementation + + def __enter__(self): + return self + + def __exit__(self, ex_type, ex_value, ex_traceback): + self.close() # ------------------------------------------------------------------------- @@ -445,7 +452,8 @@ class lammps(object): This is a wrapper around the :cpp:func:`lammps_close` function of the C-library interface. """ - if self.opened: self.lib.lammps_close(self.lmp) + if self.lmp and self.opened: + self.lib.lammps_close(self.lmp) self.lmp = None self.opened = 0 @@ -454,9 +462,7 @@ class lammps(object): def finalize(self): """Shut down the MPI communication through the library interface by calling :cpp:func:`lammps_finalize`. """ - if self.opened: self.lib.lammps_close(self.lmp) - self.lmp = None - self.opened = 0 + self.close() self.lib.lammps_finalize() # ------------------------------------------------------------------------- diff --git a/unittest/python/python-open.py b/unittest/python/python-open.py index ad4cc24a24..328745ded0 100644 --- a/unittest/python/python-open.py +++ b/unittest/python/python-open.py @@ -50,6 +50,16 @@ class PythonOpen(unittest.TestCase): self.assertIsNot(lmp.lmp,None) self.assertEqual(lmp.opened,1) + def testContextManager(self): + """Automatically clean up LAMMPS instance""" + with lammps(name=self.machine) as lmp: + self.assertIsNot(lmp.lmp,None) + self.assertEqual(lmp.opened,1) + self.assertEqual(has_mpi and has_mpi4py,lmp.has_mpi4py) + self.assertEqual(has_mpi,lmp.has_mpi_support) + self.assertIsNone(lmp.lmp,None) + self.assertEqual(lmp.opened,0) + @unittest.skipIf(not (has_mpi and has_mpi4py),"Skipping MPI test since LAMMPS is not parallel or mpi4py is not found") def testWithMPI(self): from mpi4py import MPI From 67660197a649f59bfc82677a285f66e6d721a0e7 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 10 May 2021 17:43:01 -0400 Subject: [PATCH 19/32] Add missing configuration file for LGTM --- .gitattributes | 1 + .lgtm.yml | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 .lgtm.yml diff --git a/.gitattributes b/.gitattributes index 02b13c8ee5..c93225ca26 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ .gitattributes export-ignore .gitignore export-ignore .github export-ignore +.lgtm.yml export-ignore diff --git a/.lgtm.yml b/.lgtm.yml new file mode 100644 index 0000000000..c36bdbb55e --- /dev/null +++ b/.lgtm.yml @@ -0,0 +1,11 @@ +extraction: + cpp: + configure: + command: + - "mkdir build" + - "cd build" + - "cmake -G Ninja -C ../cmake/presets/minimal.cmake ../cmake" + index: + build_command: + - "cd build" + - "ninja" From 85acf0b067232bdb106a0dd1065b2d30938cb739 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 10 May 2021 17:46:11 -0400 Subject: [PATCH 20/32] Remove unused imports --- lib/pace/Install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pace/Install.py b/lib/pace/Install.py index 08bbb331bb..140d65c819 100644 --- a/lib/pace/Install.py +++ b/lib/pace/Install.py @@ -6,7 +6,7 @@ used to automate the steps described in the README file in this dir """ from __future__ import print_function -import sys, os, subprocess, shutil +import sys, subprocess from argparse import ArgumentParser sys.path.append('..') @@ -102,4 +102,4 @@ if buildflag: print("Removing pace build files and archive ...") cmd = 'rm %s; make clean-build' % (download_filename) - subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) \ No newline at end of file + subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) From e1b2235d3643a1795a20bea52865dcaab6beb1b2 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 10 May 2021 18:23:39 -0400 Subject: [PATCH 21/32] Update py_nve.py --- examples/python/py_nve.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/examples/python/py_nve.py b/examples/python/py_nve.py index 9ff7c0978b..740668b850 100644 --- a/examples/python/py_nve.py +++ b/examples/python/py_nve.py @@ -1,7 +1,5 @@ from __future__ import print_function -from lammps import lammps, LAMMPS_INT, LAMMPS_DOUBLE -import ctypes -import traceback +from lammps import lammps import numpy as np class LAMMPSFix(object): @@ -80,36 +78,30 @@ class NVE_Opt(LAMMPSFixMove): self.ntypes = self.lmp.extract_global("ntypes") self.dtv = dt self.dtf = 0.5 * dt * ftm2v - self.mass = self.lmp.numpy.extract_atom("mass") def initial_integrate(self, vflag): - nlocal = self.lmp.extract_global("nlocal") + mass = self.lmp.numpy.extract_atom("mass") atype = self.lmp.numpy.extract_atom("type") x = self.lmp.numpy.extract_atom("x") v = self.lmp.numpy.extract_atom("v") f = self.lmp.numpy.extract_atom("f") dtf = self.dtf dtv = self.dtv - mass = self.mass dtfm = dtf / np.take(mass, atype) - dtfm.reshape((nlocal, 1)) for d in range(x.shape[1]): - v[:,d] += dtfm[:,0] * f[:,d] + v[:,d] += dtfm * f[:,d] x[:,d] += dtv * v[:,d] def final_integrate(self): - nlocal = self.lmp.extract_global("nlocal") mass = self.lmp.numpy.extract_atom("mass") atype = self.lmp.numpy.extract_atom("type") v = self.lmp.numpy.extract_atom("v") f = self.lmp.numpy.extract_atom("f") dtf = self.dtf - mass = self.mass dtfm = dtf / np.take(mass, atype) - dtfm.reshape((nlocal, 1)) for d in range(v.shape[1]): - v[:,d] += dtfm[:,0] * f[:,d] + v[:,d] += dtfm * f[:,d] From b4539fdac29f432db78cddccedd3f47d663ff91c Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 10 May 2021 18:54:01 -0400 Subject: [PATCH 22/32] Update CodeQL configuration --- .github/codeql/cpp.yml | 4 ++++ .github/codeql/python.yml | 5 +++++ .github/workflows/codeql-analysis.yml | 8 +++++--- 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 .github/codeql/cpp.yml create mode 100644 .github/codeql/python.yml diff --git a/.github/codeql/cpp.yml b/.github/codeql/cpp.yml new file mode 100644 index 0000000000..6244ba707d --- /dev/null +++ b/.github/codeql/cpp.yml @@ -0,0 +1,4 @@ +paths: + - src + - lib + - tools diff --git a/.github/codeql/python.yml b/.github/codeql/python.yml new file mode 100644 index 0000000000..c02a54e3ea --- /dev/null +++ b/.github/codeql/python.yml @@ -0,0 +1,5 @@ +paths: + - python/lammps + +queries: + - uses: security-and-quality diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 827306c9aa..064ba6c652 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -31,16 +31,18 @@ jobs: uses: github/codeql-action/init@v1 with: languages: ${{ matrix.language }} + config-file: ./.github/codeql/${{ matrix.language }}.yml - name: Create Build Environment - run: cmake -E make_directory ${{github.workspace}}/build + if: ${{ matrix.language == 'cpp' }} + run: mkdir build - name: Building LAMMPS via CMake if: ${{ matrix.language == 'cpp' }} shell: bash - working-directory: ${{github.workspace}}/build + working-directory: build run: | - cmake -C $GITHUB_WORKSPACE/cmake/presets/most.cmake $GITHUB_WORKSPACE/cmake + cmake -C ../cmake/presets/most.cmake ../cmake cmake --build . --parallel 2 - name: Perform CodeQL Analysis From 0260674698ee088e5c291b49e5f9ef73fb6f3d3c Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 10 May 2021 18:54:53 -0400 Subject: [PATCH 23/32] Update .lgtm.yml --- .lgtm.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.lgtm.yml b/.lgtm.yml index c36bdbb55e..2f2a31f292 100644 --- a/.lgtm.yml +++ b/.lgtm.yml @@ -9,3 +9,6 @@ extraction: build_command: - "cd build" - "ninja" + python: + python_setup: + version: 3 From 985fe9cd318fd2a2cdc9df14c9bfe521f427a930 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 10 May 2021 19:09:44 -0400 Subject: [PATCH 24/32] Use fmt::gmtime in timer.cpp --- src/timer.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/timer.cpp b/src/timer.cpp index 79fb63e7b5..0258f4d044 100644 --- a/src/timer.cpp +++ b/src/timer.cpp @@ -15,6 +15,7 @@ #include "comm.h" #include "error.h" +#include "fmt/chrono.h" #include @@ -26,8 +27,6 @@ #include #endif -#include - using namespace LAMMPS_NS; @@ -286,15 +285,13 @@ void Timer::modify_params(int narg, char **arg) if (comm->me == 0) { // format timeout setting - char timebuf[32]; - if (_timeout < 0) strcpy(timebuf,"off"); - else { - time_t tv = _timeout; - struct tm *tm = gmtime(&tv); - strftime(timebuf,32,"%H:%M:%S",tm); + std::string timeout = "off"; + if (_timeout >= 0) { + std::time_t tv = _timeout; + timeout = fmt::format("{:%H:%M:%S}", fmt::gmtime(tv)); } utils::logmesg(lmp,"New timer settings: style={} mode={} timeout={}\n", - timer_style[_level],timer_mode[_sync],timebuf); + timer_style[_level],timer_mode[_sync],timeout); } } From ecc9658ccab45d95f3200b1ec0df60a94fbdc7a6 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 10 May 2021 19:19:26 -0400 Subject: [PATCH 25/32] Add context manager code to PyLammps --- python/lammps/pylammps.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index be58df373e..dae2efcbe7 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -409,6 +409,12 @@ class PyLammps(object): self._enable_cmd_history = False self.runs = [] + def __enter__(self): + return self + + def __exit__(self, ex_type, ex_value, ex_traceback): + self.close() + def __del__(self): if self.lmp: self.lmp.close() self.lmp = None From 1ae21f46ab8797a9010d933d730b3a9f509a33c6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 10 May 2021 17:11:14 -0400 Subject: [PATCH 26/32] revert change that introduced a bug --- src/GPU/pair_lj_charmm_coul_charmm_gpu.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/GPU/pair_lj_charmm_coul_charmm_gpu.cpp b/src/GPU/pair_lj_charmm_coul_charmm_gpu.cpp index a2b00b480f..e15600fd81 100644 --- a/src/GPU/pair_lj_charmm_coul_charmm_gpu.cpp +++ b/src/GPU/pair_lj_charmm_coul_charmm_gpu.cpp @@ -133,6 +133,15 @@ void PairLJCharmmCoulCharmmGPU::init_style() error->all(FLERR, "Cannot use newton pair with lj/charmm/coul/long/gpu pair style"); + // Repeated cutsq calculation in init_one() is required for GPU package + + for (int i = 1; i <= atom->ntypes; i++) { + for (int j = i; j <= atom->ntypes; j++) { + if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) + init_one(i,j); + } + } + cut_lj_innersq = cut_lj_inner * cut_lj_inner; cut_coul_innersq = cut_coul_inner * cut_coul_inner; cut_ljsq = cut_lj * cut_lj; From 883d55f416847824f2e56a6c651d7672a4044446 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 10 May 2021 17:11:48 -0400 Subject: [PATCH 27/32] skip running GPU test if there is no viable GPU device --- unittest/force-styles/test_pair_style.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index 057f2b5352..d40c7dc124 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -778,6 +778,7 @@ TEST(PairStyle, omp) TEST(PairStyle, gpu) { if (!LAMMPS::is_installed_pkg("GPU")) GTEST_SKIP(); + if (!Info::has_gpu_device()) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); const char *args_neigh[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", "-sf", "gpu"}; From af6eae29d4629602d6568eb720ba1b44bb75cc48 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 10 May 2021 17:28:50 -0400 Subject: [PATCH 28/32] reformat else statements --- src/USER-MISC/compute_hma.cpp | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/USER-MISC/compute_hma.cpp b/src/USER-MISC/compute_hma.cpp index fbe8c67d39..23c0334dd3 100644 --- a/src/USER-MISC/compute_hma.cpp +++ b/src/USER-MISC/compute_hma.cpp @@ -77,7 +77,8 @@ ComputeHMA::ComputeHMA(LAMMPS *lmp, int narg, char **arg) : { if (narg < 4) error->all(FLERR,"Illegal compute hma command"); if (igroup) error->all(FLERR,"Compute hma must use group all"); - if (strcmp(arg[3],"NULL") == 0) {error->all(FLERR,"fix ID specifying the set temperature of canonical simulation is required");} + if (strcmp(arg[3],"NULL") == 0) + error->all(FLERR,"fix ID specifying the set temperature of canonical simulation is required"); else id_temp = utils::strdup(arg[3]); create_attribute = 1; @@ -121,8 +122,7 @@ ComputeHMA::ComputeHMA(LAMMPS *lmp, int narg, char **arg) : computeU = size_vector; extlist[size_vector] = 1; size_vector++; - } - else if (!strcmp(arg[iarg], "p")) { + } else if (!strcmp(arg[iarg], "p")) { if (iarg+2 > narg) error->all(FLERR,"Illegal compute hma command"); if (computeP>-1) continue; computeP = size_vector; @@ -130,19 +130,16 @@ ComputeHMA::ComputeHMA(LAMMPS *lmp, int narg, char **arg) : extlist[size_vector] = 0; size_vector++; iarg++; - } - else if (!strcmp(arg[iarg], "cv")) { + } else if (!strcmp(arg[iarg], "cv")) { if (computeCv>-1) continue; computeCv = size_vector; comm_forward = 3; extlist[size_vector] = 1; size_vector++; - } - else if (!strcmp(arg[iarg], "anharmonic")) { + } else if (!strcmp(arg[iarg], "anharmonic")) { // the first time we're called, we'll grab lattice pressure and energy returnAnharmonic = -1; - } - else { + } else { error->all(FLERR,"Illegal compute hma command"); } } @@ -278,8 +275,7 @@ void ComputeHMA::compute_vector() } fdr += dx*f[i][0] + dy*f[i][1] + dz*f[i][2]; } - } - else { + } else { for (int i = 0; i < nlocal; i++) { int xbox = (image[i] & IMGMASK) - IMGMAX; int ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; @@ -369,8 +365,7 @@ void ComputeHMA::compute_vector() if (computeU>-1) { if (returnAnharmonic) { vector[computeU] = uTotal - uLat + 0.5*fdrTotal; - } - else { + } else { vector[computeU] = uTotal + 0.5*fdrTotal + 0.5*dimension*(atom->natoms - 1)*force->boltz*finaltemp; } } @@ -380,8 +375,7 @@ void ComputeHMA::compute_vector() double fv = ((deltaPcap)-(force->boltz*finaltemp*force->nktv2p*atom->natoms/vol))/(force->boltz*finaltemp*dimension*(atom->natoms - 1)); if (returnAnharmonic) { vector[computeP] = p - pLat + (fv*fdrTotal); - } - else { + } else { vector[computeP] = p + (fv*fdrTotal) + deltaPcap; } } @@ -391,8 +385,7 @@ void ComputeHMA::compute_vector() double buTot; if (returnAnharmonic) { buTot = (uTotal - uLat + 0.5*fdrTotal)/finaltemp; - } - else { + } else { buTot = (uTotal + 0.5*fdrTotal)/finaltemp + 0.5*dimension*(atom->natoms - 1)*force->boltz; } double one = -0.25*(fdr + phiSum)/finaltemp; From ead311adf8f58a4b5e46b7e1cedf88746836e5d3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 11 May 2021 11:48:44 -0400 Subject: [PATCH 29/32] replace variable length array on stack with std::unique_ptr() this closes #2757 --- src/MC/fix_charge_regulation.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/MC/fix_charge_regulation.cpp b/src/MC/fix_charge_regulation.cpp index 6226dd5ba5..416d0541c3 100644 --- a/src/MC/fix_charge_regulation.cpp +++ b/src/MC/fix_charge_regulation.cpp @@ -42,6 +42,7 @@ #include #include +#include using namespace LAMMPS_NS; using namespace FixConst; @@ -724,7 +725,9 @@ void FixChargeRegulation::forward_ions_multival() { double energy_before = energy_stored; double factor = 1; double dummyp[3]; - int mm[salt_charge_ratio + 1];// particle ID array for all ions to be inserted + + // particle ID array for all ions to be inserted + auto mm = std::unique_ptr(new int[salt_charge_ratio + 1]); if (salt_charge[0] <= -salt_charge[1]) { // insert one anion and (salt_charge_ratio) cations @@ -778,9 +781,12 @@ void FixChargeRegulation::backward_ions_multival() { double energy_before = energy_stored; double factor = 1; double dummyp[3]; // dummy particle - int mm[salt_charge_ratio + 1]; // particle ID array for all deleted ions - double qq[salt_charge_ratio + 1]; // charge array for all deleted ions - int mask_tmp[salt_charge_ratio + 1]; // temporary mask array + // particle ID array for all deleted ions + auto mm = std::unique_ptr(new int[salt_charge_ratio + 1]); + // charge array for all deleted ions + auto qq = std::unique_ptr(new double[salt_charge_ratio + 1]); + // temporary mask array + auto mask_tmp = std::unique_ptr(new int[salt_charge_ratio + 1]); if (salt_charge[0] <= -salt_charge[1]) { // delete one anion and (salt_charge_ratio) cations From 228711f59bc995199fcd6d7e9302f72745c5f4f9 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 11 May 2021 14:50:32 -0400 Subject: [PATCH 30/32] add GPU device query functions to library interface and its wrappers --- doc/src/Library_config.rst | 12 ++++++++ python/lammps/core.py | 34 +++++++++++++++++++++- src/library.cpp | 58 +++++++++++++++++++++++++++++++++++++- src/library.h | 2 ++ tools/swig/lammps.i | 4 +++ 5 files changed, 108 insertions(+), 2 deletions(-) diff --git a/doc/src/Library_config.rst b/doc/src/Library_config.rst index a5b87e23a7..04b12f35de 100644 --- a/doc/src/Library_config.rst +++ b/doc/src/Library_config.rst @@ -15,6 +15,8 @@ This section documents the following functions: - :cpp:func:`lammps_config_package_count` - :cpp:func:`lammps_config_package_name` - :cpp:func:`lammps_config_accelerator` +- :cpp:func:`lammps_has_gpu_device` +- :cpp:func:`lammps_gpu_device_info` - :cpp:func:`lammps_has_style` - :cpp:func:`lammps_style_count` - :cpp:func:`lammps_style_name` @@ -132,6 +134,16 @@ approach. ----------------------- +.. doxygenfunction:: lammps_has_gpu_device + :project: progguide + +----------------------- + +.. doxygenfunction:: lammps_get_gpu_device_info + :project: progguide + +----------------------- + .. doxygenfunction:: lammps_has_style :project: progguide diff --git a/python/lammps/core.py b/python/lammps/core.py index 8610e85811..6761f9502c 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -281,6 +281,7 @@ class lammps(object): self.lib.lammps_version.argtypes = [c_void_p] self.lib.lammps_get_os_info.argtypes = [c_char_p, c_int] + self.lib.lammps_get_gpu_device_info.argtypes = [c_char_p, c_int] self.lib.lammps_get_mpi_comm.argtypes = [c_void_p] @@ -490,7 +491,7 @@ class lammps(object): sb = create_string_buffer(512) self.lib.lammps_get_os_info(sb,512) - return sb + return sb.value.decode() # ------------------------------------------------------------------------- @@ -1552,6 +1553,37 @@ class lammps(object): # ------------------------------------------------------------------------- + @property + def has_gpu_device(self): + """ Availability of GPU package compatible device + + This is a wrapper around the :cpp:func:`lammps_has_gpu_device` + function of the C library interface. + + :return: True if a GPU package compatible device is present, otherwise False + :rtype: bool + """ + return self.lib.lammps_has_gpu_device() != 0 + + # ------------------------------------------------------------------------- + + def get_gpu_device_info(self): + """Return a string with detailed information about any devices that are + usable by the GPU package. + + This is a wrapper around the :cpp:func:`lammps_get_gpu_device_info` + function of the C-library interface. + + :return: GPU device info string + :rtype: string + """ + + sb = create_string_buffer(8192) + self.lib.lammps_get_gpu_device_info(sb,8192) + return sb.value.decode() + + # ------------------------------------------------------------------------- + @property def installed_packages(self): """ List of the names of enabled packages in the LAMMPS shared library diff --git a/src/library.cpp b/src/library.cpp index 8677b30079..2e2f7a3d0d 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -4111,8 +4111,10 @@ int lammps_version(void *handle) The :cpp:func:`lammps_get_os_info` function can be used to retrieve detailed information about the hosting operating system and compiler/runtime. + A suitable buffer for a C-style string has to be provided and its length. -If the assembled text will be truncated to not overflow this buffer. +The assembled text will be truncated to not overflow this buffer. The +string is typically a few hundred bytes long. .. versionadded:: 9Oct2020 @@ -4339,6 +4341,60 @@ int lammps_config_accelerator(const char *package, return Info::has_accelerator_feature(package,category,setting) ? 1 : 0; } +/** Check for presence of a viable GPU package device + * +\verbatim embed:rst + +The :cpp:func:`lammps_has_gpu_device` function checks at runtime if +an accelerator device is present that can be used with the +:doc:`GPU package `. If at least one suitable device is +present the function will return 1, otherwise 0. + +More detailed information about the available device or devices can +be obtained by calling the +:cpp:func:`lammps_get_gpu_device_info` function. + +.. versionadded:: 14May2021 + +\endverbatim + * + * \return 1 if viable device is available, 0 if not. */ + +int lammps_has_gpu_device() +{ + return Info::has_gpu_device() ? 1: 0; +} + +/** Get GPU package device information + * +\verbatim embed:rst + +The :cpp:func:`lammps_get_gpu_device_info` function can be used to retrieve +detailed information about any accelerator devices that are viable for use +with the :doc:`GPU package `. It will produce a string that is +equivalent to the output of the ``nvc_get_device`` or ``ocl_get_device`` or +``hip_get_device`` tools that are compiled alongside LAMMPS if the GPU +package is enabled. + +A suitable buffer for a C-style string has to be provided and its length. +The assembled text will be truncated to not overflow this buffer. This +string can be several kilobytes long, if multiple devices are present. + +.. versionadded:: 14May2021 + +\endverbatim + * + * \param buffer string buffer to copy the information to + * \param buf_size size of the provided string buffer */ + +void lammps_get_gpu_device_info(char *buffer, int buf_size) +{ + if (buf_size <= 0) return; + buffer[0] = buffer[buf_size-1] = '\0'; + std::string devinfo = Info::get_gpu_device_info(); + strncpy(buffer, devinfo.c_str(), buf_size-1); +} + /* ---------------------------------------------------------------------- */ /** Check if a specific style has been included in LAMMPS diff --git a/src/library.h b/src/library.h index 4cfaf2ce44..a199c86652 100644 --- a/src/library.h +++ b/src/library.h @@ -196,6 +196,8 @@ int lammps_config_package_count(); int lammps_config_package_name(int, char *, int); int lammps_config_accelerator(const char *, const char *, const char *); +int lammps_has_gpu_device(); +void lammps_get_gpu_device_info(char *buffer, int buf_size); int lammps_has_style(void *, const char *, const char *); int lammps_style_count(void *, const char *); diff --git a/tools/swig/lammps.i b/tools/swig/lammps.i index 986fd5cad3..ec37120c07 100644 --- a/tools/swig/lammps.i +++ b/tools/swig/lammps.i @@ -116,6 +116,8 @@ extern int lammps_config_has_package(const char *); extern int lammps_config_package_count(); extern int lammps_config_package_name(int, char *, int); extern int lammps_config_accelerator(const char *, const char *, const char *); +extern int lammps_has_gpu_device(); +extern void lammps_get_gpu_device_info(char *buffer, int buf_size); extern int lammps_has_style(void *, const char *, const char *); extern int lammps_style_count(void *, const char *); extern int lammps_style_name(void *, const char *, int, char *buffer, int buf_size); @@ -236,6 +238,8 @@ extern int lammps_config_has_package(const char *); extern int lammps_config_package_count(); extern int lammps_config_package_name(int, char *, int); extern int lammps_config_accelerator(const char *, const char *, const char *); +extern int lammps_has_gpu_device(); +extern void lammps_get_gpu_device_info(char *buffer, int buf_size); extern int lammps_has_style(void *, const char *, const char *); extern int lammps_style_count(void *, const char *); extern int lammps_style_name(void *, const char *, int, char *buffer, int buf_size); From fbe9240cf3bfc0b640713deb47db2be634ce40ab Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 11 May 2021 15:17:43 -0400 Subject: [PATCH 31/32] add python unit test for GPU capabilities --- unittest/python/python-capabilities.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/unittest/python/python-capabilities.py b/unittest/python/python-capabilities.py index 372eecc869..2c8aa8cdc3 100644 --- a/unittest/python/python-capabilities.py +++ b/unittest/python/python-capabilities.py @@ -158,5 +158,14 @@ class PythonCapabilities(unittest.TestCase): if self.cmake_cache['GPU_PREC'].lower() == 'single': self.assertIn('single',settings['GPU']['precision']) + def test_gpu_device(self): + + info = self.lmp.get_gpu_device_info() + if self.lmp.has_gpu_device: + self.assertTrue(info) + self.assertGreaterEqual(info.find("Device"),0) + else: + self.assertFalse(info) + if __name__ == "__main__": unittest.main() From 8f917b509b229790744d6d6436418e9bc31b4963 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 11 May 2021 15:24:04 -0400 Subject: [PATCH 32/32] add test for querying the operating system info --- unittest/python/python-capabilities.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/unittest/python/python-capabilities.py b/unittest/python/python-capabilities.py index 2c8aa8cdc3..2ace093a7e 100644 --- a/unittest/python/python-capabilities.py +++ b/unittest/python/python-capabilities.py @@ -33,6 +33,13 @@ class PythonCapabilities(unittest.TestCase): def test_version(self): self.assertGreaterEqual(self.lmp.version(), 20200824) + def test_os_info(self): + import platform + + system = platform.system() + osinfo = self.lmp.get_os_info() + self.assertEqual(osinfo.find(system),0) + def test_has_gzip_support(self): self.assertEqual(self.lmp.has_gzip_support, self.cmake_cache['WITH_GZIP'])