Skip to content

Commit 465171d

Browse files
authored
Merge pull request lammps#4514 from akohlmey/library-handle-argument-errors
Improve handling argument errors with library interface functions
2 parents 7878ec1 + d515af2 commit 465171d

File tree

13 files changed

+1104
-665
lines changed

13 files changed

+1104
-665
lines changed

doc/src/Library_utility.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ functions. They do not directly call the LAMMPS library.
2020
- :cpp:func:`lammps_force_timeout`
2121
- :cpp:func:`lammps_has_error`
2222
- :cpp:func:`lammps_get_last_error_message`
23+
- :cpp:func:`lammps_set_show_error`
2324
- :cpp:func:`lammps_python_api_version`
2425

2526
The :cpp:func:`lammps_free` function is a clean-up function to free
@@ -110,6 +111,11 @@ where such memory buffers were allocated that require the use of
110111

111112
-----------------------
112113

114+
.. doxygenfunction:: lammps_set_show_error
115+
:project: progguide
116+
117+
-----------------------
118+
113119
.. doxygenfunction:: lammps_python_api_version
114120
:project: progguide
115121

doc/utils/sphinx-config/false_positives.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,7 @@ dE
736736
De
737737
deallocate
738738
deallocated
739+
deallocation
739740
debye
740741
Debye
741742
Decius

examples/COUPLE/plugin/liblammpsplugin.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ liblammpsplugin_t *liblammpsplugin_load(const char *lib)
204204
ADDSYM(has_error);
205205
ADDSYM(get_last_error_message);
206206
}
207+
ADDSYM(set_show_error);
207208

208209
ADDSYM(python_api_version);
209210
return lmp;

examples/COUPLE/plugin/liblammpsplugin.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ struct _liblammpsplugin {
109109
int abiversion;
110110
int has_exceptions;
111111
void *handle;
112+
112113
#if defined(LAMMPS_LIB_MPI)
113114
void *(*open)(int, char **, MPI_Comm, void **);
114115
#else
@@ -187,7 +188,7 @@ struct _liblammpsplugin {
187188
* the ifdef ensures they are compatible with rest of LAMMPS
188189
* caller must match to how LAMMPS library is built */
189190

190-
#ifndef LAMMPS_BIGBIG
191+
#if !defined(LAMMPS_BIGBIG)
191192
int (*create_atoms)(void *, int, int *, int *, double *, double *, int *, int);
192193
#else
193194
int (*create_atoms)(void *, int, int64_t *, int *, double *, double *, int64_t *, int);
@@ -255,6 +256,7 @@ struct _liblammpsplugin {
255256

256257
int (*has_error)(void *);
257258
int (*get_last_error_message)(void *, char *, int);
259+
int (*set_show_error)(void *, const int);
258260

259261
int (*python_api_version)();
260262
};

fortran/lammps.f90

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ MODULE LIBLAMMPS
248248
PROCEDURE :: force_timeout => lmp_force_timeout
249249
PROCEDURE :: has_error => lmp_has_error
250250
PROCEDURE :: get_last_error_message => lmp_get_last_error_message
251+
PROCEDURE :: set_show_error => lmp_set_show_error
251252
END TYPE lammps
252253

253254
INTERFACE lammps
@@ -1041,6 +1042,13 @@ INTEGER(c_int) FUNCTION lammps_get_last_error_message &
10411042
INTEGER(c_int), VALUE :: buf_size
10421043
END FUNCTION lammps_get_last_error_message
10431044

1045+
INTEGER(c_int) FUNCTION lammps_set_show_error(handle,flag) BIND(C)
1046+
IMPORT :: c_ptr, c_int
1047+
IMPLICIT NONE
1048+
TYPE(c_ptr), VALUE :: handle
1049+
INTEGER(c_int), VALUE :: flag
1050+
END FUNCTION lammps_set_show_error
1051+
10441052
!---------------------------------------------------------------------
10451053
! Utility functions imported for convenience (not in library.h)
10461054
!---------------------------------------------------------------------
@@ -3666,6 +3674,14 @@ SUBROUTINE lmp_get_last_error_message(self, buffer, status)
36663674
END IF
36673675
END SUBROUTINE lmp_get_last_error_message
36683676

3677+
! equivalent function to lammps_set_show_error
3678+
INTEGER FUNCTION lmp_set_show_error(self, flag)
3679+
CLASS(lammps), INTENT(IN) :: self
3680+
INTEGER, INTENT(IN) :: flag
3681+
3682+
lmp_set_show_error = lammps_set_show_error(self%handle, flag)
3683+
END FUNCTION lmp_set_show_error
3684+
36693685
! ----------------------------------------------------------------------
36703686
! functions to assign user-space pointers to LAMMPS data
36713687
! ----------------------------------------------------------------------

python/lammps/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
LMP_VAR_VECTOR = 2
5151
LMP_VAR_STRING = 3
5252

53+
# default buffer size for string buffers
54+
LMP_BUFSIZE = 1024
5355
# -------------------------------------------------------------------------
5456

5557
def get_ctypes_int(size):

python/lammps/core.py

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
LMP_TYPE_SCALAR, LMP_TYPE_VECTOR, LMP_TYPE_ARRAY, \
3030
LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS, \
3131
LMP_VAR_EQUAL, LMP_VAR_ATOM, LMP_VAR_VECTOR, LMP_VAR_STRING, \
32-
get_ctypes_int
32+
LMP_BUFSIZE, get_ctypes_int
3333

3434
from lammps.data import NeighList
3535

@@ -347,6 +347,8 @@ def __init__(self,name='',cmdargs=None,ptr=None,comm=None):
347347

348348
self.lib.lammps_get_last_error_message.argtypes = [c_void_p, c_char_p, c_int]
349349
self.lib.lammps_get_last_error_message.restype = c_int
350+
self.lib.lammps_set_show_error.argtypes = [c_void_p, c_int]
351+
self.lib.lammps_set_show_error.restype = c_int
350352

351353
self.lib.lammps_extract_global.argtypes = [c_void_p, c_char_p]
352354
self.lib.lammps_extract_global_datatype.argtypes = [c_void_p, c_char_p]
@@ -704,8 +706,8 @@ def get_os_info(self):
704706
:rtype: string
705707
"""
706708

707-
sb = create_string_buffer(512)
708-
self.lib.lammps_get_os_info(sb,512)
709+
sb = create_string_buffer(LMP_BUFSIZE)
710+
self.lib.lammps_get_os_info(sb, LMP_BUFSIZE)
709711
return sb.value.decode()
710712

711713
# -------------------------------------------------------------------------
@@ -734,8 +736,8 @@ def get_mpi_comm(self):
734736

735737
@property
736738
def _lammps_exception(self):
737-
sb = create_string_buffer(100)
738-
error_type = self.lib.lammps_get_last_error_message(self.lmp, sb, 100)
739+
sb = create_string_buffer(LMP_BUFSIZE)
740+
error_type = self.lib.lammps_get_last_error_message(self.lmp, sb, LMP_BUFSIZE)
739741
error_msg = sb.value.decode().strip()
740742

741743
if error_type == 2:
@@ -2124,6 +2126,27 @@ def is_running(self):
21242126

21252127
# -------------------------------------------------------------------------
21262128

2129+
def set_show_error(self, flag):
2130+
""" Enable or disable direct printing of error messages in C++ code
2131+
2132+
.. versionadded:: TBD
2133+
2134+
This function allows to enable or disable printing of error message directly in
2135+
the C++ code. Disabling the printing avoids printing error messages twice when
2136+
detecting and re-throwing them in Python code.
2137+
2138+
This is a wrapper around the :cpp:func:`lammps_set_show_error`
2139+
function of the library interface.
2140+
2141+
:param flag: enable (1) or disable (0) printing of error message
2142+
:type flag: int
2143+
:return: previous setting of the flag
2144+
:rtype: int
2145+
"""
2146+
self.lib.lammps_set_show_error(self.lmp, flag)
2147+
2148+
# -------------------------------------------------------------------------
2149+
21272150
def force_timeout(self):
21282151
""" Trigger an immediate timeout, i.e. a "soft stop" of a run.
21292152
@@ -2300,8 +2323,9 @@ def get_gpu_device_info(self):
23002323
:rtype: string
23012324
"""
23022325

2303-
sb = create_string_buffer(8192)
2304-
self.lib.lammps_get_gpu_device_info(sb,8192)
2326+
BUFSIZE = 8192
2327+
sb = create_string_buffer(BUFSIZE)
2328+
self.lib.lammps_get_gpu_device_info(sb, BUFSIZE)
23052329
return sb.value.decode()
23062330

23072331
# -------------------------------------------------------------------------
@@ -2318,9 +2342,9 @@ def installed_packages(self):
23182342
if self._installed_packages is None:
23192343
self._installed_packages = []
23202344
npackages = self.lib.lammps_config_package_count()
2321-
sb = create_string_buffer(100)
2345+
sb = create_string_buffer(LMP_BUFSIZE)
23222346
for idx in range(npackages):
2323-
self.lib.lammps_config_package_name(idx, sb, 100)
2347+
self.lib.lammps_config_package_name(idx, sb, LMP_BUFSIZE)
23242348
self._installed_packages.append(sb.value.decode())
23252349
return self._installed_packages
23262350

@@ -2356,17 +2380,18 @@ def available_styles(self, category):
23562380
:return: list of style names in given category
23572381
:rtype: list
23582382
"""
2383+
BUFSIZE = 8192
23592384
if self._available_styles is None:
23602385
self._available_styles = {}
23612386

23622387
if category not in self._available_styles:
23632388
self._available_styles[category] = []
23642389
with ExceptionCheck(self):
23652390
nstyles = self.lib.lammps_style_count(self.lmp, category.encode())
2366-
sb = create_string_buffer(100)
2391+
sb = create_string_buffer(BUFSIZE)
23672392
for idx in range(nstyles):
23682393
with ExceptionCheck(self):
2369-
self.lib.lammps_style_name(self.lmp, category.encode(), idx, sb, 100)
2394+
self.lib.lammps_style_name(self.lmp, category.encode(), idx, sb, BUFSIZE)
23702395
self._available_styles[category].append(sb.value.decode())
23712396
return self._available_styles[category]
23722397

@@ -2411,9 +2436,9 @@ def available_ids(self, category):
24112436
available_ids = []
24122437
if category in categories:
24132438
num = self.lib.lammps_id_count(self.lmp, category.encode())
2414-
sb = create_string_buffer(100)
2439+
sb = create_string_buffer(LMP_BUFSIZE)
24152440
for idx in range(num):
2416-
self.lib.lammps_id_name(self.lmp, category.encode(), idx, sb, 100)
2441+
self.lib.lammps_id_name(self.lmp, category.encode(), idx, sb, LMP_BUFSIZE)
24172442
available_ids.append(sb.value.decode())
24182443
return available_ids
24192444

@@ -2433,10 +2458,10 @@ def available_plugins(self, category):
24332458

24342459
available_plugins = []
24352460
num = self.lib.lammps_plugin_count(self.lmp)
2436-
sty = create_string_buffer(100)
2437-
nam = create_string_buffer(100)
2461+
sty = create_string_buffer(LMP_BUFSIZE)
2462+
nam = create_string_buffer(LMP_BUFSIZE)
24382463
for idx in range(num):
2439-
self.lib.lammps_plugin_name(idx, sty, nam, 100)
2464+
self.lib.lammps_plugin_name(idx, sty, nam, LMP_BUFSIZE)
24402465
available_plugins.append([sty.value.decode(), nam.value.decode()])
24412466
return available_plugins
24422467

python/setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def has_ext_modules(self):
4444
setup(
4545
name = "lammps",
4646
version = get_lammps_version(),
47+
license = "GPL-2.0-only",
4748
author = "The LAMMPS Developers",
4849
author_email = "[email protected]",
4950
url = "https://www.lammps.org",
@@ -57,11 +58,10 @@ def has_ext_modules(self):
5758
"Programming Language :: Python :: 3",
5859
"Development Status :: 5 - Production/Stable",
5960
"Environment :: Console",
60-
"License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
6161
"Operating System :: OS Independent",
6262
],
63-
license = "GPL",
6463
packages = pkgs,
6564
package_data = pkgdata,
6665
distclass = bdist,
66+
python_requires = '>=3.6',
6767
)

src/error.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static std::string truncpath(const std::string &path)
3535
/* ---------------------------------------------------------------------- */
3636

3737
Error::Error(LAMMPS *lmp)
38-
: Pointers(lmp), numwarn(0), maxwarn(100), allwarn(0)
38+
: Pointers(lmp), numwarn(0), maxwarn(100), allwarn(0), showerror(1)
3939
{
4040
last_error_message.clear();
4141
last_error_type = ERROR_NONE;
@@ -56,7 +56,7 @@ void Error::universe_all(const std::string &file, int line, const std::string &s
5656
} catch (fmt::format_error &) {
5757
; // do nothing
5858
}
59-
if (universe->me == 0) {
59+
if (showerror && (universe->me == 0)) {
6060
if (universe->uscreen) fputs(mesg.c_str(),universe->uscreen);
6161
if (universe->ulogfile) fputs(mesg.c_str(),universe->ulogfile);
6262
}
@@ -84,7 +84,10 @@ void Error::universe_one(const std::string &file, int line, const std::string &s
8484
{
8585
std::string mesg = fmt::format("ERROR on proc {}: {} ({}:{})\n",
8686
universe->me,str,truncpath(file),line);
87-
if (universe->uscreen) fputs(mesg.c_str(),universe->uscreen);
87+
if (showerror) {
88+
if (universe->uscreen) fputs(mesg.c_str(),universe->uscreen);
89+
if (universe->ulogfile) fputs(mesg.c_str(),universe->ulogfile);
90+
}
8891
utils::flush_buffers(lmp);
8992

9093
// allow commands if an exception was caught in a run
@@ -131,7 +134,7 @@ void Error::all(const std::string &file, int line, int failed, const std::string
131134

132135
if (failed > NOLASTLINE) mesg += utils::point_to_error(input, failed);
133136
if (failed == ARGZERO) mesg += utils::point_to_error(input, 0);
134-
if (me == 0) utils::logmesg(lmp,mesg);
137+
if (showerror && (me == 0)) utils::logmesg(lmp,mesg);
135138
utils::flush_buffers(lmp);
136139

137140
// allow commands if an exception was caught in a run
@@ -164,11 +167,12 @@ void Error::one(const std::string &file, int line, int failed, const std::string
164167
std::string mesg = fmt::format("ERROR on proc {}: {} ({}:{})\n", me, str, truncpath(file), line);
165168
if (failed > NOPOINTER) mesg += utils::point_to_error(input, failed);
166169
if (failed == ARGZERO) mesg += utils::point_to_error(input, 0);
167-
utils::logmesg(lmp,mesg);
170+
if (showerror) utils::logmesg(lmp,mesg);
168171

169-
if (universe->nworlds > 1)
170-
if (universe->uscreen)
171-
fputs(mesg.c_str(),universe->uscreen);
172+
if (showerror && (universe->nworlds > 1)) {
173+
if (universe->uscreen) fputs(mesg.c_str(),universe->uscreen);
174+
if (universe->ulogfile) fputs(mesg.c_str(),universe->ulogfile);
175+
}
172176

173177
utils::flush_buffers(lmp);
174178
// allow commands if an exception was caught in a run
@@ -213,8 +217,7 @@ void Error::warning(const std::string &file, int line, const std::string &str)
213217
{
214218
++numwarn;
215219
if ((maxwarn != 0) && ((numwarn > maxwarn) || (allwarn > maxwarn) || (maxwarn < 0))) return;
216-
std::string mesg = fmt::format("WARNING: {} ({}:{})\n",
217-
str,truncpath(file),line);
220+
std::string mesg = fmt::format("WARNING: {} ({}:{})\n", str,truncpath(file),line);
218221
if (screen) fputs(mesg.c_str(),screen);
219222
if (logfile) fputs(mesg.c_str(),logfile);
220223
}
@@ -308,3 +311,16 @@ void Error::set_last_error(const char *msg, ErrorType type)
308311
last_error_message = msg;
309312
last_error_type = type;
310313
}
314+
315+
/* ----------------------------------------------------------------------
316+
enable or disable printing error messages. for use with library interface.
317+
if flag = 0 only last error message and type are updated.
318+
returns the previous setting.
319+
------------------------------------------------------------------------- */
320+
321+
int Error::set_show_error(const int flag)
322+
{
323+
int oldflag = showerror;
324+
showerror = flag;
325+
return oldflag;
326+
}

src/error.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,13 @@ class Error : protected Pointers {
9898
std::string get_last_error() const;
9999
ErrorType get_last_error_type() const;
100100
void set_last_error(const char *msg, ErrorType type = ERROR_NORMAL);
101+
int set_show_error(const int flag);
101102

102103
private:
103104
std::string last_error_message;
104105
ErrorType last_error_type;
105106

106-
int numwarn, maxwarn, allwarn;
107+
int numwarn, maxwarn, allwarn, showerror;
107108
// internal versions that accept explicit fmtlib arguments
108109
[[noreturn]] void _all(const std::string &, int, int, fmt::string_view, fmt::format_args args);
109110
[[noreturn]] void _one(const std::string &, int, int, fmt::string_view, fmt::format_args args);

0 commit comments

Comments
 (0)