Merge branch 'master' into smooth-gpu

This commit is contained in:
Axel Kohlmeyer 2021-05-11 23:59:14 -04:00
commit 5591b0f33d
No known key found for this signature in database
GPG Key ID: D9B44E93BF0C375A
34 changed files with 426 additions and 218 deletions

1
.gitattributes vendored
View File

@ -1,3 +1,4 @@
.gitattributes export-ignore
.gitignore export-ignore
.github export-ignore
.lgtm.yml export-ignore

4
.github/codeql/cpp.yml vendored Normal file
View File

@ -0,0 +1,4 @@
paths:
- src
- lib
- tools

5
.github/codeql/python.yml vendored Normal file
View File

@ -0,0 +1,5 @@
paths:
- python/lammps
queries:
- uses: security-and-quality

View File

@ -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

14
.lgtm.yml Normal file
View File

@ -0,0 +1,14 @@
extraction:
cpp:
configure:
command:
- "mkdir build"
- "cd build"
- "cmake -G Ninja -C ../cmake/presets/minimal.cmake ../cmake"
index:
build_command:
- "cd build"
- "ninja"
python:
python_setup:
version: 3

View File

@ -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

View File

@ -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]

View File

@ -18,6 +18,7 @@
#include <map>
#include <cmath>
#include <cstdlib>
#include <iostream>
#if (LAL_USE_OMP == 1)
#include <omp.h>
#endif
@ -1026,6 +1027,22 @@ Device<PRECISION,ACC_PRECISION> global_device;
}
using namespace LAMMPS_AL;
bool lmp_has_gpu_device()
{
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,
const int first_gpu_id, const int gpu_mode,
const double particle_split, const int t_per_atom,

View File

@ -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)
subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)

View File

@ -28,12 +28,17 @@ def get_version_number():
from importlib.metadata import version
try:
vstring = version('lammps')
except: pass
except:
# nothing to do, ignore
pass
else:
from pkg_resources import get_distribution
try:
vstring = get_distribution('lammps').version
except: pass
except:
# nothing to do, ignore
pass
if not vstring:
return 0

View File

@ -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
@ -284,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]
@ -310,6 +308,7 @@ class lammps(object):
# tested to work with mpi4py versions 2 and 3
self.has_mpi4py = mpi4py_version.split('.')[0] in ['2','3']
except:
# ignore failing import
pass
# if no ptr provided, create an instance of LAMMPS
@ -418,9 +417,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()
# -------------------------------------------------------------------------
@ -447,7 +453,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
@ -456,9 +463,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()
# -------------------------------------------------------------------------
@ -486,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()
# -------------------------------------------------------------------------
@ -779,6 +784,9 @@ class lammps(object):
target_type = float
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:
@ -878,71 +886,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 <py_style_constants>`
and :ref:`type <py_type_constants>` constants is used. The
recognized, or an invalid combination of :ref:`cstyle <py_style_constants>`
and :ref:`ctype <py_type_constants>` 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 +960,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 <py_style_constants>`
and :ref:`type <py_type_constants>` constants is used. The
recognized, or an invalid combination of :ref:`fstyle <py_style_constants>`
and :ref:`ftype <py_type_constants>` 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 +987,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]
@ -1114,20 +1122,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:
@ -1136,29 +1144,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
@ -1174,17 +1182,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
@ -1194,43 +1202,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
@ -1244,15 +1252,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)
# -------------------------------------------------------------------------
@ -1545,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

View File

@ -16,7 +16,7 @@
# Written by Richard Berger <richard.berger@temple.edu>
################################################################################
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:

View File

@ -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])):

View File

@ -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() <lammps.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

View File

@ -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
@ -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

View File

@ -133,13 +133,12 @@ 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
// Repeated cutsq calculation in init_one() is required for GPU package
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);
init_one(i,j);
}
}

View File

@ -42,6 +42,7 @@
#include <cmath>
#include <cstring>
#include <memory>
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<int[]>(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<int[]>(new int[salt_charge_ratio + 1]);
// charge array for all deleted ions
auto qq = std::unique_ptr<double[]>(new double[salt_charge_ratio + 1]);
// temporary mask array
auto mask_tmp = std::unique_ptr<int[]>(new int[salt_charge_ratio + 1]);
if (salt_charge[0] <= -salt_charge[1]) {
// delete one anion and (salt_charge_ratio) cations

View File

@ -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

View File

@ -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;
}
/* ---------------------------------------------------------------------- */

View File

@ -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

View File

@ -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;

View File

@ -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"

View File

@ -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;

View File

@ -16,21 +16,23 @@
------------------------------------------------------------------------- */
#include "fix_deform.h"
#include <cstring>
#include <cmath>
#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 <cmath>
#include <cstring>
using namespace LAMMPS_NS;
using namespace FixConst;

View File

@ -42,11 +42,11 @@
#include "text_file_reader.h"
#include "update.h"
#include "variable.h"
#include "fmt/chrono.h"
#include <cctype>
#include <cmath>
#include <cstring>
#include <ctime>
#include <map>
#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",
@ -320,6 +320,8 @@ void Info::command(int narg, char **arg)
if (flags & ACCELERATOR) {
fmt::print(out,"\nAccelerator configuration:\n\n{}",
get_accelerator_info());
if (Info::has_gpu_device())
fmt::print(out,"\nAvailable GPU devices:\n{}\n",get_gpu_device_info());
}
if (flags & MEMORY) {
@ -1139,6 +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_gpu_device();
extern std::string lmp_gpu_device_info();
bool Info::has_gpu_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)

View File

@ -47,6 +47,8 @@ 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_gpu_device_info();
static std::string get_os_info();
static std::string get_compiler_info();

View File

@ -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);

View File

@ -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 <Speed_gpu>`. 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 <Speed_gpu>`. 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

View File

@ -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 *);

View File

@ -15,6 +15,7 @@
#include "comm.h"
#include "error.h"
#include "fmt/chrono.h"
#include <cstring>
@ -26,8 +27,6 @@
#include <sys/resource.h>
#endif
#include <ctime>
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);
}
}

View File

@ -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);

View File

@ -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"};

View File

@ -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'])
@ -158,5 +165,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()

View File

@ -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
@ -78,7 +88,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"):