From 06275b03c06f3615d6442ef9243a41ffecbcae19 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 17 Jul 2019 15:46:39 -0400 Subject: [PATCH 01/11] refactor FFT handling in CMake module for KSPACE. This also improves the FFT info output in the PPPM styles --- cmake/CMakeLists.txt | 7 ++++++- cmake/Modules/Packages/KSPACE.cmake | 28 ++++++++++++++++------------ src/KOKKOS/pppm_kokkos.cpp | 10 ++-------- src/KSPACE/pppm.cpp | 10 ++-------- src/KSPACE/pppm.h | 11 +++++++++++ src/KSPACE/pppm_disp.cpp | 10 ++-------- src/KSPACE/pppm_disp.h | 10 ++++++++++ 7 files changed, 49 insertions(+), 37 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index bde36aa896..4b528f280e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -673,5 +673,10 @@ if(PKG_KOKKOS) message(STATUS "Kokkos Arch: ${KOKKOS_ARCH}") endif() if(PKG_KSPACE) - message(STATUS "Using ${FFT} as FFT") + message(STATUS "Using ${FFT} as primary FFT library") + if(FFT_SINGLE) + message(STATUS "Using single precision FFTs") + else() + message(STATUS "Using double precision FFTs") + endif() endif() diff --git a/cmake/Modules/Packages/KSPACE.cmake b/cmake/Modules/Packages/KSPACE.cmake index 6938a93a36..63c42baf2d 100644 --- a/cmake/Modules/Packages/KSPACE.cmake +++ b/cmake/Modules/Packages/KSPACE.cmake @@ -1,5 +1,5 @@ if(PKG_KSPACE) - option(FFT_SINGLE "Use single precision FFT instead of double" OFF) + option(FFT_SINGLE "Use single precision FFTs instead of double precision FFTs" OFF) set(FFTW "FFTW3") if(FFT_SINGLE) set(FFTW "FFTW3F") @@ -7,26 +7,30 @@ if(PKG_KSPACE) endif() find_package(${FFTW} QUIET) if(${FFTW}_FOUND) - set(FFT "${FFTW}" CACHE STRING "FFT library for KSPACE package") + set(FFT "FFTW3" CACHE STRING "FFT library for KSPACE package") else() set(FFT "KISS" CACHE STRING "FFT library for KSPACE package") endif() - set(FFT_VALUES KISS ${FFTW} MKL) + set(FFT_VALUES KISS FFTW3 MKL) set_property(CACHE FFT PROPERTY STRINGS ${FFT_VALUES}) validate_option(FFT FFT_VALUES) string(TOUPPER ${FFT} FFT) - if(NOT FFT STREQUAL "KISS") - find_package(${FFT} REQUIRED) - if(NOT FFT STREQUAL "FFTW3F") - add_definitions(-DFFT_FFTW) - else() - add_definitions(-DFFT_${FFT}) - endif() - include_directories(${${FFT}_INCLUDE_DIRS}) - list(APPEND LAMMPS_LINK_LIBS ${${FFT}_LIBRARIES}) + + if(FFT STREQUAL "FFTW3") + find_package(${FFTW} REQUIRED) + add_definitions(-DFFT_FFTW3) + include_directories(${${FFTW}_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${${FFTW}_LIBRARIES}) + elseif(FFT STREQUAL "MKL") + find_package(MKL REQUIRED) + add_definitions(-DFFT_MKL) + include_directories(${MKL_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${MKL_LIBRARIES}) else() + # last option is KISSFFT add_definitions(-DFFT_KISS) endif() + set(FFT_PACK "array" CACHE STRING "Optimization for FFT") set(FFT_PACK_VALUES array pointer memcpy) set_property(CACHE FFT_PACK PROPERTY STRINGS ${FFT_PACK_VALUES}) diff --git a/src/KOKKOS/pppm_kokkos.cpp b/src/KOKKOS/pppm_kokkos.cpp index 7c01adc510..c9c0d6d1d4 100644 --- a/src/KOKKOS/pppm_kokkos.cpp +++ b/src/KOKKOS/pppm_kokkos.cpp @@ -306,12 +306,6 @@ void PPPMKokkos::init() if (me == 0) { -#ifdef FFT_SINGLE - const char fft_prec[] = "single"; -#else - const char fft_prec[] = "double"; -#endif - if (screen) { fprintf(screen," G vector (1/distance) = %g\n",g_ewald); fprintf(screen," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm); @@ -320,7 +314,7 @@ void PPPMKokkos::init() estimated_accuracy); fprintf(screen," estimated relative force accuracy = %g\n", estimated_accuracy/two_charge_force); - fprintf(screen," using %s precision FFTs\n",fft_prec); + fprintf(screen," using " LMP_FFT_PREC " precision " LMP_FFT_LIB "\n"); fprintf(screen," 3d grid and FFT values/proc = %d %d\n", ngrid_max,nfft_both_max); } @@ -332,7 +326,7 @@ void PPPMKokkos::init() estimated_accuracy); fprintf(logfile," estimated relative force accuracy = %g\n", estimated_accuracy/two_charge_force); - fprintf(logfile," using %s precision FFTs\n",fft_prec); + fprintf(logfile," using " LMP_FFT_PREC " precision " LMP_FFT_LIB "\n"); fprintf(logfile," 3d grid and FFT values/proc = %d %d\n", ngrid_max,nfft_both_max); } diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp index 53c18804a5..1abb19e947 100644 --- a/src/KSPACE/pppm.cpp +++ b/src/KSPACE/pppm.cpp @@ -350,12 +350,6 @@ void PPPM::init() if (me == 0) { -#ifdef FFT_SINGLE - const char fft_prec[] = "single"; -#else - const char fft_prec[] = "double"; -#endif - if (screen) { fprintf(screen," G vector (1/distance) = %g\n",g_ewald); fprintf(screen," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm); @@ -364,7 +358,7 @@ void PPPM::init() estimated_accuracy); fprintf(screen," estimated relative force accuracy = %g\n", estimated_accuracy/two_charge_force); - fprintf(screen," using %s precision FFTs\n",fft_prec); + fprintf(screen," using " LMP_FFT_PREC " precision " LMP_FFT_LIB "\n"); fprintf(screen," 3d grid and FFT values/proc = %d %d\n", ngrid_max,nfft_both_max); } @@ -376,7 +370,7 @@ void PPPM::init() estimated_accuracy); fprintf(logfile," estimated relative force accuracy = %g\n", estimated_accuracy/two_charge_force); - fprintf(logfile," using %s precision FFTs\n",fft_prec); + fprintf(logfile," using " LMP_FFT_PREC " precision " LMP_FFT_LIB "\n"); fprintf(logfile," 3d grid and FFT values/proc = %d %d\n", ngrid_max,nfft_both_max); } diff --git a/src/KSPACE/pppm.h b/src/KSPACE/pppm.h index 1ce1a0d666..6426b9c22d 100644 --- a/src/KSPACE/pppm.h +++ b/src/KSPACE/pppm.h @@ -23,11 +23,22 @@ KSpaceStyle(pppm,PPPM) #include "lmptype.h" #include +#if defined(FFT_FFTW3) +#define LMP_FFT_LIB "FFTW3" +#elif defined(FFT_MKL) +#define LMP_FFT_LIB "MKL FFT" +#else +#define LMP_FFT_LIB "KISS FFT" +#endif + #ifdef FFT_SINGLE typedef float FFT_SCALAR; +#define LMP_FFT_PREC "single" #define MPI_FFT_SCALAR MPI_FLOAT #else + typedef double FFT_SCALAR; +#define LMP_FFT_PREC "double" #define MPI_FFT_SCALAR MPI_DOUBLE #endif diff --git a/src/KSPACE/pppm_disp.cpp b/src/KSPACE/pppm_disp.cpp index 45dce0895b..ba0e85bbba 100644 --- a/src/KSPACE/pppm_disp.cpp +++ b/src/KSPACE/pppm_disp.cpp @@ -474,12 +474,6 @@ void PPPMDisp::init() MPI_Allreduce(&nfft_both,&nfft_both_max,1,MPI_INT,MPI_MAX,world); if (me == 0) { - #ifdef FFT_SINGLE - const char fft_prec[] = "single"; - #else - const char fft_prec[] = "double"; - #endif - if (screen) { fprintf(screen," Coulomb G vector (1/distance)= %g\n",g_ewald); fprintf(screen," Coulomb grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm); @@ -488,7 +482,7 @@ void PPPMDisp::init() acc); fprintf(screen," Coulomb estimated relative force accuracy = %g\n", acc/two_charge_force); - fprintf(screen," using %s precision FFTs\n",fft_prec); + fprintf(screen," using " LMP_FFT_PREC " precision " LMP_FFT_LIB "\n"); fprintf(screen," 3d grid and FFT values/proc = %d %d\n", ngrid_max, nfft_both_max); } @@ -501,7 +495,7 @@ void PPPMDisp::init() acc); fprintf(logfile," Coulomb estimated relative force accuracy = %g\n", acc/two_charge_force); - fprintf(logfile," using %s precision FFTs\n",fft_prec); + fprintf(logfile," using " LMP_FFT_PREC " precision " LMP_FFT_LIB "\n"); fprintf(logfile," 3d grid and FFT values/proc = %d %d\n", ngrid_max, nfft_both_max); } diff --git a/src/KSPACE/pppm_disp.h b/src/KSPACE/pppm_disp.h index ccbeb60f3c..8674669274 100644 --- a/src/KSPACE/pppm_disp.h +++ b/src/KSPACE/pppm_disp.h @@ -23,11 +23,21 @@ KSpaceStyle(pppm/disp,PPPMDisp) #include "lmptype.h" #include +#if defined(FFT_FFTW3) +#define LMP_FFT_LIB "FFTW3" +#elif defined(FFT_MKL) +#define LMP_FFT_LIB "MKL FFT" +#else +#define LMP_FFT_LIB "KISS FFT" +#endif + #ifdef FFT_SINGLE typedef float FFT_SCALAR; +#define LMP_FFT_PREC "single" #define MPI_FFT_SCALAR MPI_FLOAT #else typedef double FFT_SCALAR; +#define LMP_FFT_PREC "double" #define MPI_FFT_SCALAR MPI_DOUBLE #endif From bcf600d7814df4eefe4b73d3de7ac344a8decc16 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 17 Jul 2019 15:47:28 -0400 Subject: [PATCH 02/11] let CMake configuration default to Release with debug settings this way we can more easily get detailed stack traces from people compiling with CMake --- cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 4b528f280e..0f99cc6274 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -37,7 +37,7 @@ include(PreventInSourceBuilds) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS) #release comes with -O3 by default - set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) + set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) endif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS) string(TOUPPER "${CMAKE_BUILD_TYPE}" BTYPE) From 02b0fb454f7adbb412ea3d2fd7d324ff5004446b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 17 Jul 2019 16:34:43 -0400 Subject: [PATCH 03/11] include rmass[] in border communication. will otherwise trigger issues with fix shake. --- src/PERI/atom_vec_peri.cpp | 11 ++++++++++- src/atom_vec_ellipsoid.cpp | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/PERI/atom_vec_peri.cpp b/src/PERI/atom_vec_peri.cpp index 64ce323a3f..c4fa0bd43b 100644 --- a/src/PERI/atom_vec_peri.cpp +++ b/src/PERI/atom_vec_peri.cpp @@ -55,7 +55,7 @@ AtomVecPeri::AtomVecPeri(LAMMPS *lmp) : AtomVec(lmp) comm_f_only = 1; size_forward = 4; size_reverse = 3; - size_border = 11; + size_border = 12; size_velocity = 3; size_data_atom = 7; size_data_vel = 4; @@ -357,6 +357,7 @@ int AtomVecPeri::pack_border(int n, int *list, double *buf, buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; buf[m++] = vfrac[j]; + buf[m++] = rmass[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; @@ -381,6 +382,7 @@ int AtomVecPeri::pack_border(int n, int *list, double *buf, buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; buf[m++] = vfrac[j]; + buf[m++] = rmass[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; @@ -414,6 +416,7 @@ int AtomVecPeri::pack_border_vel(int n, int *list, double *buf, buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; buf[m++] = vfrac[j]; + buf[m++] = rmass[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; @@ -442,6 +445,7 @@ int AtomVecPeri::pack_border_vel(int n, int *list, double *buf, buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; buf[m++] = vfrac[j]; + buf[m++] = rmass[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; @@ -463,6 +467,7 @@ int AtomVecPeri::pack_border_vel(int n, int *list, double *buf, buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; buf[m++] = vfrac[j]; + buf[m++] = rmass[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; @@ -497,6 +502,7 @@ int AtomVecPeri::pack_border_hybrid(int n, int *list, double *buf) for (i = 0; i < n; i++) { j = list[i]; buf[m++] = vfrac[j]; + buf[m++] = rmass[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; @@ -522,6 +528,7 @@ void AtomVecPeri::unpack_border(int n, int first, double *buf) type[i] = (int) ubuf(buf[m++]).i; mask[i] = (int) ubuf(buf[m++]).i; vfrac[i] = buf[m++]; + rmass[i] = buf[m++]; s0[i] = buf[m++]; x0[i][0] = buf[m++]; x0[i][1] = buf[m++]; @@ -551,6 +558,7 @@ void AtomVecPeri::unpack_border_vel(int n, int first, double *buf) type[i] = (int) ubuf(buf[m++]).i; mask[i] = (int) ubuf(buf[m++]).i; vfrac[i] = buf[m++]; + rmass[i] = buf[m++]; s0[i] = buf[m++]; x0[i][0] = buf[m++]; x0[i][1] = buf[m++]; @@ -576,6 +584,7 @@ int AtomVecPeri::unpack_border_hybrid(int n, int first, double *buf) last = first + n; for (i = first; i < last; i++) { vfrac[i] = buf[m++]; + rmass[i] = buf[m++]; s0[i] = buf[m++]; x0[i][0] = buf[m++]; x0[i][1] = buf[m++]; diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp index 455e4f192f..7bb29bd6bc 100644 --- a/src/atom_vec_ellipsoid.cpp +++ b/src/atom_vec_ellipsoid.cpp @@ -41,7 +41,7 @@ AtomVecEllipsoid::AtomVecEllipsoid(LAMMPS *lmp) : AtomVec(lmp) comm_x_only = comm_f_only = 0; size_forward = 7; size_reverse = 6; - size_border = 14; + size_border = 15; size_velocity = 6; size_data_atom = 7; size_data_vel = 7; @@ -544,6 +544,7 @@ int AtomVecEllipsoid::pack_border(int n, int *list, double *buf, buf[m++] = ubuf(tag[j]).d; buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; + buf[m++] = rmass[j]; if (ellipsoid[j] < 0) buf[m++] = ubuf(0).d; else { buf[m++] = ubuf(1).d; @@ -576,6 +577,7 @@ int AtomVecEllipsoid::pack_border(int n, int *list, double *buf, buf[m++] = ubuf(tag[j]).d; buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; + buf[m++] = rmass[j]; if (ellipsoid[j] < 0) buf[m++] = ubuf(0).d; else { buf[m++] = ubuf(1).d; @@ -618,6 +620,7 @@ int AtomVecEllipsoid::pack_border_vel(int n, int *list, double *buf, buf[m++] = ubuf(tag[j]).d; buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; + buf[m++] = rmass[j]; if (ellipsoid[j] < 0) buf[m++] = ubuf(0).d; else { buf[m++] = ubuf(1).d; @@ -657,6 +660,7 @@ int AtomVecEllipsoid::pack_border_vel(int n, int *list, double *buf, buf[m++] = ubuf(tag[j]).d; buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; + buf[m++] = rmass[j]; if (ellipsoid[j] < 0) buf[m++] = ubuf(0).d; else { buf[m++] = ubuf(1).d; @@ -689,6 +693,7 @@ int AtomVecEllipsoid::pack_border_vel(int n, int *list, double *buf, buf[m++] = ubuf(tag[j]).d; buf[m++] = ubuf(type[j]).d; buf[m++] = ubuf(mask[j]).d; + buf[m++] = rmass[j]; if (ellipsoid[j] < 0) buf[m++] = ubuf(0).d; else { buf[m++] = ubuf(1).d; @@ -735,6 +740,7 @@ int AtomVecEllipsoid::pack_border_hybrid(int n, int *list, double *buf) m = 0; for (i = 0; i < n; i++) { j = list[i]; + buf[m++] = rmass[j]; if (ellipsoid[j] < 0) buf[m++] = ubuf(0).d; else { buf[m++] = ubuf(1).d; @@ -769,6 +775,7 @@ void AtomVecEllipsoid::unpack_border(int n, int first, double *buf) tag[i] = (tagint) ubuf(buf[m++]).i; type[i] = (int) ubuf(buf[m++]).i; mask[i] = (int) ubuf(buf[m++]).i; + rmass[i] = buf[m++]; ellipsoid[i] = (int) ubuf(buf[m++]).i; if (ellipsoid[i] == 0) ellipsoid[i] = -1; else { @@ -812,6 +819,7 @@ void AtomVecEllipsoid::unpack_border_vel(int n, int first, double *buf) tag[i] = (tagint) ubuf(buf[m++]).i; type[i] = (int) ubuf(buf[m++]).i; mask[i] = (int) ubuf(buf[m++]).i; + rmass[i] = buf[m++]; ellipsoid[i] = (int) ubuf(buf[m++]).i; if (ellipsoid[i] == 0) ellipsoid[i] = -1; else { @@ -854,6 +862,7 @@ int AtomVecEllipsoid::unpack_border_hybrid(int n, int first, double *buf) m = 0; last = first + n; for (i = first; i < last; i++) { + rmass[i] = buf[m++]; ellipsoid[i] = (int) ubuf(buf[m++]).i; if (ellipsoid[i] == 0) ellipsoid[i] = -1; else { From 856efa28aab9a140f37875a7ed5df96419280ad0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 17 Jul 2019 19:37:08 -0400 Subject: [PATCH 04/11] fix issue #1568 --- src/utils.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils.cpp b/src/utils.cpp index bbda22f24c..34e6e6fae6 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -13,6 +13,7 @@ #include #include +#include #include "utils.h" #include "lammps.h" #include "error.h" From 4c328bf846a2f0543f06e2bae0c7ec62411d5b4d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 19 Jul 2019 10:39:06 -0400 Subject: [PATCH 05/11] add metachars '\i' and '\f' to regexp for interger and floating point number chars --- src/utils.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/utils.cpp b/src/utils.cpp index bbda22f24c..a27a53e600 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -39,6 +39,10 @@ * '\W' Non-alphanumeric * '\d' Digits, [0-9] * '\D' Non-digits + * '\i' Integer chars, [0-9], '+' and '-' + * '\I' Non-integers + * '\f' Floating point number chars, [0-9], '.', 'e', 'E', '+' and '-' + * '\F' Non-floats * * *NOT* supported: * '[^abc]' Inverted class @@ -307,6 +311,7 @@ extern "C" { enum { UNUSED, DOT, BEGIN, END, QUESTIONMARK, STAR, PLUS, CHAR, CHAR_CLASS, INV_CHAR_CLASS, DIGIT, NOT_DIGIT, + INTEGER, NOT_INTEGER, FLOAT, NOT_FLOAT, ALPHA, NOT_ALPHA, WHITESPACE, NOT_WHITESPACE /*, BRANCH */ }; typedef struct regex_t { @@ -324,6 +329,8 @@ extern "C" { static int matchplus(regex_t p, regex_t *pattern, const char *text); static int matchone(regex_t p, char c); static int matchdigit(char c); + static int matchint(char c); + static int matchfloat(char c); static int matchalpha(char c); static int matchwhitespace(char c); static int matchmetachar(char c, const char *str); @@ -395,6 +402,10 @@ extern "C" { /* Meta-character: */ case 'd': { re_compiled[j].type = DIGIT; } break; case 'D': { re_compiled[j].type = NOT_DIGIT; } break; + case 'i': { re_compiled[j].type = INTEGER; } break; + case 'I': { re_compiled[j].type = NOT_INTEGER; } break; + case 'f': { re_compiled[j].type = FLOAT; } break; + case 'F': { re_compiled[j].type = NOT_FLOAT; } break; case 'w': { re_compiled[j].type = ALPHA; } break; case 'W': { re_compiled[j].type = NOT_ALPHA; } break; case 's': { re_compiled[j].type = WHITESPACE; } break; @@ -467,6 +478,16 @@ extern "C" { return ((c >= '0') && (c <= '9')); } + static int matchint(char c) + { + return (matchdigit(c) || (c == '-') || (c == '+')); + } + + static int matchfloat(char c) + { + return (matchint(c) || (c == '.') || (c == 'e') || (c == 'E')); + } + static int matchalpha(char c) { return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); @@ -502,6 +523,10 @@ extern "C" { switch (str[0]) { case 'd': return matchdigit(c); case 'D': return !matchdigit(c); + case 'i': return matchint(c); + case 'I': return !matchint(c); + case 'f': return matchfloat(c); + case 'F': return !matchfloat(c); case 'w': return matchalphanum(c); case 'W': return !matchalphanum(c); case 's': return matchwhitespace(c); @@ -544,6 +569,10 @@ extern "C" { case INV_CHAR_CLASS: return !matchcharclass(c, (const char *)p.ccl); case DIGIT: return matchdigit(c); case NOT_DIGIT: return !matchdigit(c); + case INTEGER: return matchint(c); + case NOT_INTEGER: return !matchint(c); + case FLOAT: return matchfloat(c); + case NOT_FLOAT: return !matchfloat(c); case ALPHA: return matchalphanum(c); case NOT_ALPHA: return !matchalphanum(c); case WHITESPACE: return matchwhitespace(c); From 4f7c95d87e77f880415405910f3e06c4b70b1ca6 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Fri, 19 Jul 2019 17:13:38 +0200 Subject: [PATCH 06/11] Update compute.txt Addition of a few one-liners --- doc/src/compute.txt | 89 ++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/doc/src/compute.txt b/doc/src/compute.txt index 87dbee57d6..53ed373aa5 100644 --- a/doc/src/compute.txt +++ b/doc/src/compute.txt @@ -171,42 +171,40 @@ The individual style names on the "Commands compute"_Commands_compute.html doc page are followed by one or more of (g,i,k,o,t) to indicate which accelerated styles exist. -"ackland/atom"_compute_ackland_atom.html - +"ackland/atom"_compute_ackland_atom.html - determines the local lattice structure based on the Ackland formulation "adf"_compute_adf.html - angular distribution function of triples of atoms "aggregate/atom"_compute_cluster_atom.html - aggregate ID for each atom -"angle"_compute_angle.html - -"angle/local"_compute_angle_local.html - -"angle/local"_compute_bond_local.html - theta and energy of each angle +"angle"_compute_angle.html - energy of each angle sub-style +"angle/local"_compute_angle_local.html - theta and energy of each angle "angmom/chunk"_compute_angmom_chunk.html - angular momentum for each chunk -"basal/atom"_compute_basal_atom.html - +"basal/atom"_compute_basal_atom.html - calculates the hexagonal close-packed ā€œcā€ lattice vector of each atom "body/local"_compute_body_local.html - attributes of body sub-particles -"bond"_compute_bond.html - values computed by a bond style +"bond"_compute_bond.html - energy of each bond sub-style "bond/local"_compute_bond_local.html - distance and energy of each bond "centro/atom"_compute_centro_atom.html - centro-symmetry parameter for each atom "chunk/atom"_compute_chunk_atom.html - assign chunk IDs to each atom "chunk/spread/atom"_compute_chunk_spread_atom.html - spreads chunk values to each atom in chunk "cluster/atom"_compute_cluster_atom.html - cluster ID for each atom "cna/atom"_compute_cna_atom.html - common neighbor analysis (CNA) for each atom -"cnp/atom"_compute_cnp_atom.html - +"cnp/atom"_compute_cnp_atom.html - common neighborhood parameter (CNP) for each atom "com"_compute_com.html - center-of-mass of group of atoms "com/chunk"_compute_com_chunk.html - center-of-mass for each chunk "contact/atom"_compute_contact_atom.html - contact count for each spherical particle "coord/atom"_compute_coord_atom.html - coordination number for each atom "damage/atom"_compute_damage_atom.html - Peridynamic damage for each atom -"dihedral"_compute_dihedral.html - +"dihedral"_compute_dihedral.html - energy of each dihedral sub-style "dihedral/local"_compute_dihedral_local.html - angle of each dihedral "dilatation/atom"_compute_dilatation_atom.html - Peridynamic dilatation for each atom -"dipole/chunk"_compute_dipole_chunk.html - +"dipole/chunk"_compute_dipole_chunk.html - dipole vector and total dipole for each chunk "displace/atom"_compute_displace_atom.html - displacement of each atom "dpd"_compute_dpd.html - "dpd/atom"_compute_dpd_atom.html - -"edpd/temp/atom"_compute_edpd_temp_atom.html - -"entropy/atom"_compute_entropy_atom.html - +"edpd/temp/atom"_compute_edpd_temp_atom.html - per-atom temperature for each eDPD particle in a group +"entropy/atom"_compute_entropy_atom.html - pair entropy fingerprint of each atom "erotate/asphere"_compute_erotate_asphere.html - rotational energy of aspherical particles "erotate/rigid"_compute_erotate_rigid.html - rotational energy of rigid bodies "erotate/sphere"_compute_erotate_sphere.html - rotational energy of spherical particles -"erotate/sphere/atom"_compute_erotate_sphere.html - rotational energy for each spherical particle -"erotate/sphere/atom"_compute_erotate_sphere_atom.html - +"erotate/sphere/atom"_compute_erotate_sphere_atom.html - rotational energy for each spherical particle "event/displace"_compute_event_displace.html - detect event on atom displacement "fep"_compute_fep.html - "force/tally"_compute_tally.html - @@ -218,17 +216,17 @@ compute"_Commands_compute.html doc page are followed by one or more of "heat/flux"_compute_heat_flux.html - heat flux through a group of atoms "heat/flux/tally"_compute_tally.html - "hexorder/atom"_compute_hexorder_atom.html - bond orientational order parameter q6 -"improper"_compute_improper.html - +"improper"_compute_improper.html - energy of each improper sub-style "improper/local"_compute_improper_local.html - angle of each improper "inertia/chunk"_compute_inertia_chunk.html - inertia tensor for each chunk "ke"_compute_ke.html - translational kinetic energy "ke/atom"_compute_ke_atom.html - kinetic energy for each atom -"ke/atom/eff"_compute_ke_atom_eff.html - -"ke/eff"_compute_ke_eff.html - +"ke/atom/eff"_compute_ke_atom_eff.html - per-atom translational and radial kinetic energy in the electron force field model +"ke/eff"_compute_ke_eff.html - kinetic energy of a group of nuclei and electrons in the electron force field model "ke/rigid"_compute_ke_rigid.html - translational kinetic energy of rigid bodies -"meso/e/atom"_compute_meso_e_atom.html - -"meso/rho/atom"_compute_meso_rho_atom.html - -"meso/t/atom"_compute_meso_t_atom.html - +"meso/e/atom"_compute_meso_e_atom.html - per-atom internal energy of Smooth-Particle Hydrodynamics atoms +"meso/rho/atom"_compute_meso_rho_atom.html - per-atom mesoscopic density of Smooth-Particle Hydrodynamics atoms +"meso/t/atom"_compute_meso_t_atom.html - per-atom internal temperature of Smooth-Particle Hydrodynamics atoms "msd"_compute_msd.html - mean-squared displacement of group of atoms "msd/chunk"_compute_msd_chunk.html - mean-squared displacement for each chunk "msd/nongauss"_compute_msd_nongauss.html - MSD and non-Gaussian parameter of group of atoms @@ -242,73 +240,72 @@ compute"_Commands_compute.html doc page are followed by one or more of "pe/tally"_compute_tally.html - "plasticity/atom"_compute_plasticity_atom.html - Peridynamic plasticity for each atom "pressure"_compute_pressure.html - total pressure and pressure tensor -"pressure/cylinder"_compute_pressure_cylinder.html - -"pressure/uef"_compute_pressure_uef.html - +"pressure/cylinder"_compute_pressure_cylinder.html - pressure tensor in cylindrical coordinates +"pressure/uef"_compute_pressure_uef.html - pressure tensor in the reference frame of an applied flow field "property/atom"_compute_property_atom.html - convert atom attributes to per-atom vectors/arrays "property/chunk"_compute_property_chunk.html - extract various per-chunk attributes "property/local"_compute_property_local.html - convert local attributes to localvectors/arrays -"ptm/atom"_compute_ptm_atom.html - +"ptm/atom"_compute_ptm_atom.html - determines the local lattice structure based on the Polyhedral Template Matching method "rdf"_compute_rdf.html - radial distribution function g(r) histogram of group of atoms "reduce"_compute_reduce.html - combine per-atom quantities into a single global value "reduce/chunk"_compute_reduce_chunk.html - reduce per-atom quantities within each chunk "reduce/region"_compute_reduce.html - same as compute reduce, within a region "rigid/local"_compute_rigid_local.html - extract rigid body attributes -"saed"_compute_saed.html - +"saed"_compute_saed.html - electron diffraction intensity on a mesh of reciprocal lattice nodes "slice"_compute_slice.html - extract values from global vector or array "smd/contact/radius"_compute_smd_contact_radius.html - -"smd/damage"_compute_smd_damage.html - +"smd/damage"_compute_smd_damage.html - damage status of SPH particles in Smooth Mach Dynamics "smd/hourglass/error"_compute_smd_hourglass_error.html - -"smd/internal/energy"_compute_smd_internal_energy.html - -"smd/plastic/strain"_compute_smd_plastic_strain.html - -"smd/plastic/strain/rate"_compute_smd_plastic_strain_rate.html - -"smd/rho"_compute_smd_rho.html - -"smd/tlsph/defgrad"_compute_smd_tlsph_defgrad.html - -"smd/tlsph/dt"_compute_smd_tlsph_dt.html - +"smd/internal/energy"_compute_smd_internal_energy.html - per-particle enthalpy in Smooth Mach Dynamics +"smd/plastic/strain"_compute_smd_plastic_strain.html - equivalent plastic strain per particle in Smooth Mach Dynamics +"smd/plastic/strain/rate"_compute_smd_plastic_strain_rate.html - time rate of the equivalent plastic strain in Smooth Mach Dynamics +"smd/rho"_compute_smd_rho.html - per-particle mass density in Smooth Mach Dynamics +"smd/tlsph/defgrad"_compute_smd_tlsph_defgrad.html - deformation gradient in Smooth Mach Dynamics +"smd/tlsph/dt"_compute_smd_tlsph_dt.html - CFL-stable time increment per particle in Smooth Mach Dynamics "smd/tlsph/num/neighs"_compute_smd_tlsph_num_neighs.html - "smd/tlsph/shape"_compute_smd_tlsph_shape.html - "smd/tlsph/strain"_compute_smd_tlsph_strain.html - "smd/tlsph/strain/rate"_compute_smd_tlsph_strain_rate.html - -"smd/tlsph/stress"_compute_smd_tlsph_stress.html - -"smd/triangle/vertices"_compute_smd_triangle_vertices.html - +"smd/tlsph/stress"_compute_smd_tlsph_stress.html - per-particle Cauchy stress tensor for SPH particles "smd/triangle/vertices"_compute_smd_triangle_vertices.html - "smd/ulsph/num/neighs"_compute_smd_ulsph_num_neighs.html - "smd/ulsph/strain"_compute_smd_ulsph_strain.html - "smd/ulsph/strain/rate"_compute_smd_ulsph_strain_rate.html - -"smd/ulsph/stress"_compute_smd_ulsph_stress.html - -"smd/vol"_compute_smd_vol.html - +"smd/ulsph/stress"_compute_smd_ulsph_stress.html - per-particle Cauchy stress tensor and von Mises equivalent stress in Smooth Mach Dynamics +"smd/vol"_compute_smd_vol.html - per-particle volumes and their sum in Smooth Mach Dynamics "sna/atom"_compute_sna_atom.html - calculate bispectrum coefficients for each atom "snad/atom"_compute_sna_atom.html - derivative of bispectrum coefficients for each atom "snav/atom"_compute_sna_atom.html - virial contribution from bispectrum coefficients for each atom -"spin"_compute_spin.html - +"spin"_compute_spin.html - magnetic quantities for a system of atoms having spins "stress/atom"_compute_stress_atom.html - stress tensor for each atom -"stress/mop"_compute_stress_mop.html - -"stress/mop/profile"_compute_stress_mop.html - +"stress/mop"_compute_stress_mop.html - normal components of the local stress tensor using the method of planes +"stress/mop/profile"_compute_stress_mop.html - profile of the normal components of the local stress tensor using the method of planes "stress/tally"_compute_tally.html - -"tdpd/cc/atom"_compute_tdpd_cc_atom.html - +"tdpd/cc/atom"_compute_tdpd_cc_atom.html - per-atom chemical concentration of a specified species for each tDPD particle "temp"_compute_temp.html - temperature of group of atoms "temp/asphere"_compute_temp_asphere.html - temperature of aspherical particles "temp/body"_compute_temp_body.html - temperature of body particles "temp/chunk"_compute_temp_chunk.html - temperature of each chunk "temp/com"_compute_temp_com.html - temperature after subtracting center-of-mass velocity -"temp/cs"_compute_temp_cs.html - +"temp/cs"_compute_temp_cs.html - temperature based on the center-of-mass velocity of atom pairs that are bonded to each other "temp/deform"_compute_temp_deform.html - temperature excluding box deformation velocity -"temp/deform/eff"_compute_temp_deform_eff.html - -"temp/drude"_compute_temp_drude.html - -"temp/eff"_compute_temp_eff.html - +"temp/deform/eff"_compute_temp_deform_eff.html - temperature excluding box deformation velocity in the electron force field model +"temp/drude"_compute_temp_drude.html - temperature of Core-Drude pairs +"temp/eff"_compute_temp_eff.html - temperature of a group of nuclei and electrons in the electron force field model "temp/partial"_compute_temp_partial.html - temperature excluding one or more dimensions of velocity "temp/profile"_compute_temp_profile.html - temperature excluding a binned velocity profile "temp/ramp"_compute_temp_ramp.html - temperature excluding ramped velocity component "temp/region"_compute_temp_region.html - temperature of a region of atoms -"temp/region/eff"_compute_temp_region_eff.html - -"temp/rotate"_compute_temp_rotate.html - +"temp/region/eff"_compute_temp_region_eff.html - temperature of a region of nuclei and electrons in the electron force field model +"temp/rotate"_compute_temp_rotate.html - temperature of a group of atoms after subtracting out their center-of-mass and angular velocities "temp/sphere"_compute_temp_sphere.html - temperature of spherical particles -"temp/uef"_compute_temp_uef.html - +"temp/uef"_compute_temp_uef.html - kinetic energy tensor in the reference frame of an applied flow field "ti"_compute_ti.html - thermodynamic integration free energy values "torque/chunk"_compute_torque_chunk.html - torque applied on each chunk "vacf"_compute_vacf.html - velocity auto-correlation function of group of atoms "vcm/chunk"_compute_vcm_chunk.html - velocity of center-of-mass for each chunk "voronoi/atom"_compute_voronoi_atom.html - Voronoi volume and neighbors for each atom -"xrd"_compute_xrd.html - :ul +"xrd"_compute_xrd.html - x-ray diffraction intensity on a mesh of reciprocal lattice nodes :ul [Restrictions:] none From 8526e7a4cdb16bb29e00e049e62de472eb9ee6de Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 19 Jul 2019 11:14:39 -0400 Subject: [PATCH 07/11] checking return value of ?scanf() calls to detect problems parsing files --- doc/src/Errors_messages.txt | 5 +++++ src/REPLICA/neb.cpp | 23 ++++++++++++--------- src/USER-REAXC/fix_qeq_reax.cpp | 8 +++++--- src/atom.cpp | 36 ++++++++++++++++++++------------- src/atom.h | 5 +++++ src/reader_native.cpp | 32 ++++++++++++++++++++--------- src/reader_xyz.cpp | 6 ++++-- 7 files changed, 77 insertions(+), 38 deletions(-) diff --git a/doc/src/Errors_messages.txt b/doc/src/Errors_messages.txt index 1d635ed841..c55d3743ab 100644 --- a/doc/src/Errors_messages.txt +++ b/doc/src/Errors_messages.txt @@ -5890,6 +5890,11 @@ The element names in the ADP file do not match those requested. :dd The element names in the EAM file do not match those requested. :dd +{Incorrect format of ... section in data file} :dt + +Number or type of values per line in the given section of the data file +is not consistent with the requirements for this section. :dd + {Incorrect format in COMB potential file} :dt Incorrect number of words per line in the potential file. :dd diff --git a/src/REPLICA/neb.cpp b/src/REPLICA/neb.cpp index 6b68c52dbb..4061ec6541 100644 --- a/src/REPLICA/neb.cpp +++ b/src/REPLICA/neb.cpp @@ -397,28 +397,33 @@ void NEB::readfile(char *file, int flag) open(file); while (1) { eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one(FLERR,"Unexpected end of neb file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of NEB file"); start = &line[strspn(line," \t\n\v\f\r")]; if (*start != '\0' && *start != '#') break; } - sscanf(line,"%d",&nlines); + int rv = sscanf(line,"%d",&nlines); + if (rv != 1) nlines = -1; } MPI_Bcast(&nlines,1,MPI_INT,0,uworld); - + if (nlines < 0) + error->universe_all(FLERR,"Incorrectly formatted NEB file"); } else { if (me == 0) { if (ireplica) { open(file); while (1) { eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->one(FLERR,"Unexpected end of neb file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of NEB file"); start = &line[strspn(line," \t\n\v\f\r")]; if (*start != '\0' && *start != '#') break; } - sscanf(line,"%d",&nlines); + int rv = sscanf(line,"%d",&nlines); + if (rv != 1) nlines = -1; } else nlines = 0; } MPI_Bcast(&nlines,1,MPI_INT,0,world); + if (nlines < 0) + error->all(FLERR,"Incorrectly formatted NEB file"); } char *buffer = new char[CHUNK*MAXLINE]; @@ -442,7 +447,7 @@ void NEB::readfile(char *file, int flag) eofflag = comm->read_lines_from_file_universe(fp,nchunk,MAXLINE,buffer); else eofflag = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer); - if (eofflag) error->all(FLERR,"Unexpected end of neb file"); + if (eofflag) error->all(FLERR,"Unexpected end of NEB file"); buf = buffer; next = strchr(buf,'\n'); @@ -451,7 +456,7 @@ void NEB::readfile(char *file, int flag) *next = '\n'; if (nwords != ATTRIBUTE_PERLINE) - error->all(FLERR,"Incorrect atom format in neb file"); + error->all(FLERR,"Incorrect atom format in NEB file"); // loop over lines of atom coords // tokenize the line into values @@ -509,12 +514,12 @@ void NEB::readfile(char *file, int flag) int ntotal; MPI_Allreduce(&ncount,&ntotal,1,MPI_INT,MPI_SUM,uworld); if (ntotal != nreplica*nlines) - error->universe_all(FLERR,"Invalid atom IDs in neb file"); + error->universe_all(FLERR,"Invalid atom IDs in NEB file"); } else { int ntotal; MPI_Allreduce(&ncount,&ntotal,1,MPI_INT,MPI_SUM,world); if (ntotal != nlines) - error->all(FLERR,"Invalid atom IDs in neb file"); + error->all(FLERR,"Invalid atom IDs in NEB file"); } // clean up diff --git a/src/USER-REAXC/fix_qeq_reax.cpp b/src/USER-REAXC/fix_qeq_reax.cpp index faa0632608..6c0da278c2 100644 --- a/src/USER-REAXC/fix_qeq_reax.cpp +++ b/src/USER-REAXC/fix_qeq_reax.cpp @@ -200,7 +200,7 @@ void FixQEqReax::pertype_parameters(char *arg) return; } - int i,itype,ntypes; + int i,itype,ntypes,rv; double v1,v2,v3; FILE *pf; @@ -216,9 +216,11 @@ void FixQEqReax::pertype_parameters(char *arg) error->one(FLERR,"Fix qeq/reax parameter file could not be found"); for (i = 1; i <= ntypes && !feof(pf); i++) { - fscanf(pf,"%d %lg %lg %lg",&itype,&v1,&v2,&v3); + rv = fscanf(pf,"%d %lg %lg %lg",&itype,&v1,&v2,&v3); + if (rv != 4) + error->one(FLERR,"Fix qeq/reax: Incorrect format of param file"); if (itype < 1 || itype > ntypes) - error->one(FLERR,"Fix qeq/reax invalid atom type in param file"); + error->one(FLERR,"Fix qeq/reax: invalid atom type in param file"); chi[itype] = v1; eta[itype] = v2; gamma[itype] = v3; diff --git a/src/atom.cpp b/src/atom.cpp index 1f5d5a80c4..e5a982d620 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -1071,7 +1071,7 @@ void Atom::data_vels(int n, char *buf, tagint id_offset) void Atom::data_bonds(int n, char *buf, int *count, tagint id_offset, int type_offset) { - int m,tmp,itype; + int m,tmp,itype,rv; tagint atom1,atom2; char *next; int newton_bond = force->newton_bond; @@ -1079,8 +1079,10 @@ void Atom::data_bonds(int n, char *buf, int *count, tagint id_offset, for (int i = 0; i < n; i++) { next = strchr(buf,'\n'); *next = '\0'; - sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&itype,&atom1,&atom2); + rv = sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT, + &tmp,&itype,&atom1,&atom2); + if (rv != 4) + error->one(FLERR,"Incorrect format of Bonds section in data file"); if (id_offset) { atom1 += id_offset; atom2 += id_offset; @@ -1124,7 +1126,7 @@ void Atom::data_bonds(int n, char *buf, int *count, tagint id_offset, void Atom::data_angles(int n, char *buf, int *count, tagint id_offset, int type_offset) { - int m,tmp,itype; + int m,tmp,itype,rv; tagint atom1,atom2,atom3; char *next; int newton_bond = force->newton_bond; @@ -1132,8 +1134,10 @@ void Atom::data_angles(int n, char *buf, int *count, tagint id_offset, for (int i = 0; i < n; i++) { next = strchr(buf,'\n'); *next = '\0'; - sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&itype,&atom1,&atom2,&atom3); + rv = sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, + &tmp,&itype,&atom1,&atom2,&atom3); + if (rv != 5) + error->one(FLERR,"Incorrect format of Angles section in data file"); if (id_offset) { atom1 += id_offset; atom2 += id_offset; @@ -1194,7 +1198,7 @@ void Atom::data_angles(int n, char *buf, int *count, tagint id_offset, void Atom::data_dihedrals(int n, char *buf, int *count, tagint id_offset, int type_offset) { - int m,tmp,itype; + int m,tmp,itype,rv; tagint atom1,atom2,atom3,atom4; char *next; int newton_bond = force->newton_bond; @@ -1202,9 +1206,11 @@ void Atom::data_dihedrals(int n, char *buf, int *count, tagint id_offset, for (int i = 0; i < n; i++) { next = strchr(buf,'\n'); *next = '\0'; - sscanf(buf,"%d %d " - TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&itype,&atom1,&atom2,&atom3,&atom4); + rv = sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT + " " TAGINT_FORMAT " " TAGINT_FORMAT, + &tmp,&itype,&atom1,&atom2,&atom3,&atom4); + if (rv != 6) + error->one(FLERR,"Incorrect format of Dihedrals section in data file"); if (id_offset) { atom1 += id_offset; atom2 += id_offset; @@ -1283,7 +1289,7 @@ void Atom::data_dihedrals(int n, char *buf, int *count, tagint id_offset, void Atom::data_impropers(int n, char *buf, int *count, tagint id_offset, int type_offset) { - int m,tmp,itype; + int m,tmp,itype,rv; tagint atom1,atom2,atom3,atom4; char *next; int newton_bond = force->newton_bond; @@ -1291,9 +1297,11 @@ void Atom::data_impropers(int n, char *buf, int *count, tagint id_offset, for (int i = 0; i < n; i++) { next = strchr(buf,'\n'); *next = '\0'; - sscanf(buf,"%d %d " - TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&itype,&atom1,&atom2,&atom3,&atom4); + rv = sscanf(buf,"%d %d " + TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, + &tmp,&itype,&atom1,&atom2,&atom3,&atom4); + if (rv != 6) + error->one(FLERR,"Incorrect format of Impropers section in data file"); if (id_offset) { atom1 += id_offset; atom2 += id_offset; diff --git a/src/atom.h b/src/atom.h index 5cd9ca819b..81f643c007 100644 --- a/src/atom.h +++ b/src/atom.h @@ -426,6 +426,11 @@ E: Incorrect atom format in data file Number of values per atom line in the data file is not consistent with the atom style. +E: Incorrect format of ... section in data file + +Number or type of values per line in the given section of the data file +is not consistent with the requirements for this section. + E: Invalid atom type in Atoms section of data file Atom types must range from 1 to specified # of types. diff --git a/src/reader_native.cpp b/src/reader_native.cpp index 7c772ab6b8..60b7ecd764 100644 --- a/src/reader_native.cpp +++ b/src/reader_native.cpp @@ -59,8 +59,9 @@ int ReaderNative::read_time(bigint &ntimestep) if (strstr(line,"ITEM: TIMESTEP") != line) error->one(FLERR,"Dump file is incorrectly formatted"); read_lines(1); - sscanf(line,BIGINT_FORMAT,&ntimestep); - + int rv = sscanf(line,BIGINT_FORMAT,&ntimestep); + if (rv != 1) + error->one(FLERR,"Dump file is incorrectly formatted"); return 0; } @@ -73,7 +74,9 @@ void ReaderNative::skip() { read_lines(2); bigint natoms; - sscanf(line,BIGINT_FORMAT,&natoms); + int rv = sscanf(line,BIGINT_FORMAT,&natoms); + if (rv != 1) + error->one(FLERR,"Dump file is incorrectly formatted"); read_lines(5); @@ -110,8 +113,12 @@ bigint ReaderNative::read_header(double box[3][3], int &boxinfo, int &triclinic, int &xflag, int &yflag, int &zflag) { bigint natoms; + int rv; + read_lines(2); - sscanf(line,BIGINT_FORMAT,&natoms); + rv = sscanf(line,BIGINT_FORMAT,&natoms); + if (rv != 1) + error->one(FLERR,"Dump file is incorrectly formatted"); boxinfo = 1; triclinic = 0; @@ -120,14 +127,19 @@ bigint ReaderNative::read_header(double box[3][3], int &boxinfo, int &triclinic, if (line[strlen("ITEM: BOX BOUNDS ")] == 'x') triclinic = 1; read_lines(1); - if (!triclinic) sscanf(line,"%lg %lg",&box[0][0],&box[0][1]); - else sscanf(line,"%lg %lg %lg",&box[0][0],&box[0][1],&box[0][2]); + if (!triclinic) rv = 2 - sscanf(line,"%lg %lg",&box[0][0],&box[0][1]); + else rv = 3 - sscanf(line,"%lg %lg %lg",&box[0][0],&box[0][1],&box[0][2]); + if (rv != 0) error->one(FLERR,"Dump file is incorrectly formatted"); + read_lines(1); - if (!triclinic) sscanf(line,"%lg %lg",&box[1][0],&box[1][1]); - else sscanf(line,"%lg %lg %lg",&box[1][0],&box[1][1],&box[1][2]); + if (!triclinic) rv = 2 - sscanf(line,"%lg %lg",&box[1][0],&box[1][1]); + else rv = 3 - sscanf(line,"%lg %lg %lg",&box[1][0],&box[1][1],&box[1][2]); + if (rv != 0) error->one(FLERR,"Dump file is incorrectly formatted"); + read_lines(1); - if (!triclinic) sscanf(line,"%lg %lg",&box[2][0],&box[2][1]); - else sscanf(line,"%lg %lg %lg",&box[2][0],&box[2][1],&box[2][2]); + if (!triclinic) rv = 2 - sscanf(line,"%lg %lg",&box[2][0],&box[2][1]); + else rv = 3 - sscanf(line,"%lg %lg %lg",&box[2][0],&box[2][1],&box[2][2]); + if (rv != 0) error->one(FLERR,"Dump file is incorrectly formatted"); read_lines(1); diff --git a/src/reader_xyz.cpp b/src/reader_xyz.cpp index 303c25cd7a..040eb9d460 100644 --- a/src/reader_xyz.cpp +++ b/src/reader_xyz.cpp @@ -170,7 +170,7 @@ bigint ReaderXYZ::read_header(double /*box*/[3][3], int &boxinfo, int &/*triclin void ReaderXYZ::read_atoms(int n, int nfield, double **fields) { - int i,m; + int i,m,rv; char *eof; int mytype; double myx, myy, myz; @@ -180,7 +180,9 @@ void ReaderXYZ::read_atoms(int n, int nfield, double **fields) if (eof == NULL) error->one(FLERR,"Unexpected end of dump file"); ++nid; - sscanf(line,"%*s%lg%lg%lg", &myx, &myy, &myz); + rv = sscanf(line,"%*s%lg%lg%lg", &myx, &myy, &myz); + if (rv != 3) + error->one("Dump file is incorrectly formatted"); // XXX: we could insert an element2type translation here // XXX: for now we flag unrecognized types as type 0, From 1de00aaab0baf227c49bb7e7bc33ab5f559416cf Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 19 Jul 2019 11:16:41 -0400 Subject: [PATCH 08/11] improve parsing of data file header the header lines are now checked using regular expressions instead of strstr() which allows for stricter checking, but also is more forgiving in terms of extra or different whitespace return value of sscanf() calls is checked and on failure LAMMPS errors out --- src/read_data.cpp | 132 +++++++++++++++++++++++++++++++++------------- 1 file changed, 94 insertions(+), 38 deletions(-) diff --git a/src/read_data.cpp b/src/read_data.cpp index e70a526c38..989f989269 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -45,6 +45,7 @@ #include "irregular.h" #include "error.h" #include "memory.h" +#include "utils.h" using namespace LAMMPS_NS; @@ -999,74 +1000,115 @@ void ReadData::header(int firstpass) // customize for new header lines // check for triangles before angles so "triangles" not matched as "angles" int extra_flag_value = 0; + int rv; - if (strstr(line,"atoms")) { - sscanf(line,BIGINT_FORMAT,&natoms); + if (utils::strmatch(line,"^\\s*\\d+\\s+atoms\\s")) { + rv = sscanf(line,BIGINT_FORMAT,&natoms); + if (rv != 1) + error->all(FLERR,"Could not parse 'atoms' line in data file header"); if (addflag == NONE) atom->natoms = natoms; else if (firstpass) atom->natoms += natoms; - } else if (strstr(line,"ellipsoids")) { + } else if (utils::strmatch(line,"^\\s*\\d+\\s+ellipsoids\\s")) { if (!avec_ellipsoid) error->all(FLERR,"No ellipsoids allowed with this atom style"); - sscanf(line,BIGINT_FORMAT,&nellipsoids); + rv = sscanf(line,BIGINT_FORMAT,&nellipsoids); + if (rv != 1) + error->all(FLERR,"Could not parse 'ellipsoids' line in data file header"); if (addflag == NONE) atom->nellipsoids = nellipsoids; else if (firstpass) atom->nellipsoids += nellipsoids; - } else if (strstr(line,"lines")) { + } else if (utils::strmatch(line,"^\\s*\\d+\\s+lines\\s")) { if (!avec_line) error->all(FLERR,"No lines allowed with this atom style"); - sscanf(line,BIGINT_FORMAT,&nlines); + rv = sscanf(line,BIGINT_FORMAT,&nlines); + if (rv != 1) + error->all(FLERR,"Could not parse 'lines' line in data file header"); if (addflag == NONE) atom->nlines = nlines; else if (firstpass) atom->nlines += nlines; - } else if (strstr(line,"triangles")) { + } else if (utils::strmatch(line,"^\\s*\\d+\\s+triangles\\s")) { if (!avec_tri) error->all(FLERR,"No triangles allowed with this atom style"); - sscanf(line,BIGINT_FORMAT,&ntris); + rv = sscanf(line,BIGINT_FORMAT,&ntris); + if (rv != 1) + error->all(FLERR,"Could not parse 'triangles' line in data file header"); if (addflag == NONE) atom->ntris = ntris; else if (firstpass) atom->ntris += ntris; - } else if (strstr(line,"bodies")) { + } else if (utils::strmatch(line,"^\\s*\\d+\\s+bodies\\s")) { if (!avec_body) error->all(FLERR,"No bodies allowed with this atom style"); - sscanf(line,BIGINT_FORMAT,&nbodies); + rv = sscanf(line,BIGINT_FORMAT,&nbodies); + if (rv != 1) + error->all(FLERR,"Could not parse 'bodies' line in data file header"); if (addflag == NONE) atom->nbodies = nbodies; else if (firstpass) atom->nbodies += nbodies; - } else if (strstr(line,"bonds")) { - sscanf(line,BIGINT_FORMAT,&nbonds); + } else if (utils::strmatch(line,"^\\s*\\d+\\s+bonds\\s")) { + rv = sscanf(line,BIGINT_FORMAT,&nbonds); + if (rv != 1) + error->all(FLERR,"Could not parse 'bonds' line in data file header"); if (addflag == NONE) atom->nbonds = nbonds; else if (firstpass) atom->nbonds += nbonds; - } else if (strstr(line,"angles")) { - sscanf(line,BIGINT_FORMAT,&nangles); + + } else if (utils::strmatch(line,"^\\s*\\d+\\s+angles\\s")) { + rv = sscanf(line,BIGINT_FORMAT,&nangles); + if (rv != 1) + error->all(FLERR,"Could not parse 'angles' line in data file header"); if (addflag == NONE) atom->nangles = nangles; else if (firstpass) atom->nangles += nangles; - } else if (strstr(line,"dihedrals")) { - sscanf(line,BIGINT_FORMAT,&ndihedrals); + + } else if (utils::strmatch(line,"^\\s*\\d+\\s+dihedrals\\s")) { + rv = sscanf(line,BIGINT_FORMAT,&ndihedrals); + if (rv != 1) + error->all(FLERR,"Could not parse 'dihedrals' line in data file header"); if (addflag == NONE) atom->ndihedrals = ndihedrals; else if (firstpass) atom->ndihedrals += ndihedrals; - } else if (strstr(line,"impropers")) { - sscanf(line,BIGINT_FORMAT,&nimpropers); + + } else if (utils::strmatch(line,"^\\s*\\d+\\s+impropers\\s")) { + rv = sscanf(line,BIGINT_FORMAT,&nimpropers); + if (rv != 1) + error->all(FLERR,"Could not parse 'impropers' line in data file header"); if (addflag == NONE) atom->nimpropers = nimpropers; else if (firstpass) atom->nimpropers += nimpropers; // Atom class type settings are only set by first data file - } else if (strstr(line,"atom types")) { - sscanf(line,"%d",&ntypes); + } else if (utils::strmatch(line,"^\\s*\\d+\\s+atom\\s+types\\s")) { + rv = sscanf(line,"%d",&ntypes); + if (rv != 1) + error->all(FLERR,"Could not parse 'atom types' line " + "in data file header"); if (addflag == NONE) atom->ntypes = ntypes + extra_atom_types; - } else if (strstr(line,"bond types")) { - sscanf(line,"%d",&nbondtypes); + + } else if (utils::strmatch(line,"\\s*\\d+\\s+bond\\s+types\\s")) { + rv = sscanf(line,"%d",&nbondtypes); + if (rv != 1) + error->all(FLERR,"Could not parse 'bond types' line " + "in data file header"); if (addflag == NONE) atom->nbondtypes = nbondtypes + extra_bond_types; - } else if (strstr(line,"angle types")) { - sscanf(line,"%d",&nangletypes); + + } else if (utils::strmatch(line,"^\\s*\\d+\\s+angle\\s+types\\s")) { + rv = sscanf(line,"%d",&nangletypes); + if (rv != 1) + error->all(FLERR,"Could not parse 'angle types' line " + "in data file header"); if (addflag == NONE) atom->nangletypes = nangletypes + extra_angle_types; - } else if (strstr(line,"dihedral types")) { - sscanf(line,"%d",&ndihedraltypes); + + } else if (utils::strmatch(line,"^\\s*\\d+\\s+dihedral\\s+types\\s")) { + rv = sscanf(line,"%d",&ndihedraltypes); + if (rv != 1) + error->all(FLERR,"Could not parse 'dihedral types' line " + "in data file header"); if (addflag == NONE) atom->ndihedraltypes = ndihedraltypes + extra_dihedral_types; - } else if (strstr(line,"improper types")) { - sscanf(line,"%d",&nimpropertypes); + + } else if (utils::strmatch(line,"^\\s*\\d+\\s+improper\\s+types\\s")) { + rv = sscanf(line,"%d",&nimpropertypes); + if (rv != 1) + error->all(FLERR,"Could not parse 'improper types' line " + "in data file header"); if (addflag == NONE) atom->nimpropertypes = nimpropertypes + extra_improper_types; @@ -1095,15 +1137,27 @@ void ReadData::header(int firstpass) // local copy of box info // so can treat differently for first vs subsequent data files - } else if (strstr(line,"xlo xhi")) { - sscanf(line,"%lg %lg",&boxlo[0],&boxhi[0]); - } else if (strstr(line,"ylo yhi")) { - sscanf(line,"%lg %lg",&boxlo[1],&boxhi[1]); - } else if (strstr(line,"zlo zhi")) { - sscanf(line,"%lg %lg",&boxlo[2],&boxhi[2]); - } else if (strstr(line,"xy xz yz")) { + } else if (utils::strmatch(line,"^\\s*\\f+\\s+\\f+\\s+xlo\\s+xhi\\s")) { + rv = sscanf(line,"%lg %lg",&boxlo[0],&boxhi[0]); + if (rv != 2) + error->all(FLERR,"Could not parse 'xlo xhi' line in data file header"); + + } else if (utils::strmatch(line,"^\\s*\\f+\\s+\\f+\\s+ylo\\s+yhi\\s")) { + rv = sscanf(line,"%lg %lg",&boxlo[1],&boxhi[1]); + if (rv != 2) + error->all(FLERR,"Could not parse 'ylo yhi' line in data file header"); + + } else if (utils::strmatch(line,"^\\s*\\f+\\s+\\f+\\s+zlo\\s+zhi\\s")) { + rv = sscanf(line,"%lg %lg",&boxlo[2],&boxhi[2]); + if (rv != 2) + error->all(FLERR,"Could not parse 'zlo zhi' line in data file header"); + + } else if (utils::strmatch(line,"^\\s*\\f+\\s+\\f+\\s+\\f+" + "\\s+xy\\s+xz\\s+yz\\s")) { triclinic = 1; - sscanf(line,"%lg %lg %lg",&xy,&xz,&yz); + rv = sscanf(line,"%lg %lg %lg",&xy,&xz,&yz); + if (rv != 3) + error->all(FLERR,"Could not parse 'xy xz yz' line in data file header"); } else break; } @@ -1638,7 +1692,7 @@ void ReadData::bonus(bigint nbonus, AtomVec *ptr, const char *type) void ReadData::bodies(int firstpass) { - int m,nchunk,nline,nmax,ninteger,ndouble,nword,ncount,onebody,tmp; + int m,nchunk,nline,nmax,ninteger,ndouble,nword,ncount,onebody,tmp,rv; char *eof; int mapflag = 0; @@ -1666,7 +1720,9 @@ void ReadData::bodies(int firstpass) while (nchunk < nmax && nline <= CHUNK-MAXBODY) { eof = fgets(&buffer[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); - sscanf(&buffer[m],"%d %d %d",&tmp,&ninteger,&ndouble); + rv = sscanf(&buffer[m],"%d %d %d",&tmp,&ninteger,&ndouble); + if (rv != 3) + error->one(FLERR,"Incorrect format in Bodies section of data file"); m += strlen(&buffer[m]); // read lines one at a time into buffer and count words From d730ef5b19dfe7b14327ddb9a0733f49c04baf4b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 19 Jul 2019 11:31:45 -0400 Subject: [PATCH 09/11] fix typo --- src/reader_xyz.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reader_xyz.cpp b/src/reader_xyz.cpp index 040eb9d460..19f0ff2135 100644 --- a/src/reader_xyz.cpp +++ b/src/reader_xyz.cpp @@ -182,7 +182,7 @@ void ReaderXYZ::read_atoms(int n, int nfield, double **fields) ++nid; rv = sscanf(line,"%*s%lg%lg%lg", &myx, &myy, &myz); if (rv != 3) - error->one("Dump file is incorrectly formatted"); + error->one(FLERR,"Dump file is incorrectly formatted"); // XXX: we could insert an element2type translation here // XXX: for now we flag unrecognized types as type 0, From e72aef2a9621118f7662f53be37a226037669d30 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 19 Jul 2019 12:01:16 -0400 Subject: [PATCH 10/11] more sscanf() return value checking --- src/procmap.cpp | 9 ++++++--- src/universe.cpp | 10 +++++----- src/variable.cpp | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/procmap.cpp b/src/procmap.cpp index 9d1ed83e73..8207b61f4c 100644 --- a/src/procmap.cpp +++ b/src/procmap.cpp @@ -301,7 +301,8 @@ void ProcMap::custom_grid(char *cfile, int nprocs, MPI_Bcast(&n,1,MPI_INT,0,world); MPI_Bcast(line,n,MPI_CHAR,0,world); - sscanf(line,"%d %d %d",&procgrid[0],&procgrid[1],&procgrid[2]); + int rv = sscanf(line,"%d %d %d",&procgrid[0],&procgrid[1],&procgrid[2]); + if (rv != 3) error->all(FLERR,"Processors custom grid file is inconsistent"); int flag = 0; if (procgrid[0]*procgrid[1]*procgrid[2] != nprocs) flag = 1; @@ -320,8 +321,10 @@ void ProcMap::custom_grid(char *cfile, int nprocs, for (int i = 0; i < nprocs; i++) { if (!fgets(line,MAXLINE,fp)) error->one(FLERR,"Unexpected end of custom file"); - sscanf(line,"%d %d %d %d", - &cmap[i][0],&cmap[i][1],&cmap[i][2],&cmap[i][3]); + rv = sscanf(line,"%d %d %d %d", + &cmap[i][0],&cmap[i][1],&cmap[i][2],&cmap[i][3]); + if (rv != 4) + error->one(FLERR,"Processors custom grid file is inconsistent"); } fclose(fp); } diff --git a/src/universe.cpp b/src/universe.cpp index f078590103..dba31f8b76 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -114,19 +114,19 @@ void Universe::reorder(char *style, char *arg) // read nprocs lines // uni2orig = inverse mapping - int me_orig,me_new; - sscanf(line,"%d %d",&me_orig,&me_new); + int me_orig,me_new,rv; + rv = sscanf(line,"%d %d",&me_orig,&me_new); if (me_orig < 0 || me_orig >= nprocs || - me_new < 0 || me_new >= nprocs) + me_new < 0 || me_new >= nprocs || rv != 2) error->one(FLERR,"Invalid entry in -reorder file"); uni2orig[me_new] = me_orig; for (int i = 1; i < nprocs; i++) { if (!fgets(line,MAXLINE,fp)) error->one(FLERR,"Unexpected end of -reorder file"); - sscanf(line,"%d %d",&me_orig,&me_new); + rv = sscanf(line,"%d %d",&me_orig,&me_new); if (me_orig < 0 || me_orig >= nprocs || - me_new < 0 || me_new >= nprocs) + me_new < 0 || me_new >= nprocs || rv != 2) error->one(FLERR,"Invalid entry in -reorder file"); uni2orig[me_new] = me_orig; } diff --git a/src/variable.cpp b/src/variable.cpp index ea7f3044d7..63a425bcf5 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -5162,8 +5162,8 @@ int VarReader::read_peratom() for (i = 0; i < nchunk; i++) { next = strchr(buf,'\n'); *next = '\0'; - sscanf(buf,TAGINT_FORMAT " %lg",&tag,&value); - if (tag <= 0 || tag > map_tag_max) + int rv = sscanf(buf,TAGINT_FORMAT " %lg",&tag,&value); + if (tag <= 0 || tag > map_tag_max || rv != 2) error->one(FLERR,"Invalid atom ID in variable file"); if ((m = atom->map(tag)) >= 0) vstore[m] = value; buf = next + 1; From 276e3b2df10e5f3ea160986f090651182b56aa5d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 19 Jul 2019 14:00:24 -0400 Subject: [PATCH 11/11] update fix tmd input similar to read_data --- src/fix_tmd.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/fix_tmd.cpp b/src/fix_tmd.cpp index 4cbb244bc0..10315a750d 100644 --- a/src/fix_tmd.cpp +++ b/src/fix_tmd.cpp @@ -30,6 +30,7 @@ #include "force.h" #include "memory.h" #include "error.h" +#include "utils.h" using namespace LAMMPS_NS; using namespace FixConst; @@ -164,7 +165,7 @@ void FixTMD::init() dtv = update->dt; dtf = update->dt * force->ftm2v; - if (strstr(update->integrate_style,"respa")) + if (utils::strmatch(update->integrate_style,"^respa")) step_respa = ((Respa *) update->integrate)->step; } @@ -423,21 +424,27 @@ void FixTMD::readfile(char *file) *next = '\0'; if (firstline) { - if (strstr(bufptr,"xlo xhi")) { + if (utils::strmatch(bufptr,"^\\s*\\f+\\s+\\f+\\s+xlo\\s+xhi")) { double lo,hi; - sscanf(bufptr,"%lg %lg",&lo,&hi); + n = sscanf(bufptr,"%lg %lg",&lo,&hi); + if (n != 2) + error->all(FLERR,"Incorrect format in TMD target file"); xprd = hi - lo; bufptr = next + 1; continue; - } else if (strstr(bufptr,"ylo yhi")) { + } else if (utils::strmatch(bufptr,"^\\s*\\f+\\s+\\f+\\s+ylo\\s+yhi")) { double lo,hi; - sscanf(bufptr,"%lg %lg",&lo,&hi); + n = sscanf(bufptr,"%lg %lg",&lo,&hi); + if (n != 2) + error->all(FLERR,"Incorrect format in TMD target file"); yprd = hi - lo; bufptr = next + 1; continue; - } else if (strstr(bufptr,"zlo zhi")) { + } else if (utils::strmatch(bufptr,"^\\s*\\f+\\s+\\f+\\s+zlo\\s+zhi")) { double lo,hi; - sscanf(bufptr,"%lg %lg",&lo,&hi); + n = sscanf(bufptr,"%lg %lg",&lo,&hi); + if (n != 2) + error->all(FLERR,"Incorrect format in TMD target file"); zprd = hi - lo; bufptr = next + 1; continue; @@ -455,14 +462,13 @@ void FixTMD::readfile(char *file) } if (imageflag) - n = sscanf(bufptr,TAGINT_FORMAT " %lg %lg %lg %d %d %d", - &itag,&x,&y,&z,&ix,&iy,&iz); + n = 7 - sscanf(bufptr,TAGINT_FORMAT " %lg %lg %lg %d %d %d", + &itag,&x,&y,&z,&ix,&iy,&iz); else - n = sscanf(bufptr,TAGINT_FORMAT " %lg %lg %lg",&itag,&x,&y,&z); + n = 4 - sscanf(bufptr,TAGINT_FORMAT " %lg %lg %lg",&itag,&x,&y,&z); - if (n < 0) { - if (me == 0) error->warning(FLERR,"Ignoring empty or incorrectly" - " formatted line in target file"); + if (n != 0) { + error->all(FLERR,"Incorrectly formatted line in TMD target file"); bufptr = next + 1; continue; }