From af76ffdfdacf2faaf4b6740c1e57993e28ad54e7 Mon Sep 17 00:00:00 2001 From: Vladislav Galigerov Date: Sun, 18 Jun 2023 17:08:49 +0300 Subject: [PATCH 01/17] ROCM aware OpenMPI support --- src/KOKKOS/kokkos.cpp | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 91ea6d37ac..7f3f9f0d10 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -43,8 +43,7 @@ #define GPU_AWARE_UNKNOWN static int have_gpu_aware = -1; -// TODO HIP: implement HIP-aware MPI support (UCX) detection -#if defined(KOKKOS_ENABLE_HIP) || defined(KOKKOS_ENABLE_SYCL) || defined(KOKKOS_ENABLE_OPENMPTARGET) +#if defined(KOKKOS_ENABLE_SYCL) || defined(KOKKOS_ENABLE_OPENMPTARGET) GPU_AWARE_UNKNOWN #elif defined(KOKKOS_ENABLE_CUDA) @@ -71,7 +70,28 @@ GPU_AWARE_UNKNOWN GPU_AWARE_UNKNOWN #endif // OPEN_MPI -#endif // KOKKOS_ENABLE_CUDA +#elif defined(KOKKOS_ENABLE_HIP) + +// OpenMPI supports detecting HIP-aware MPI as of version 5.0.0 +#if (OPEN_MPI) +#if (OMPI_MAJOR_VERSION >= 5) +#include +#if defined(OMPI_HAVE_MPI_EXT_ROCM) && OMPI_HAVE_MPI_EXT_ROCM +// May have rocm enabled: below we will check dynamically with MPIX_Query_rocm_support() +static int have_gpu_aware = 1; +#elif defined(OMPI_HAVE_MPI_EXT_ROCM) && !OMPI_HAVE_MPI_EXT_ROCM +static int have_gpu_aware = 0; +#else +GPU_AWARE_UNKNOWN +#endif // defined(OMPI_HAVE_MPI_EXT_ROCM) +#else // old OpenMPI +GPU_AWARE_UNKNOWN +#endif // (OMPI_MAJOR_VERSION >=5) +#else // unknown MPI library +GPU_AWARE_UNKNOWN +#endif // OPEN_MPI + +#endif // KOKKOS_ENABLE_CUDA & KOKKOS_ENABLE_HIP #endif // LMP_ENABLE_DEVICE @@ -236,8 +256,20 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) binsize = 0.0; #ifdef KOKKOS_ENABLE_CUDA - // TODO HIP: implement HIP-aware MPI testing gpu_aware_flag = 1; +#elif defined(KOKKOS_ENABLE_HIP) && defined(OMPI_HAVE_MPI_EXT_ROCM) && OMPI_HAVE_MPI_EXT_ROCM + if(have_gpu_aware == 1) + { + gpu_aware_flag = MPIX_Query_rocm_support(); + if(gpu_aware_flag && me == 0) + { + error->warning(FLERR,"ROCm-aware OpenMPI is supported and enabled (debug msg, remove it later)"); + } + } + else + { + gpu_aware_flag = 0; + } #else gpu_aware_flag = 0; #endif From bd1794f142a6ad1fde680f41b539772494874489 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Tue, 17 Oct 2023 12:59:10 -0600 Subject: [PATCH 02/17] Remove debug output --- src/KOKKOS/kokkos.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 9eee432969..0c9a028f28 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -266,18 +266,10 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) #ifdef KOKKOS_ENABLE_CUDA gpu_aware_flag = 1; #elif defined(KOKKOS_ENABLE_HIP) && defined(OMPI_HAVE_MPI_EXT_ROCM) && OMPI_HAVE_MPI_EXT_ROCM - if(have_gpu_aware == 1) - { + if (have_gpu_aware == 1) gpu_aware_flag = MPIX_Query_rocm_support(); - if(gpu_aware_flag && me == 0) - { - error->warning(FLERR,"ROCm-aware OpenMPI is supported and enabled (debug msg, remove it later)"); - } - } else - { gpu_aware_flag = 0; - } #else gpu_aware_flag = 0; #endif From 791f7d1d882fc4f994891e5cb59efaafd884c912 Mon Sep 17 00:00:00 2001 From: vladgl Date: Wed, 18 Oct 2023 22:14:42 +0300 Subject: [PATCH 03/17] Add dynamic check for CUDA --- src/KOKKOS/kokkos.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 0c9a028f28..787f75fd47 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -37,7 +37,7 @@ // for detecting GPU-aware MPI support: // the variable int have_gpu_aware -// - is 1 if GPU-aware MPI support is available +// - is 1 if GPU-aware MPI support is potentially available // - is 0 if GPU-aware MPI support is unavailable // - is -1 if GPU-aware MPI support is unknown @@ -48,24 +48,20 @@ GPU_AWARE_UNKNOWN #elif defined(KOKKOS_ENABLE_CUDA) // OpenMPI supports detecting GPU-aware MPI as of version 2.0.0 - #if (OPEN_MPI) #if (OMPI_MAJOR_VERSION >= 2) - #include - #if defined(MPIX_CUDA_AWARE_SUPPORT) && MPIX_CUDA_AWARE_SUPPORT +// May have CUDA-aware enabled: below we will check dynamically with MPIX_Query_cuda_support() static int have_gpu_aware = 1; #elif defined(MPIX_CUDA_AWARE_SUPPORT) && !MPIX_CUDA_AWARE_SUPPORT static int have_gpu_aware = 0; #else GPU_AWARE_UNKNOWN #endif // defined(MPIX_CUDA_AWARE_SUPPORT) - #else // old OpenMPI GPU_AWARE_UNKNOWN #endif // (OMPI_MAJOR_VERSION >=2) - #else // unknown MPI library GPU_AWARE_UNKNOWN #endif // OPEN_MPI @@ -76,10 +72,10 @@ GPU_AWARE_UNKNOWN #if (OPEN_MPI) #if (OMPI_MAJOR_VERSION >= 5) #include -#if defined(OMPI_HAVE_MPI_EXT_ROCM) && OMPI_HAVE_MPI_EXT_ROCM -// May have rocm enabled: below we will check dynamically with MPIX_Query_rocm_support() +#if defined(MPIX_ROCM_AWARE_SUPPORT ) && MPIX_ROCM_AWARE_SUPPORT +// May have ROCm-aware enabled: below we will check dynamically with MPIX_Query_rocm_support() static int have_gpu_aware = 1; -#elif defined(OMPI_HAVE_MPI_EXT_ROCM) && !OMPI_HAVE_MPI_EXT_ROCM +#elif defined(MPIX_ROCM_AWARE_SUPPORT) && !MPIX_ROCM_AWARE_SUPPORT static int have_gpu_aware = 0; #else GPU_AWARE_UNKNOWN @@ -263,13 +259,10 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) // default settings for package kokkos command binsize = 0.0; -#ifdef KOKKOS_ENABLE_CUDA - gpu_aware_flag = 1; -#elif defined(KOKKOS_ENABLE_HIP) && defined(OMPI_HAVE_MPI_EXT_ROCM) && OMPI_HAVE_MPI_EXT_ROCM - if (have_gpu_aware == 1) - gpu_aware_flag = MPIX_Query_rocm_support(); - else - gpu_aware_flag = 0; +#if defined(KOKKOS_ENABLE_CUDA) && defined(MPIX_CUDA_AWARE_SUPPORT) && MPIX_CUDA_AWARE_SUPPORT + gpu_aware_flag = MPIX_Query_cuda_support(); +#elif defined(KOKKOS_ENABLE_HIP) && defined(MPIX_ROCM_AWARE_SUPPORT) && MPIX_ROCM_AWARE_SUPPORT + gpu_aware_flag = MPIX_Query_rocm_support(); #else gpu_aware_flag = 0; #endif From b1ffb70f7d62355efd7de688ef2193c2477315ca Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 26 Oct 2023 17:20:33 -0600 Subject: [PATCH 04/17] Logic tweak --- src/KOKKOS/kokkos.cpp | 61 +++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 787f75fd47..b190c7f6b6 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -37,7 +37,7 @@ // for detecting GPU-aware MPI support: // the variable int have_gpu_aware -// - is 1 if GPU-aware MPI support is potentially available +// - is 1 if GPU-aware MPI support is available // - is 0 if GPU-aware MPI support is unavailable // - is -1 if GPU-aware MPI support is unknown @@ -52,7 +52,6 @@ GPU_AWARE_UNKNOWN #if (OMPI_MAJOR_VERSION >= 2) #include #if defined(MPIX_CUDA_AWARE_SUPPORT) && MPIX_CUDA_AWARE_SUPPORT -// May have CUDA-aware enabled: below we will check dynamically with MPIX_Query_cuda_support() static int have_gpu_aware = 1; #elif defined(MPIX_CUDA_AWARE_SUPPORT) && !MPIX_CUDA_AWARE_SUPPORT static int have_gpu_aware = 0; @@ -72,8 +71,7 @@ GPU_AWARE_UNKNOWN #if (OPEN_MPI) #if (OMPI_MAJOR_VERSION >= 5) #include -#if defined(MPIX_ROCM_AWARE_SUPPORT ) && MPIX_ROCM_AWARE_SUPPORT -// May have ROCm-aware enabled: below we will check dynamically with MPIX_Query_rocm_support() +#if defined(MPIX_ROCM_AWARE_SUPPORT) && MPIX_ROCM_AWARE_SUPPORT static int have_gpu_aware = 1; #elif defined(MPIX_ROCM_AWARE_SUPPORT) && !MPIX_ROCM_AWARE_SUPPORT static int have_gpu_aware = 0; @@ -89,7 +87,7 @@ GPU_AWARE_UNKNOWN #endif // KOKKOS_ENABLE_CUDA & KOKKOS_ENABLE_HIP -#endif // LMP_ENABLE_DEVICE +#endif // LMP_KOKKOS_GPU using namespace LAMMPS_NS; @@ -259,10 +257,8 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) // default settings for package kokkos command binsize = 0.0; -#if defined(KOKKOS_ENABLE_CUDA) && defined(MPIX_CUDA_AWARE_SUPPORT) && MPIX_CUDA_AWARE_SUPPORT - gpu_aware_flag = MPIX_Query_cuda_support(); -#elif defined(KOKKOS_ENABLE_HIP) && defined(MPIX_ROCM_AWARE_SUPPORT) && MPIX_ROCM_AWARE_SUPPORT - gpu_aware_flag = MPIX_Query_rocm_support(); +#if defined(LMP_KOKKOS_GPU) + gpu_aware_flag = 1; #else gpu_aware_flag = 0; #endif @@ -299,12 +295,22 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) #ifdef LMP_KOKKOS_GPU // check and warn about GPU-aware MPI availability when using multiple MPI tasks - // change default only if we can safely detect that GPU-aware MPI is not available + // change default only if we can detect that GPU-aware MPI is not available int nmpi = 0; MPI_Comm_size(world,&nmpi); if (nmpi > 1) { + // runtime check for OpenMPI GPU-aware + +#if (OPEN_MPI) +#if (OMPI_MAJOR_VERSION >= 2) && defined(KOKKOS_ENABLE_CUDA) + have_gpu_aware = MPIX_Query_cuda_support(); +#elif (OMPI_MAJOR_VERSION >= 5) && defined(KOKKOS_ENABLE_HIP) + have_gpu_aware = MPIX_Query_rocm_support(); +#endif +#endif + #if defined(MPI_VERSION) && (MPI_VERSION > 2) // Check for IBM Spectrum MPI @@ -312,17 +318,17 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) char mpi_version[MPI_MAX_LIBRARY_VERSION_STRING]; MPI_Get_library_version(mpi_version, &len); if (strstr(&mpi_version[0], "Spectrum") != nullptr) { - gpu_aware_flag = 0; char* str; + have_gpu_aware = 0; if ((str = getenv("OMPI_MCA_pml_pami_enable_cuda"))) - if ((strcmp(str,"1") == 0)) { + if ((strcmp(str,"1") == 0)) have_gpu_aware = 1; - gpu_aware_flag = 1; - } - if (!gpu_aware_flag) + if (!have_gpu_aware) { if (me == 0) error->warning(FLERR,"The Spectrum MPI '-gpu' flag is not set. Disabling GPU-aware MPI"); + gpu_aware_flag = 0; + } } #endif @@ -332,27 +338,32 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) "use '-pk kokkos gpu/aware on' to override"); gpu_aware_flag = 0; } else if (have_gpu_aware == -1) { // maybe we are dealing with MPICH, MVAPICH2 or some derivative? - // MVAPICH2 + // MVAPICH2 #if defined(MPICH) && defined(MVAPICH2_VERSION) char* str; - gpu_aware_flag = 0; + have_gpu_aware = 0; if ((str = getenv("MV2_USE_CUDA"))) if ((strcmp(str,"1") == 0)) - gpu_aware_flag = 1; + have_gpu_aware = 1; - if (!gpu_aware_flag) + if (!have_gpu_aware) { if (me == 0) error->warning(FLERR,"MVAPICH2 'MV2_USE_CUDA' environment variable is not set. Disabling GPU-aware MPI"); + gpu_aware_flag = 0; + } // pure MPICH or some unsupported MPICH derivative #elif defined(MPICH) && !defined(MVAPICH2_VERSION) char* str; - gpu_aware_flag = 0; + have_gpu_aware = 0; if ((str = getenv("MPICH_GPU_SUPPORT_ENABLED"))) if ((strcmp(str,"1") == 0)) - gpu_aware_flag = 1; + have_gpu_aware = 1; - if (!gpu_aware_flag && me == 0) - error->warning(FLERR,"Detected MPICH. Disabling GPU-aware MPI"); + if (!have_gpu_aware) { + if (me == 0) + error->warning(FLERR,"Detected MPICH. Disabling GPU-aware MPI"); + gpu_aware_flag = 0; + } #else if (me == 0) error->warning(FLERR,"Kokkos with GPU-enabled backend assumes GPU-aware MPI is available," @@ -360,9 +371,9 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) " '-pk kokkos gpu/aware off' if getting segmentation faults"); #endif - } // if (-1 == have_gpu_aware) + } // if (have_gpu_aware == -1) } // nmpi > 0 -#endif // LMP_ENABLE_DEVICE +#endif // LMP_KOKKOS_GPU #ifdef KILL_KOKKOS_ON_SIGSEGV signal(SIGSEGV, my_signal_handler); From 16dd61ca5f138fe8ddab162667bfe66de0da4f15 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Fri, 27 Oct 2023 09:48:26 -0600 Subject: [PATCH 05/17] Remove redundant compile-time checks --- src/KOKKOS/kokkos.cpp | 106 ++++++++++++------------------------------ 1 file changed, 31 insertions(+), 75 deletions(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index b190c7f6b6..ace1d0f575 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -33,62 +33,6 @@ #include // for getpid() #endif -#ifdef LMP_KOKKOS_GPU - -// for detecting GPU-aware MPI support: -// the variable int have_gpu_aware -// - is 1 if GPU-aware MPI support is available -// - is 0 if GPU-aware MPI support is unavailable -// - is -1 if GPU-aware MPI support is unknown - -#define GPU_AWARE_UNKNOWN static int have_gpu_aware = -1; - -#if defined(KOKKOS_ENABLE_SYCL) || defined(KOKKOS_ENABLE_OPENMPTARGET) -GPU_AWARE_UNKNOWN -#elif defined(KOKKOS_ENABLE_CUDA) - -// OpenMPI supports detecting GPU-aware MPI as of version 2.0.0 -#if (OPEN_MPI) -#if (OMPI_MAJOR_VERSION >= 2) -#include -#if defined(MPIX_CUDA_AWARE_SUPPORT) && MPIX_CUDA_AWARE_SUPPORT -static int have_gpu_aware = 1; -#elif defined(MPIX_CUDA_AWARE_SUPPORT) && !MPIX_CUDA_AWARE_SUPPORT -static int have_gpu_aware = 0; -#else -GPU_AWARE_UNKNOWN -#endif // defined(MPIX_CUDA_AWARE_SUPPORT) -#else // old OpenMPI -GPU_AWARE_UNKNOWN -#endif // (OMPI_MAJOR_VERSION >=2) -#else // unknown MPI library -GPU_AWARE_UNKNOWN -#endif // OPEN_MPI - -#elif defined(KOKKOS_ENABLE_HIP) - -// OpenMPI supports detecting HIP-aware MPI as of version 5.0.0 -#if (OPEN_MPI) -#if (OMPI_MAJOR_VERSION >= 5) -#include -#if defined(MPIX_ROCM_AWARE_SUPPORT) && MPIX_ROCM_AWARE_SUPPORT -static int have_gpu_aware = 1; -#elif defined(MPIX_ROCM_AWARE_SUPPORT) && !MPIX_ROCM_AWARE_SUPPORT -static int have_gpu_aware = 0; -#else -GPU_AWARE_UNKNOWN -#endif // defined(OMPI_HAVE_MPI_EXT_ROCM) -#else // old OpenMPI -GPU_AWARE_UNKNOWN -#endif // (OMPI_MAJOR_VERSION >=5) -#else // unknown MPI library -GPU_AWARE_UNKNOWN -#endif // OPEN_MPI - -#endif // KOKKOS_ENABLE_CUDA & KOKKOS_ENABLE_HIP - -#endif // LMP_KOKKOS_GPU - using namespace LAMMPS_NS; int KokkosLMP::is_finalized = 0; @@ -301,18 +245,35 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) MPI_Comm_size(world,&nmpi); if (nmpi > 1) { - // runtime check for OpenMPI GPU-aware - + // for detecting GPU-aware MPI support: + // the variable int have_gpu_aware + // - is 1 if GPU-aware MPI support is available + // - is 0 if GPU-aware MPI support is unavailable + // - is -1 if GPU-aware MPI support is unknown + + int have_gpu_aware = -1; + + // OpenMPI + #if (OPEN_MPI) + have_gpu_aware = 0; #if (OMPI_MAJOR_VERSION >= 2) && defined(KOKKOS_ENABLE_CUDA) - have_gpu_aware = MPIX_Query_cuda_support(); + have_gpu_aware = MPIX_Query_cuda_support(); #elif (OMPI_MAJOR_VERSION >= 5) && defined(KOKKOS_ENABLE_HIP) - have_gpu_aware = MPIX_Query_rocm_support(); -#endif + have_gpu_aware = MPIX_Query_rocm_support(); #endif + if (gpu_aware_flag == 1 && have_gpu_aware == 0) { + if (me == 0) + error->warning(FLERR,"Turning off GPU-aware MPI since it is not detected, " + "use '-pk kokkos gpu/aware on' to override"); + gpu_aware_flag = 0; + } +#endif + + // IBM Spectrum MPI + #if defined(MPI_VERSION) && (MPI_VERSION > 2) - // Check for IBM Spectrum MPI int len; char mpi_version[MPI_MAX_LIBRARY_VERSION_STRING]; @@ -332,12 +293,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) } #endif - if (gpu_aware_flag == 1 && have_gpu_aware == 0) { - if (me == 0) - error->warning(FLERR,"Turning off GPU-aware MPI since it is not detected, " - "use '-pk kokkos gpu/aware on' to override"); - gpu_aware_flag = 0; - } else if (have_gpu_aware == -1) { // maybe we are dealing with MPICH, MVAPICH2 or some derivative? + if (have_gpu_aware == -1) { // MVAPICH2 #if defined(MPICH) && defined(MVAPICH2_VERSION) char* str; @@ -351,7 +307,8 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) error->warning(FLERR,"MVAPICH2 'MV2_USE_CUDA' environment variable is not set. Disabling GPU-aware MPI"); gpu_aware_flag = 0; } - // pure MPICH or some unsupported MPICH derivative + // pure MPICH or some MPICH derivative + // check for Cray MPICH which has GPU-aware support #elif defined(MPICH) && !defined(MVAPICH2_VERSION) char* str; have_gpu_aware = 0; @@ -365,13 +322,12 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) gpu_aware_flag = 0; } #else - if (me == 0) - error->warning(FLERR,"Kokkos with GPU-enabled backend assumes GPU-aware MPI is available," - " but cannot determine if this is the case\n try" - " '-pk kokkos gpu/aware off' if getting segmentation faults"); - + if (me == 0) + error->warning(FLERR,"Kokkos with GPU-enabled backend assumes GPU-aware MPI is available," + " but cannot determine if this is the case\n try" + " '-pk kokkos gpu/aware off' if getting segmentation faults"); #endif - } // if (have_gpu_aware == -1) + } } // nmpi > 0 #endif // LMP_KOKKOS_GPU From 0ab687040211409e7080d917596755eac0145500 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Fri, 27 Oct 2023 10:31:24 -0600 Subject: [PATCH 06/17] Need to include MPI header --- src/KOKKOS/kokkos.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index ace1d0f575..41417c66ae 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -257,10 +257,13 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) #if (OPEN_MPI) have_gpu_aware = 0; -#if (OMPI_MAJOR_VERSION >= 2) && defined(KOKKOS_ENABLE_CUDA) +#if (OMPI_MAJOR_VERSION >= 2) +#include +#if defined(KOKKOS_ENABLE_CUDA) have_gpu_aware = MPIX_Query_cuda_support(); #elif (OMPI_MAJOR_VERSION >= 5) && defined(KOKKOS_ENABLE_HIP) have_gpu_aware = MPIX_Query_rocm_support(); +#endif #endif if (gpu_aware_flag == 1 && have_gpu_aware == 0) { From e7fc2923a52e0af045cb797f88c3a7f5ab6e3c42 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Fri, 27 Oct 2023 14:59:51 -0600 Subject: [PATCH 07/17] whitespace --- src/KOKKOS/kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 41417c66ae..1116808c60 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -254,7 +254,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) int have_gpu_aware = -1; // OpenMPI - + #if (OPEN_MPI) have_gpu_aware = 0; #if (OMPI_MAJOR_VERSION >= 2) From 6c3206f2f63c0d69098e2c9135d85863e0a1356e Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 27 Oct 2023 15:36:22 -0600 Subject: [PATCH 08/17] Tweaks --- src/KOKKOS/kokkos.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 1116808c60..9670e2fbd5 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -33,6 +33,12 @@ #include // for getpid() #endif +#ifdef LMP_KOKKOS_GPU +#if (OPEN_MPI) && (OMPI_MAJOR_VERSION >= 2) +#include +#endif +#endif + using namespace LAMMPS_NS; int KokkosLMP::is_finalized = 0; @@ -256,23 +262,32 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) // OpenMPI #if (OPEN_MPI) - have_gpu_aware = 0; #if (OMPI_MAJOR_VERSION >= 2) -#include + #if defined(KOKKOS_ENABLE_CUDA) have_gpu_aware = MPIX_Query_cuda_support(); -#elif (OMPI_MAJOR_VERSION >= 5) && defined(KOKKOS_ENABLE_HIP) +#endif + +#if defined(KOKKOS_ENABLE_HIP) +#if (OMPI_MAJOR_VERSION >= 5) have_gpu_aware = MPIX_Query_rocm_support(); +#else + have_gpu_aware = 0; #endif #endif +#else + have_gpu_aware = 0; +#endif // OMPI_MAJOR_VERSION >= 2 + if (gpu_aware_flag == 1 && have_gpu_aware == 0) { if (me == 0) error->warning(FLERR,"Turning off GPU-aware MPI since it is not detected, " "use '-pk kokkos gpu/aware on' to override"); gpu_aware_flag = 0; } -#endif + +#endif // OPEN_MPI // IBM Spectrum MPI From c5c816e36074b704449abbcd073afb029e0d7de7 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Sat, 28 Oct 2023 20:14:53 -0600 Subject: [PATCH 09/17] Add another check --- src/KOKKOS/kokkos.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 9670e2fbd5..f702c8a2d1 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -265,13 +265,15 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) #if (OMPI_MAJOR_VERSION >= 2) #if defined(KOKKOS_ENABLE_CUDA) +#if defined(OMPI_HAVE_MPI_EXT_CUDA) && OMPI_HAVE_MPI_EXT_CUDA have_gpu_aware = MPIX_Query_cuda_support(); #endif +#endif #if defined(KOKKOS_ENABLE_HIP) -#if (OMPI_MAJOR_VERSION >= 5) +#if defined(OMPI_HAVE_MPI_EXT_ROCM) && OMPI_HAVE_MPI_EXT_ROCM have_gpu_aware = MPIX_Query_rocm_support(); -#else +#elif (OMPI_MAJOR_VERSION < 5) have_gpu_aware = 0; #endif #endif From 549ea506d4d8cd9a7e85aee85fe4fd59fc8aef62 Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Sun, 29 Oct 2023 15:46:55 -0400 Subject: [PATCH 10/17] add var keyword to fix_deposit borrowed from create_atoms --- src/fix_deposit.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++-- src/fix_deposit.h | 6 +++- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/src/fix_deposit.cpp b/src/fix_deposit.cpp index d2bcb3e855..7f11987ad7 100644 --- a/src/fix_deposit.cpp +++ b/src/fix_deposit.cpp @@ -20,6 +20,7 @@ #include "domain.h" #include "error.h" #include "fix.h" +#include "input.h" #include "lattice.h" #include "math_const.h" #include "math_extra.h" @@ -29,6 +30,7 @@ #include "random_park.h" #include "region.h" #include "update.h" +#include "variable.h" #include #include @@ -209,6 +211,10 @@ FixDeposit::~FixDeposit() delete [] idrigid; delete [] idshake; delete [] idregion; + delete [] vstr; + delete [] xstr; + delete [] ystr; + delete [] zstr; memory->destroy(coords); memory->destroy(imageflags); } @@ -361,6 +367,8 @@ void FixDeposit::pre_exchange() } while (iregion->match(coord[0],coord[1],coord[2]) == 0); } else error->all(FLERR,"Unknown particle distribution in fix deposit"); + if (varflag && vartest(coord[0],coord[1],coord[2]) == 0) continue; + // adjust vertical coord by offset if (dimension == 2) coord[1] += offset; @@ -583,8 +591,10 @@ void FixDeposit::pre_exchange() // warn if not successful b/c too many attempts - if (!success && comm->me == 0) - error->warning(FLERR,"Particle deposition was unsuccessful"); + if (warnflag && !success && comm->me == 0) { + error->warning(FLERR,"One or more particle depositions were unsuccessful"); + warnflag = 0; + } // reset global natoms,nbonds,etc // increment maxtag_all and maxmol_all if necessary @@ -661,6 +671,8 @@ void FixDeposit::options(int narg, char **arg) iregion = nullptr; idregion = nullptr; + varflag = 0; + vstr = xstr = ystr = zstr = nullptr; mode = ATOM; molfrac = nullptr; rigidflag = 0; @@ -680,6 +692,7 @@ void FixDeposit::options(int narg, char **arg) scaleflag = 1; targetflag = 0; orientflag = 0; + warnflag = 1; rx = 0.0; ry = 0.0; rz = 0.0; @@ -693,6 +706,27 @@ void FixDeposit::options(int narg, char **arg) idregion = utils::strdup(arg[iarg+1]); iarg += 2; + } else if (strcmp(arg[iarg], "var") == 0) { + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "create_atoms var", error); + delete[] vstr; + vstr = utils::strdup(arg[iarg + 1]); + varflag = 1; + iarg += 2; + } else if (strcmp(arg[iarg], "set") == 0) { + if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, "create_atoms set", error); + if (strcmp(arg[iarg + 1], "x") == 0) { + delete[] xstr; + xstr = utils::strdup(arg[iarg + 2]); + } else if (strcmp(arg[iarg + 1], "y") == 0) { + delete[] ystr; + ystr = utils::strdup(arg[iarg + 2]); + } else if (strcmp(arg[iarg + 1], "z") == 0) { + delete[] zstr; + zstr = utils::strdup(arg[iarg + 2]); + } else + error->all(FLERR, "Unknown create_atoms set option {}", arg[iarg + 2]); + iarg += 3; + } else if (strcmp(arg[iarg],"mol") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix deposit command"); int imol = atom->find_molecule(arg[iarg+1]); @@ -815,6 +849,39 @@ void FixDeposit::options(int narg, char **arg) iarg += 4; } else error->all(FLERR,"Illegal fix deposit command"); } + + // error check and further setup for variable test + + if (!vstr && (xstr || ystr || zstr)) + error->all(FLERR, "Incomplete use of variables in create_atoms command"); + if (vstr && (!xstr && !ystr && !zstr)) + error->all(FLERR, "Incomplete use of variables in create_atoms command"); + + if (varflag) { + vvar = input->variable->find(vstr); + if (vvar < 0) error->all(FLERR, "Variable {} for create_atoms does not exist", vstr); + if (!input->variable->equalstyle(vvar)) + error->all(FLERR, "Variable for create_atoms is invalid style"); + + if (xstr) { + xvar = input->variable->find(xstr); + if (xvar < 0) error->all(FLERR, "Variable {} for create_atoms does not exist", xstr); + if (!input->variable->internalstyle(xvar)) + error->all(FLERR, "Variable for create_atoms is invalid style"); + } + if (ystr) { + yvar = input->variable->find(ystr); + if (yvar < 0) error->all(FLERR, "Variable {} for create_atoms does not exist", ystr); + if (!input->variable->internalstyle(yvar)) + error->all(FLERR, "Variable for create_atoms is invalid style"); + } + if (zstr) { + zvar = input->variable->find(zstr); + if (zvar < 0) error->all(FLERR, "Variable {} for create_atoms does not exist", zstr); + if (!input->variable->internalstyle(zvar)) + error->all(FLERR, "Variable for create_atoms is invalid style"); + } + } } /* ---------------------------------------------------------------------- @@ -908,3 +975,20 @@ void *FixDeposit::extract(const char *str, int &itype) return nullptr; } + +/* ---------------------------------------------------------------------- + test a generated atom position against variable evaluation + first set x,y,z values in internal variables +------------------------------------------------------------------------- */ + +int FixDeposit::vartest(double x, double y, double z) +{ + if (xstr) input->variable->internal_set(xvar, x); + if (ystr) input->variable->internal_set(yvar, y); + if (zstr) input->variable->internal_set(zvar, z); + + double value = input->variable->compute_equal(vvar); + + if (value == 0.0) return 0; + return 1; +} diff --git a/src/fix_deposit.h b/src/fix_deposit.h index 2b866dc068..5d2824fba3 100644 --- a/src/fix_deposit.h +++ b/src/fix_deposit.h @@ -40,7 +40,8 @@ class FixDeposit : public Fix { private: int ninsert, ntype, nfreq, seed; int globalflag, localflag, maxattempt, rateflag, scaleflag, targetflag; - int mode, rigidflag, shakeflag, idnext, distflag, orientflag; + int mode, rigidflag, shakeflag, idnext, distflag, orientflag, warnflag; + int varflag, vvar, xvar, yvar, zvar; double lo, hi, deltasq, nearsq, rate, sigma; double vxlo, vxhi, vylo, vyhi, vzlo, vzhi; double xlo, xhi, ylo, yhi, zlo, zhi, xmid, ymid, zmid; @@ -48,6 +49,8 @@ class FixDeposit : public Fix { class Region *iregion; char *idregion; char *idrigid, *idshake; + char *vstr, *xstr, *ystr, *zstr; + char *xstr_copy, *ystr_copy, *zstr_copy; class Molecule **onemols; int nmol, natom_max; @@ -64,6 +67,7 @@ class FixDeposit : public Fix { void find_maxid(); void options(int, char **); + int vartest(double, double, double); // evaluate a variable with new atom position }; } // namespace LAMMPS_NS From d4ee6f476c0c29dc91b3f7749c41495d1e742e8f Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Sun, 29 Oct 2023 16:13:12 -0400 Subject: [PATCH 11/17] var/set docs for fix_deposit --- doc/src/fix_deposit.rst | 48 ++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/doc/src/fix_deposit.rst b/doc/src/fix_deposit.rst index 08711001c5..72db67343e 100644 --- a/doc/src/fix_deposit.rst +++ b/doc/src/fix_deposit.rst @@ -17,12 +17,16 @@ Syntax * M = insert a single atom or molecule every M steps * seed = random # seed (positive integer) * one or more keyword/value pairs may be appended to args -* keyword = *region* or *id* or *global* or *local* or *near* or *gaussian* or *attempt* or *rate* or *vx* or *vy* or *vz* or *target* or *mol* or *molfrac* or *rigid* or *shake* or *orient* or *units* +* keyword = *region* or *var* or *set* or *id* or *global* or *local* or *near* or *gaussian* or *attempt* or *rate* or *vx* or *vy* or *vz* or *target* or *mol* or *molfrac* or *rigid* or *shake* or *orient* or *units* .. parsed-literal:: *region* value = region-ID region-ID = ID of region to use as insertion volume + *var* value = name = variable name to evaluate for test of atom creation + *set* values = dim name + dim = *x* or *y* or *z* + name = name of variable to set with x, y, or z atom position *id* value = *max* or *next* max = atom ID for new atom(s) is max ID of all current atoms plus one next = atom ID for new atom(s) increments by one for every deposition @@ -193,17 +197,19 @@ simulation that is "nearby" the chosen x,y position. In this context, particles is less than the *delta* setting. Once a trial x,y,z position has been selected, the insertion is only -performed if no current atom in the simulation is within a distance R -of any atom in the new particle, including the effect of periodic -boundary conditions if applicable. R is defined by the *near* -keyword. Note that the default value for R is 0.0, which will allow -atoms to strongly overlap if you are inserting where other atoms are -present. This distance test is performed independently for each atom -in an inserted molecule, based on the randomly rotated configuration -of the molecule. If this test fails, a new random position within the -insertion volume is chosen and another trial is made. Up to Q -attempts are made. If the particle is not successfully inserted, -LAMMPS prints a warning message. +performed if both the *near* and *var* keywords are satisfied (see below). +If either the *near* or the *var* keyword is not satisfied, a new random +position within the insertion volume is chosen and another trial is made. +Up to Q attempts are made. If one or more particle insertions are not +successful, LAMMPS prints a warning message. + +The *near* keyword ensures that no current atom in the simulation is within +a distance R of any atom in the new particle, including the effect of +periodic boundary conditions if applicable. Note that the default value +for R is 0.0, which will allow atoms to strongly overlap if you are +inserting where other atoms are present. This distance test is performed +independently for each atom in an inserted molecule, based on the randomly +rotated configuration of the molecule. .. note:: @@ -214,6 +220,24 @@ LAMMPS prints a warning message. existing particle. LAMMPS will issue a warning if R is smaller than this value, based on the radii of existing and inserted particles. +The *var* and *set* keywords can be used together to provide a criterion +for accepting or rejecting the addition of an individual atom, based on its +coordinates. The *name* specified for the *var* keyword is the name of an +:doc:`equal-style variable ` that should evaluate to a zero or +non-zero value based on one or two or three variables that will store the +*x*, *y*, or *z* coordinates of an atom (one variable per coordinate). If +used, these other variables must be :doc:`internal-style variables +` defined in the input script; their initial numeric value can be +anything. They must be internal-style variables, because this command +resets their values directly. The *set* keyword is used to identify the +names of these other variables, one variable for the *x*-coordinate of a +created atom, one for *y*, and one for *z*. When an atom is created, its +:math:`(x,y,z)` coordinates become the values for any *set* variable that +is defined. The *var* variable is then evaluated. If the returned value +is 0.0, the atom is not created. If it is non-zero, the atom is created. +For an example of how to use these keywords, see the +:doc:`create_atoms `command. + The *rate* option moves the insertion volume in the z direction (3d) or y direction (2d). This enables particles to be inserted from a successively higher height over time. Note that this parameter is From f3a7ec8c55e5ae5e81d799e49b34030575a421e2 Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Sun, 29 Oct 2023 16:19:11 -0400 Subject: [PATCH 12/17] copy/paste issues --- src/fix_deposit.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/fix_deposit.cpp b/src/fix_deposit.cpp index 7f11987ad7..6dea4a0932 100644 --- a/src/fix_deposit.cpp +++ b/src/fix_deposit.cpp @@ -707,13 +707,13 @@ void FixDeposit::options(int narg, char **arg) iarg += 2; } else if (strcmp(arg[iarg], "var") == 0) { - if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "create_atoms var", error); + if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "fix deposit var", error); delete[] vstr; vstr = utils::strdup(arg[iarg + 1]); varflag = 1; iarg += 2; } else if (strcmp(arg[iarg], "set") == 0) { - if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, "create_atoms set", error); + if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, "fix deposit set", error); if (strcmp(arg[iarg + 1], "x") == 0) { delete[] xstr; xstr = utils::strdup(arg[iarg + 2]); @@ -724,7 +724,7 @@ void FixDeposit::options(int narg, char **arg) delete[] zstr; zstr = utils::strdup(arg[iarg + 2]); } else - error->all(FLERR, "Unknown create_atoms set option {}", arg[iarg + 2]); + error->all(FLERR, "Unknown fix deposit set option {}", arg[iarg + 2]); iarg += 3; } else if (strcmp(arg[iarg],"mol") == 0) { @@ -853,33 +853,33 @@ void FixDeposit::options(int narg, char **arg) // error check and further setup for variable test if (!vstr && (xstr || ystr || zstr)) - error->all(FLERR, "Incomplete use of variables in create_atoms command"); + error->all(FLERR, "Incomplete use of variables in fix deposit command"); if (vstr && (!xstr && !ystr && !zstr)) - error->all(FLERR, "Incomplete use of variables in create_atoms command"); + error->all(FLERR, "Incomplete use of variables in fix deposit command"); if (varflag) { vvar = input->variable->find(vstr); - if (vvar < 0) error->all(FLERR, "Variable {} for create_atoms does not exist", vstr); + if (vvar < 0) error->all(FLERR, "Variable {} for fix deposit does not exist", vstr); if (!input->variable->equalstyle(vvar)) - error->all(FLERR, "Variable for create_atoms is invalid style"); + error->all(FLERR, "Variable for fix deposit is invalid style"); if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all(FLERR, "Variable {} for create_atoms does not exist", xstr); + if (xvar < 0) error->all(FLERR, "Variable {} for fix deposit does not exist", xstr); if (!input->variable->internalstyle(xvar)) - error->all(FLERR, "Variable for create_atoms is invalid style"); + error->all(FLERR, "Variable for fix deposit is invalid style"); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all(FLERR, "Variable {} for create_atoms does not exist", ystr); + if (yvar < 0) error->all(FLERR, "Variable {} for fix deposit does not exist", ystr); if (!input->variable->internalstyle(yvar)) - error->all(FLERR, "Variable for create_atoms is invalid style"); + error->all(FLERR, "Variable for fix deposit is invalid style"); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all(FLERR, "Variable {} for create_atoms does not exist", zstr); + if (zvar < 0) error->all(FLERR, "Variable {} for fix deposit does not exist", zstr); if (!input->variable->internalstyle(zvar)) - error->all(FLERR, "Variable for create_atoms is invalid style"); + error->all(FLERR, "Variable for fix deposit is invalid style"); } } } From 17640f54d2a43a71f4bd8bdc5e333575afec5548 Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Sat, 4 Nov 2023 17:53:19 -0400 Subject: [PATCH 13/17] reset warnflag for each run --- src/fix_deposit.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fix_deposit.cpp b/src/fix_deposit.cpp index 6dea4a0932..4a9c5aa9da 100644 --- a/src/fix_deposit.cpp +++ b/src/fix_deposit.cpp @@ -232,6 +232,8 @@ int FixDeposit::setmask() void FixDeposit::init() { + warnflag = 1; + // set index and check validity of region iregion = domain->get_region_by_id(idregion); From 6fef7871e8dd1639140fd1cba41fc7c27fae8be0 Mon Sep 17 00:00:00 2001 From: yury-lysogorskiy Date: Tue, 7 Nov 2023 16:46:47 +0100 Subject: [PATCH 14/17] Update pair_pace_extrapolation.cpp BUGFIX: pair_pace_extrapolation: setup flag aceimpl->ace->compute_projections = true before computing extrapolation grade --- src/ML-PACE/pair_pace_extrapolation.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ML-PACE/pair_pace_extrapolation.cpp b/src/ML-PACE/pair_pace_extrapolation.cpp index 8a0116526a..dc0fb1848b 100644 --- a/src/ML-PACE/pair_pace_extrapolation.cpp +++ b/src/ML-PACE/pair_pace_extrapolation.cpp @@ -202,8 +202,10 @@ void PairPACEExtrapolation::compute(int eflag, int vflag) // jnum(0) = 50 // jlist(neigh ind of 0-atom) = [1,2,10,7,99,25, .. 50 element in total] try { - if (flag_compute_extrapolation_grade) + if (flag_compute_extrapolation_grade) { + aceimpl->ace->compute_projections = true; aceimpl->ace->compute_atom(i, x, type, jnum, jlist); + } else aceimpl->rec_ace->compute_atom(i, x, type, jnum, jlist); } catch (std::exception &e) { From 46768d0ff3dd2a201afb4d78400d92b6d467b8a2 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Mon, 6 Nov 2023 23:18:42 -0700 Subject: [PATCH 15/17] Correctly build argv with nullptr at the end --- src/angle_write.cpp | 8 +- src/dihedral_write.cpp | 8 +- src/lammps.cpp | 23 +++++ src/lammps.h | 6 ++ unittest/c-library/test_library_commands.cpp | 5 +- unittest/c-library/test_library_config.cpp | 5 +- unittest/c-library/test_library_external.cpp | 8 +- unittest/c-library/test_library_mpi.cpp | 20 ++-- unittest/c-library/test_library_open.cpp | 20 ++-- .../c-library/test_library_properties.cpp | 13 +-- .../c-library/test_library_scatter_gather.cpp | 5 +- unittest/commands/test_mpi_load_balancing.cpp | 6 +- unittest/cplusplus/test_input_class.cpp | 15 ++- unittest/cplusplus/test_lammps_class.cpp | 52 +++++------ unittest/force-styles/test_angle_style.cpp | 44 +++------ unittest/force-styles/test_bond_style.cpp | 44 +++------ unittest/force-styles/test_dihedral_style.cpp | 32 +++---- unittest/force-styles/test_fix_timestep.cpp | 30 +++--- unittest/force-styles/test_improper_style.cpp | 30 +++--- unittest/force-styles/test_pair_style.cpp | 92 +++++++------------ unittest/fortran/wrap_extract_variable.cpp | 4 +- unittest/testing/core.h | 20 +--- 22 files changed, 207 insertions(+), 283 deletions(-) diff --git a/src/angle_write.cpp b/src/angle_write.cpp index e64c2f23c8..fb0e65ccf5 100644 --- a/src/angle_write.cpp +++ b/src/angle_write.cpp @@ -123,11 +123,9 @@ void AngleWrite::command(int narg, char **arg) if (comm->me == 0) { // set up new LAMMPS instance with dummy system to evaluate angle potential - const char *args[] = {"AngleWrite", "-nocite", "-echo", "none", - "-log", "none", "-screen", "none"}; - char **argv = (char **) args; - int argc = sizeof(args) / sizeof(char *); - LAMMPS *writer = new LAMMPS(argc, argv, singlecomm); + LAMMPS::argv args = {"AngleWrite", "-nocite", "-echo", "none", + "-log", "none", "-screen", "none"}; + LAMMPS *writer = new LAMMPS(args, singlecomm); // create dummy system replicating angle style settings writer->input->one(fmt::format("units {}", update->unit_style)); diff --git a/src/dihedral_write.cpp b/src/dihedral_write.cpp index 285d9cf931..3d87591bcc 100644 --- a/src/dihedral_write.cpp +++ b/src/dihedral_write.cpp @@ -124,12 +124,8 @@ void DihedralWrite::command(int narg, char **arg) if (comm->me == 0) { // set up new LAMMPS instance with dummy system to evaluate dihedral potential - // const char *args[] = {"DihedralWrite", "-nocite", "-echo", "none", - // "-log", "none", "-screen", "none"}; - const char *args[] = {"DihedralWrite", "-nocite", "-echo", "screen", "-log", "none"}; - char **argv = (char **) args; - int argc = sizeof(args) / sizeof(char *); - LAMMPS *writer = new LAMMPS(argc, argv, singlecomm); + LAMMPS::argv args = {"DihedralWrite", "-nocite", "-echo", "screen", "-log", "none"}; + LAMMPS *writer = new LAMMPS(args, singlecomm); // create dummy system replicating dihedral style settings writer->input->one(fmt::format("units {}", update->unit_style)); diff --git a/src/lammps.cpp b/src/lammps.cpp index 6fc06521d1..c0336ee588 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -107,6 +107,15 @@ using namespace LAMMPS_NS; * The specifics of setting up and running a simulation are handled by the * individual component class instances. */ +/** Create a LAMMPS simulation instance + * + * \param args list of arguments + * \param communicator MPI communicator used by this LAMMPS instance + */ +LAMMPS::LAMMPS(argv & args, MPI_Comm communicator) : + LAMMPS(args.size(), argv_pointers(args).data(), communicator) { +} + /** Create a LAMMPS simulation instance * * The LAMMPS constructor starts up a simulation by allocating all @@ -1464,3 +1473,17 @@ void LAMMPS::print_config(FILE *fp) } fputs("\n\n",fp); } + +/** Create vector of argv string pointers including terminating nullptr element + * + * \param args list of arguments + */ +std::vector LAMMPS::argv_pointers(argv & args){ + std::vector r; + r.reserve(args.size()+1); + for(auto & a : args) { + r.push_back((char*)a.data()); + } + r.push_back(nullptr); + return r; +} diff --git a/src/lammps.h b/src/lammps.h index 05a215eeac..4ec3f384d9 100644 --- a/src/lammps.h +++ b/src/lammps.h @@ -16,6 +16,8 @@ #include #include +#include +#include namespace LAMMPS_NS { @@ -84,6 +86,10 @@ class LAMMPS { static const char *git_branch(); static const char *git_descriptor(); + using argv = std::vector; + static std::vector argv_pointers(argv & args); + + LAMMPS(argv & args, MPI_Comm); LAMMPS(int, char **, MPI_Comm); ~LAMMPS() noexcept(false); void create(); diff --git a/unittest/c-library/test_library_commands.cpp b/unittest/c-library/test_library_commands.cpp index d4e326cd36..31f8268a8f 100644 --- a/unittest/c-library/test_library_commands.cpp +++ b/unittest/c-library/test_library_commands.cpp @@ -26,10 +26,11 @@ protected: void SetUp() override { const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite", - "-var", "x", "2", "-var", "zpos", "1.5"}; + "-var", "x", "2", "-var", "zpos", "1.5", + nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); lmp = lammps_open_no_mpi(argc, argv, nullptr); diff --git a/unittest/c-library/test_library_config.cpp b/unittest/c-library/test_library_config.cpp index 78d6439c17..64a5ee89be 100644 --- a/unittest/c-library/test_library_config.cpp +++ b/unittest/c-library/test_library_config.cpp @@ -29,10 +29,11 @@ protected: { const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite", - "-var", "input_dir", STRINGIFY(TEST_INPUT_FOLDER)}; + "-var", "input_dir", STRINGIFY(TEST_INPUT_FOLDER), + nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); lmp = lammps_open_no_mpi(argc, argv, nullptr); diff --git a/unittest/c-library/test_library_external.cpp b/unittest/c-library/test_library_external.cpp index 57d3bef080..9011ac19a8 100644 --- a/unittest/c-library/test_library_external.cpp +++ b/unittest/c-library/test_library_external.cpp @@ -64,9 +64,9 @@ static void callback(void *handle, step_t timestep, int nlocal, tag_t *, double TEST(lammps_external, callback) { - const char *args[] = {"liblammps", "-log", "none", "-nocite"}; + const char *args[] = {"liblammps", "-log", "none", "-nocite", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); void *handle = lammps_open_no_mpi(argc, argv, nullptr); @@ -131,9 +131,9 @@ TEST(lammps_external, callback) TEST(lammps_external, array) { - const char *args[] = {"liblammps", "-log", "none", "-nocite"}; + const char *args[] = {"liblammps", "-log", "none", "-nocite", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); void *handle = lammps_open_no_mpi(argc, argv, nullptr); diff --git a/unittest/c-library/test_library_mpi.cpp b/unittest/c-library/test_library_mpi.cpp index 1609107ae0..f60105a229 100644 --- a/unittest/c-library/test_library_mpi.cpp +++ b/unittest/c-library/test_library_mpi.cpp @@ -34,9 +34,9 @@ TEST(MPI, global_box) int boxflag; ::testing::internal::CaptureStdout(); - const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite"}; + const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; void *lmp = lammps_open(argc, argv, MPI_COMM_WORLD, nullptr); lammps_command(lmp, "units lj"); lammps_command(lmp, "atom_style atomic"); @@ -77,9 +77,9 @@ TEST(MPI, sub_box) int boxflag; ::testing::internal::CaptureStdout(); - const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite"}; + const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; void *lmp = lammps_open(argc, argv, MPI_COMM_WORLD, nullptr); lammps_command(lmp, "units lj"); lammps_command(lmp, "atom_style atomic"); @@ -143,9 +143,9 @@ TEST(MPI, split_comm) MPI_Comm_split(MPI_COMM_WORLD, color, key, &newcomm); - const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite"}; + const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; void *lmp = lammps_open(argc, argv, newcomm, nullptr); lammps_command(lmp, "units lj"); lammps_command(lmp, "atom_style atomic"); @@ -173,9 +173,9 @@ TEST(MPI, multi_partition) MPI_Comm_rank(MPI_COMM_WORLD, &me); const char *args[] = {"LAMMPS_test", "-log", "none", "-partition", "4x1", - "-echo", "screen", "-nocite", "-in", "none"}; + "-echo", "screen", "-nocite", "-in", "none", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; void *lmp = lammps_open(argc, argv, MPI_COMM_WORLD, nullptr); lammps_command(lmp, "units lj"); @@ -205,9 +205,9 @@ protected: void SetUp() override { - const char *args[] = {testbinary, "-log", "none", "-echo", "screen", "-nocite"}; + const char *args[] = {testbinary, "-log", "none", "-echo", "screen", "-nocite", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; if (!verbose) ::testing::internal::CaptureStdout(); lmp = lammps_open(argc, argv, MPI_COMM_WORLD, nullptr); InitSystem(); diff --git a/unittest/c-library/test_library_open.cpp b/unittest/c-library/test_library_open.cpp index 1cd65d843d..267f8e0978 100644 --- a/unittest/c-library/test_library_open.cpp +++ b/unittest/c-library/test_library_open.cpp @@ -39,9 +39,9 @@ TEST(lammps_open, null_args) TEST(lammps_open, with_args) { - const char *args[] = {"liblammps", "-log", "none", "-nocite"}; + const char *args[] = {"liblammps", "-log", "none", "-nocite", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; // MPI is already initialized MPI_Comm mycomm; @@ -78,9 +78,9 @@ TEST(lammps_open, with_args) TEST(lammps_open, with_kokkos) { if (!LAMMPS_NS::LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP(); - const char *args[] = {"liblammps", "-k", "on", "t", "2", "-sf", "kk", "-log", "none"}; + const char *args[] = {"liblammps", "-k", "on", "t", "2", "-sf", "kk", "-log", "none", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); void *alt_ptr; @@ -108,9 +108,9 @@ TEST(lammps_open, with_kokkos) TEST(lammps_open_no_mpi, no_screen) { - const char *args[] = {"liblammps", "-log", "none", "-screen", "none", "-nocite"}; + const char *args[] = {"liblammps", "-log", "none", "-screen", "none", "-nocite", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); void *alt_ptr; @@ -139,9 +139,9 @@ TEST(lammps_open_no_mpi, with_omp) { if (!LAMMPS_NS::LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); const char *args[] = {"liblammps", "-pk", "omp", "2", "neigh", "no", - "-sf", "omp", "-log", "none", "-nocite"}; + "-sf", "omp", "-log", "none", "-nocite", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); void *alt_ptr; @@ -201,9 +201,9 @@ TEST(lammps_open_fortran, no_args) TEST(lammps_open_no_mpi, lammps_error) { - const char *args[] = {"liblammps", "-log", "none", "-nocite"}; + const char *args[] = {"liblammps", "-log", "none", "-nocite", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); void *alt_ptr; diff --git a/unittest/c-library/test_library_properties.cpp b/unittest/c-library/test_library_properties.cpp index 0c5ad2c809..40d0d08575 100644 --- a/unittest/c-library/test_library_properties.cpp +++ b/unittest/c-library/test_library_properties.cpp @@ -33,10 +33,11 @@ protected: { const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite", - "-var", "input_dir", STRINGIFY(TEST_INPUT_FOLDER)}; + "-var", "input_dir", STRINGIFY(TEST_INPUT_FOLDER), + nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); lmp = lammps_open_no_mpi(argc, argv, nullptr); @@ -551,10 +552,10 @@ protected: void SetUp() override { - const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite"}; + const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite", nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); lmp = lammps_open_no_mpi(argc, argv, nullptr); @@ -632,10 +633,10 @@ TEST(SystemSettings, kokkos) // clang-format off const char *args[] = {"SystemSettings", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk"}; + "-k", "on", "t", "4", "-sf", "kk", nullptr}; // clang-format on char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); void *lmp = lammps_open_no_mpi(argc, argv, nullptr); diff --git a/unittest/c-library/test_library_scatter_gather.cpp b/unittest/c-library/test_library_scatter_gather.cpp index ee672c9b86..0303a47337 100644 --- a/unittest/c-library/test_library_scatter_gather.cpp +++ b/unittest/c-library/test_library_scatter_gather.cpp @@ -32,10 +32,11 @@ protected: { const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite", - "-var", "input_dir", STRINGIFY(TEST_INPUT_FOLDER)}; + "-var", "input_dir", STRINGIFY(TEST_INPUT_FOLDER), + nullptr}; char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + int argc = (sizeof(args) / sizeof(char *)) - 1; ::testing::internal::CaptureStdout(); lmp = lammps_open_no_mpi(argc, argv, nullptr); diff --git a/unittest/commands/test_mpi_load_balancing.cpp b/unittest/commands/test_mpi_load_balancing.cpp index bc5f07beb1..efdee8c4eb 100644 --- a/unittest/commands/test_mpi_load_balancing.cpp +++ b/unittest/commands/test_mpi_load_balancing.cpp @@ -33,11 +33,9 @@ protected: void SetUp() override { - const char *args[] = {testbinary, "-log", "none", "-echo", "screen", "-nocite"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {testbinary, "-log", "none", "-echo", "screen", "-nocite"}; if (!verbose) ::testing::internal::CaptureStdout(); - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + lmp = new LAMMPS(args, MPI_COMM_WORLD); InitSystem(); if (!verbose) ::testing::internal::GetCapturedStdout(); } diff --git a/unittest/cplusplus/test_input_class.cpp b/unittest/cplusplus/test_input_class.cpp index 6595c24695..708d3f7cae 100644 --- a/unittest/cplusplus/test_input_class.cpp +++ b/unittest/cplusplus/test_input_class.cpp @@ -8,6 +8,7 @@ #include #include +#include "../testing/utils.h" #include "gtest/gtest.h" const char *demo_input[] = {"region box block 0 $x 0 2 0 2", "create_box 1 box", @@ -21,9 +22,9 @@ protected: LAMMPS *lmp; Input_commands() { - const char *args[] = {"LAMMPS_test"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + const char * args[] = {"LAMMPS_test", nullptr}; + char ** argv = (char**)args; + int argc = 1; int flag; MPI_Initialized(&flag); @@ -33,13 +34,11 @@ protected: void SetUp() override { - const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite", - "-var", "zpos", "1.5", "-var", "x", "2"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"LAMMPS_test", "-log", "none", "-echo", "screen", "-nocite", + "-var", "zpos", "1.5", "-var", "x", "2"}; ::testing::internal::CaptureStdout(); - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + lmp = new LAMMPS(args, MPI_COMM_WORLD); std::string output = ::testing::internal::GetCapturedStdout(); EXPECT_STREQ(output.substr(0, 8).c_str(), "LAMMPS ("); } diff --git a/unittest/cplusplus/test_lammps_class.cpp b/unittest/cplusplus/test_lammps_class.cpp index 64ce1eefb1..6f279fc96c 100644 --- a/unittest/cplusplus/test_lammps_class.cpp +++ b/unittest/cplusplus/test_lammps_class.cpp @@ -21,9 +21,9 @@ protected: LAMMPS *lmp; LAMMPS_plain() : lmp(nullptr) { - const char *args[] = {"LAMMPS_test"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + const char * args[] = {"LAMMPS_test", nullptr}; + char ** argv = (char**)args; + int argc = 1; int flag; MPI_Initialized(&flag); @@ -34,12 +34,10 @@ protected: void SetUp() override { - const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "both", "-nocite"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"LAMMPS_test", "-log", "none", "-echo", "both", "-nocite"}; ::testing::internal::CaptureStdout(); - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + lmp = new LAMMPS(args, MPI_COMM_WORLD); std::string output = ::testing::internal::GetCapturedStdout(); EXPECT_THAT(output, StartsWith("LAMMPS (")); } @@ -159,9 +157,9 @@ protected: LAMMPS *lmp; LAMMPS_omp() : lmp(nullptr) { - const char *args[] = {"LAMMPS_test"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + const char * args[] = {"LAMMPS_test", nullptr}; + char ** argv = (char**)args; + int argc = 1; int flag; MPI_Initialized(&flag); @@ -172,15 +170,13 @@ protected: void SetUp() override { - const char *args[] = {"LAMMPS_test", "-log", "none", "-screen", "none", "-echo", "screen", - "-pk", "omp", "2", "neigh", "yes", "-sf", "omp"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"LAMMPS_test", "-log", "none", "-screen", "none", "-echo", "screen", + "-pk", "omp", "2", "neigh", "yes", "-sf", "omp"}; // only run this test fixture with omp suffix if OPENMP package is installed if (LAMMPS::is_installed_pkg("OPENMP")) - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + lmp = new LAMMPS(args, MPI_COMM_WORLD); else GTEST_SKIP(); } @@ -242,9 +238,9 @@ protected: LAMMPS *lmp; LAMMPS_kokkos() : lmp(nullptr) { - const char *args[] = {"LAMMPS_test"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + const char * args[] = {"LAMMPS_test", nullptr}; + char ** argv = (char**)args; + int argc = 1; int flag; MPI_Initialized(&flag); @@ -255,15 +251,13 @@ protected: void SetUp() override { - const char *args[] = {"LAMMPS_test", "-log", "none", "-echo", "none", "-screen", "none", - "-k", "on", "t", "1", "-sf", "kk"}; + LAMMPS::argv args = {"LAMMPS_test", "-log", "none", "-echo", "none", "-screen", "none", + "-k", "on", "t", "1", "-sf", "kk"}; if (Info::has_accelerator_feature("KOKKOS", "api", "openmp")) args[10] = "2"; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); if (LAMMPS::is_installed_pkg("KOKKOS")) { ::testing::internal::CaptureStdout(); - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + lmp = new LAMMPS(args, MPI_COMM_WORLD); ::testing::internal::GetCapturedStdout(); } else GTEST_SKIP(); @@ -333,12 +327,10 @@ TEST(LAMMPS_init, OpenMP) fputs("\n", fp); fclose(fp); - const char *args[] = {"LAMMPS_init", "-in", "in.lammps_empty", "-log", "none", "-nocite"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"LAMMPS_init", "-in", "in.lammps_empty", "-log", "none", "-nocite"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + LAMMPS *lmp = new LAMMPS(args, MPI_COMM_WORLD); std::string output = ::testing::internal::GetCapturedStdout(); EXPECT_THAT(output, ContainsRegex(".*using 2 OpenMP thread.*per MPI task.*")); @@ -366,12 +358,10 @@ TEST(LAMMPS_init, NoOpenMP) fclose(fp); platform::unsetenv("OMP_NUM_THREADS"); - const char *args[] = {"LAMMPS_init", "-in", "in.lammps_class_noomp", "-log", "none", "-nocite"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"LAMMPS_init", "-in", "in.lammps_class_noomp", "-log", "none", "-nocite"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + LAMMPS *lmp = new LAMMPS(args, MPI_COMM_WORLD); std::string output = ::testing::internal::GetCapturedStdout(); EXPECT_THAT(output, ContainsRegex( ".*OMP_NUM_THREADS environment is not set.*Defaulting to 1 thread.*")); diff --git a/unittest/force-styles/test_angle_style.cpp b/unittest/force-styles/test_angle_style.cpp index e9f4a3f7fc..bd0e3d8859 100644 --- a/unittest/force-styles/test_angle_style.cpp +++ b/unittest/force-styles/test_angle_style.cpp @@ -59,11 +59,11 @@ void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg) delete lmp; } -LAMMPS *init_lammps(int argc, char **argv, const TestConfig &cfg, const bool newton = true) +LAMMPS *init_lammps(LAMMPS::argv & args, const TestConfig &cfg, const bool newton = true) { LAMMPS *lmp; - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + lmp = new LAMMPS(args, MPI_COMM_WORLD); // check if prerequisite styles are available Info *info = new Info(lmp); @@ -211,11 +211,9 @@ void data_lammps(LAMMPS *lmp, const TestConfig &cfg) void generate_yaml_file(const char *outfile, const TestConfig &config) { // initialize system geometry - const char *args[] = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"}; + LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); - LAMMPS *lmp = init_lammps(argc, argv, config); + LAMMPS *lmp = init_lammps(args, config); if (!lmp) { std::cerr << "One or more prerequisite styles are not available " "in this LAMMPS configuration:\n"; @@ -303,13 +301,10 @@ TEST(AngleStyle, plain) { if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -358,7 +353,7 @@ TEST(AngleStyle, plain) if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); if (!verbose) ::testing::internal::GetCapturedStdout(); // skip over these tests if newton bond is forced to be on @@ -422,14 +417,11 @@ TEST(AngleStyle, omp) if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite", - "-pk", "omp", "4", "-sf", "omp"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "omp", "4", "-sf", "omp"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -482,7 +474,7 @@ TEST(AngleStyle, omp) if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); if (!verbose) ::testing::internal::GetCapturedStdout(); // skip over these tests if newton bond is forced to be on @@ -525,14 +517,11 @@ TEST(AngleStyle, single) { if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"}; // create a LAMMPS instance with standard settings to detect the number of atom types if (!verbose) ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config); + LAMMPS *lmp = init_lammps(args, test_config); if (!verbose) ::testing::internal::GetCapturedStdout(); if (!lmp) { @@ -672,13 +661,10 @@ TEST(AngleStyle, extract) { if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"}; if (!verbose) ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); if (!verbose) ::testing::internal::GetCapturedStdout(); if (!lmp) { diff --git a/unittest/force-styles/test_bond_style.cpp b/unittest/force-styles/test_bond_style.cpp index c723541366..aa99f41f8d 100644 --- a/unittest/force-styles/test_bond_style.cpp +++ b/unittest/force-styles/test_bond_style.cpp @@ -59,11 +59,11 @@ void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg) delete lmp; } -LAMMPS *init_lammps(int argc, char **argv, const TestConfig &cfg, const bool newton = true) +LAMMPS *init_lammps(LAMMPS::argv & args, const TestConfig &cfg, const bool newton = true) { LAMMPS *lmp; - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + lmp = new LAMMPS(args, MPI_COMM_WORLD); // check if prerequisite styles are available Info *info = new Info(lmp); @@ -211,11 +211,9 @@ void data_lammps(LAMMPS *lmp, const TestConfig &cfg) void generate_yaml_file(const char *outfile, const TestConfig &config) { // initialize system geometry - const char *args[] = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"}; + LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); - LAMMPS *lmp = init_lammps(argc, argv, config); + LAMMPS *lmp = init_lammps(args, config); if (!lmp) { std::cerr << "One or more prerequisite styles are not available " "in this LAMMPS configuration:\n"; @@ -303,13 +301,10 @@ TEST(BondStyle, plain) { if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -358,7 +353,7 @@ TEST(BondStyle, plain) if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); if (!verbose) ::testing::internal::GetCapturedStdout(); // skip over these tests if newton bond is forced to be on @@ -424,14 +419,11 @@ TEST(BondStyle, omp) if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", - "-pk", "omp", "4", "-sf", "omp"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "omp", "4", "-sf", "omp"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -484,7 +476,7 @@ TEST(BondStyle, omp) if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); if (!verbose) ::testing::internal::GetCapturedStdout(); // skip over these tests if newton bond is forced to be on @@ -527,14 +519,11 @@ TEST(BondStyle, single) { if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"}; // create a LAMMPS instance with standard settings to detect the number of atom types if (!verbose) ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config); + LAMMPS *lmp = init_lammps(args, test_config); if (!verbose) ::testing::internal::GetCapturedStdout(); if (!lmp) { @@ -785,13 +774,10 @@ TEST(BondStyle, extract) { if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"}; if (!verbose) ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); if (!verbose) ::testing::internal::GetCapturedStdout(); if (!lmp) { diff --git a/unittest/force-styles/test_dihedral_style.cpp b/unittest/force-styles/test_dihedral_style.cpp index 2039155644..25690fc33d 100644 --- a/unittest/force-styles/test_dihedral_style.cpp +++ b/unittest/force-styles/test_dihedral_style.cpp @@ -59,11 +59,9 @@ void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg) delete lmp; } -LAMMPS *init_lammps(int argc, char **argv, const TestConfig &cfg, const bool newton = true) +LAMMPS *init_lammps(LAMMPS::argv & args, const TestConfig &cfg, const bool newton = true) { - LAMMPS *lmp; - - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + LAMMPS *lmp = new LAMMPS(args, MPI_COMM_WORLD); // check if prerequisite styles are available Info *info = new Info(lmp); @@ -220,11 +218,9 @@ void data_lammps(LAMMPS *lmp, const TestConfig &cfg) void generate_yaml_file(const char *outfile, const TestConfig &config) { // initialize system geometry - const char *args[] = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite"}; + LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); - LAMMPS *lmp = init_lammps(argc, argv, config); + LAMMPS *lmp = init_lammps(args, config); if (!lmp) { std::cerr << "One or more prerequisite styles are not available " "in this LAMMPS configuration:\n"; @@ -306,13 +302,10 @@ TEST(DihedralStyle, plain) { if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -361,7 +354,7 @@ TEST(DihedralStyle, plain) if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); if (!verbose) ::testing::internal::GetCapturedStdout(); // skip over these tests if newton bond is forced to be on @@ -427,14 +420,11 @@ TEST(DihedralStyle, omp) if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite", - "-pk", "omp", "4", "-sf", "omp"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "omp", "4", "-sf", "omp"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -488,7 +478,7 @@ TEST(DihedralStyle, omp) if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); if (!verbose) ::testing::internal::GetCapturedStdout(); // skip over these tests if newton bond is forced to be on diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index b65eab2049..2d2c2fa0b8 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -61,11 +61,11 @@ void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg) delete lmp; } -LAMMPS *init_lammps(int argc, char **argv, const TestConfig &cfg, const bool use_respa = false) +LAMMPS *init_lammps(LAMMPS::argv & args, const TestConfig &cfg, const bool use_respa = false) { LAMMPS *lmp; - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + lmp = new LAMMPS(args, MPI_COMM_WORLD); // check if prerequisite styles are available Info *info = new Info(lmp); @@ -169,11 +169,8 @@ void restart_lammps(LAMMPS *lmp, const TestConfig &cfg, bool use_rmass, bool use void generate_yaml_file(const char *outfile, const TestConfig &config) { // initialize system geometry - const char *args[] = {"FixIntegrate", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); - LAMMPS *lmp = init_lammps(argc, argv, config); + LAMMPS::argv args = {"FixIntegrate", "-log", "none", "-echo", "screen", "-nocite"}; + LAMMPS *lmp = init_lammps(args, config); if (!lmp) { std::cerr << "One or more prerequisite styles are not available " "in this LAMMPS configuration:\n"; @@ -252,13 +249,10 @@ TEST(FixTimestep, plain) if (test_config.skip_tests.count("static")) GTEST_SKIP(); #endif - const char *args[] = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config); + LAMMPS *lmp = init_lammps(args, test_config); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -420,7 +414,7 @@ TEST(FixTimestep, plain) if (!verbose) ::testing::internal::GetCapturedStdout(); ::testing::internal::CaptureStdout(); - lmp = init_lammps(argc, argv, test_config, true); + lmp = init_lammps(args, test_config, true); output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -554,14 +548,12 @@ TEST(FixTimestep, omp) if (test_config.skip_tests.count("static")) GTEST_SKIP(); #endif - const char *args[] = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite", - "-pk", "omp", "4", "-sf", "omp"}; + LAMMPS::argv args = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "omp", "4", "-sf", "omp"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config); + LAMMPS *lmp = init_lammps(args, test_config); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -723,7 +715,7 @@ TEST(FixTimestep, omp) if (!verbose) ::testing::internal::GetCapturedStdout(); ::testing::internal::CaptureStdout(); - lmp = init_lammps(argc, argv, test_config, true); + lmp = init_lammps(args, test_config, true); output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; diff --git a/unittest/force-styles/test_improper_style.cpp b/unittest/force-styles/test_improper_style.cpp index 259bd9008d..b4096df868 100644 --- a/unittest/force-styles/test_improper_style.cpp +++ b/unittest/force-styles/test_improper_style.cpp @@ -59,11 +59,11 @@ void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg) delete lmp; } -LAMMPS *init_lammps(int argc, char **argv, const TestConfig &cfg, const bool newton = true) +LAMMPS *init_lammps(LAMMPS::argv & args, const TestConfig &cfg, const bool newton = true) { LAMMPS *lmp; - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + lmp = new LAMMPS(args, MPI_COMM_WORLD); // check if prerequisite styles are available Info *info = new Info(lmp); @@ -211,11 +211,9 @@ void data_lammps(LAMMPS *lmp, const TestConfig &cfg) void generate_yaml_file(const char *outfile, const TestConfig &config) { // initialize system geometry - const char *args[] = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"}; + LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); - LAMMPS *lmp = init_lammps(argc, argv, config); + LAMMPS *lmp = init_lammps(args, config); if (!lmp) { std::cerr << "One or more prerequisite styles are not available " "in this LAMMPS configuration:\n"; @@ -297,13 +295,10 @@ TEST(ImproperStyle, plain) { if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -352,7 +347,7 @@ TEST(ImproperStyle, plain) if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); if (!verbose) ::testing::internal::GetCapturedStdout(); // skip over these tests if newton bond is forced to be on @@ -418,14 +413,11 @@ TEST(ImproperStyle, omp) if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite", - "-pk", "omp", "4", "-sf", "omp"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "omp", "4", "-sf", "omp"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -479,7 +471,7 @@ TEST(ImproperStyle, omp) if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); if (!verbose) ::testing::internal::GetCapturedStdout(); // skip over these tests if newton bond is forced to be on diff --git a/unittest/force-styles/test_pair_style.cpp b/unittest/force-styles/test_pair_style.cpp index f44a6e61d3..8ad2ce9aaa 100644 --- a/unittest/force-styles/test_pair_style.cpp +++ b/unittest/force-styles/test_pair_style.cpp @@ -61,11 +61,11 @@ void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg) delete lmp; } -LAMMPS *init_lammps(int argc, char **argv, const TestConfig &cfg, const bool newton = true) +LAMMPS *init_lammps(LAMMPS::argv & args, const TestConfig &cfg, const bool newton = true) { LAMMPS *lmp; - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + lmp = new LAMMPS(args, MPI_COMM_WORLD); // check if prerequisite styles are available Info *info = new Info(lmp); @@ -225,11 +225,9 @@ void data_lammps(LAMMPS *lmp, const TestConfig &cfg) void generate_yaml_file(const char *outfile, const TestConfig &config) { // initialize system geometry - const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"}; + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"}; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); - LAMMPS *lmp = init_lammps(argc, argv, config); + LAMMPS *lmp = init_lammps(args, config); if (!lmp) { std::cerr << "One or more prerequisite styles are not available " "in this LAMMPS configuration:\n"; @@ -323,13 +321,10 @@ TEST(PairStyle, plain) { if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -388,7 +383,7 @@ TEST(PairStyle, plain) if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); if (!verbose) ::testing::internal::GetCapturedStdout(); // skip over these tests if newton pair is forced to be on @@ -469,7 +464,7 @@ TEST(PairStyle, plain) if (pair->respa_enable) { if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); lmp->input->one("run_style respa 2 1 inner 1 4.8 5.5 outer 2"); run_lammps(lmp); if (!verbose) ::testing::internal::GetCapturedStdout(); @@ -501,17 +496,14 @@ TEST(PairStyle, omp) if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", - "-pk", "omp", "4", "-sf", "omp"}; + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "omp", "4", "-sf", "omp"}; // cannot run dpd styles with more than 1 thread due to using multiple pRNGs if (utils::strmatch(test_config.pair_style, "^dpd")) args[8] = "1"; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); - ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -570,7 +562,7 @@ TEST(PairStyle, omp) if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); if (!verbose) ::testing::internal::GetCapturedStdout(); pair = lmp->force->pair; @@ -626,8 +618,8 @@ TEST(PairStyle, kokkos_omp) if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP(); - const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", - "-k", "on", "t", "4", "-sf", "kk"}; + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", + "-k", "on", "t", "4", "-sf", "kk"}; // cannot run dpd styles in plain or hybrid with more than 1 thread due to using multiple pRNGs if (utils::strmatch(test_config.pair_style, "^dpd") || @@ -642,11 +634,8 @@ TEST(PairStyle, kokkos_omp) utils::strmatch(test_config.pair_style, " pace")) args[9] = "1"; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); - ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -704,7 +693,7 @@ TEST(PairStyle, kokkos_omp) if (lmp->force->newton_pair == 0) { if (!verbose) ::testing::internal::CaptureStdout(); cleanup_lammps(lmp, test_config); - lmp = init_lammps(argc, argv, test_config, false); + lmp = init_lammps(args, test_config, false); if (!verbose) ::testing::internal::GetCapturedStdout(); pair = lmp->force->pair; @@ -767,22 +756,19 @@ TEST(PairStyle, gpu) (!Info::has_fft_single_support())) GTEST_SKIP(); - const char *args_neigh[] = {"PairStyle", "-log", "none", "-echo", - "screen", "-nocite", "-sf", "gpu"}; - const char *args_noneigh[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", "-sf", - "gpu", "-pk", "gpu", "0", "neigh", "no"}; - - char **argv = (char **)args_neigh; - int argc = sizeof(args_neigh) / sizeof(char *); + LAMMPS::argv args_neigh = {"PairStyle", "-log", "none", "-echo", + "screen", "-nocite", "-sf", "gpu"}; + LAMMPS::argv args_noneigh = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", "-sf", + "gpu", "-pk", "gpu", "0", "neigh", "no"}; + LAMMPS::argv args = args_neigh; // cannot use GPU neighbor list with hybrid pair style (yet) if (test_config.pair_style.substr(0, 6) == "hybrid") { - argv = (char **)args_noneigh; - argc = sizeof(args_noneigh) / sizeof(char *); + args = args_noneigh; } ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, false); + LAMMPS *lmp = init_lammps(args, test_config, false); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -854,18 +840,15 @@ TEST(PairStyle, intel) if (!LAMMPS::is_installed_pkg("INTEL")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", - "-pk", "intel", "0", "mode", "double", "omp", - "4", "lrt", "no", "-sf", "intel"}; + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", + "-pk", "intel", "0", "mode", "double", "omp", + "4", "lrt", "no", "-sf", "intel"}; // cannot use more than 1 thread for dpd styles due to pRNG if (utils::strmatch(test_config.pair_style, "^dpd")) args[12] = "1"; - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); - ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -942,13 +925,10 @@ TEST(PairStyle, opt) if (!LAMMPS::is_installed_pkg("OPT")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", "-sf", "opt"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", "-sf", "opt"}; ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config); + LAMMPS *lmp = init_lammps(args, test_config); std::string output = ::testing::internal::GetCapturedStdout(); if (verbose) std::cout << output; @@ -1025,17 +1005,14 @@ TEST(PairStyle, single) { if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"}; // need to add this dependency test_config.prerequisites.emplace_back("atom", "full"); // create a LAMMPS instance with standard settings to detect the number of atom types if (!verbose) ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config); + LAMMPS *lmp = init_lammps(args, test_config); if (!verbose) ::testing::internal::GetCapturedStdout(); if (!lmp) { @@ -1276,13 +1253,10 @@ TEST(PairStyle, extract) { if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); - const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"}; - - char **argv = (char **)args; - int argc = sizeof(args) / sizeof(char *); + LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"}; if (!verbose) ::testing::internal::CaptureStdout(); - LAMMPS *lmp = init_lammps(argc, argv, test_config, true); + LAMMPS *lmp = init_lammps(args, test_config, true); if (!verbose) ::testing::internal::GetCapturedStdout(); if (!lmp) { diff --git a/unittest/fortran/wrap_extract_variable.cpp b/unittest/fortran/wrap_extract_variable.cpp index 1082a381bb..8c81897c0a 100644 --- a/unittest/fortran/wrap_extract_variable.cpp +++ b/unittest/fortran/wrap_extract_variable.cpp @@ -71,10 +71,10 @@ protected: // clang-format off const char *args[] = { "LAMMPS_Fortran_test", "-l", "none", "-echo", "screen", "-nocite", - "-var", "input_dir", input_dir, "-var", "zpos", "1.5", "-var", "x", "2" }; + "-var", "input_dir", input_dir, "-var", "zpos", "1.5", "-var", "x", "2", nullptr }; // clang-format on char **argv = (char **)args; - int argc = sizeof(args) / sizeof(const char *); + int argc = (sizeof(args) / sizeof(const char *)) - 1; ::testing::internal::CaptureStdout(); lmp = (LAMMPS_NS::LAMMPS *)f_lammps_with_c_args(argc, argv); diff --git a/unittest/testing/core.h b/unittest/testing/core.h index 88503dc188..8f1a84d2d8 100644 --- a/unittest/testing/core.h +++ b/unittest/testing/core.h @@ -106,31 +106,21 @@ public: } protected: - std::string testbinary = "LAMMPSTest"; - std::vector args = {"-log", "none", "-echo", "screen", "-nocite"}; + std::string testbinary = "LAMMPSTest"; + LAMMPS::argv args = {"-log", "none", "-echo", "screen", "-nocite"}; LAMMPS *lmp; Info *info; void SetUp() override { - int argc = args.size() + 1; - char **argv = new char *[argc]; - argv[0] = LAMMPS_NS::utils::strdup(testbinary); - for (int i = 1; i < argc; i++) { - argv[i] = LAMMPS_NS::utils::strdup(args[i - 1]); - } + LAMMPS::argv full_args = {testbinary}; + full_args.insert(full_args.end(), args.begin(), args.end()); HIDE_OUTPUT([&] { - lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + lmp = new LAMMPS(full_args, MPI_COMM_WORLD); info = new Info(lmp); }); InitSystem(); - - for (int i = 0; i < argc; i++) { - delete[] argv[i]; - argv[i] = nullptr; - } - delete[] argv; } virtual void InitSystem() {} From 053a904d08506f95001d976305b592c887821045 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Tue, 7 Nov 2023 17:55:32 -0700 Subject: [PATCH 16/17] bugfix: make copy of exename --- src/lammps.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lammps.cpp b/src/lammps.cpp index c0336ee588..0914658d75 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -219,7 +219,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : suffix = suffix2 = nullptr; suffix_enable = 0; pair_only_flag = 0; - if (arg) exename = arg[0]; + if (arg) exename = utils::strdup(arg[0]); else exename = nullptr; packargs = nullptr; num_package = 0; @@ -809,6 +809,7 @@ LAMMPS::~LAMMPS() noexcept(false) delete memory; delete pkg_lists; + delete[] exename; } /* ---------------------------------------------------------------------- From eff65ad3f33a47fafa2c3c67b48807461ad0e3dc Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Thu, 9 Nov 2023 20:29:14 -0700 Subject: [PATCH 17/17] bugfix: correctly build argv when using Python interface --- python/lammps/core.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/python/lammps/core.py b/python/lammps/core.py index 84a80e77a3..1ff123760b 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -379,8 +379,9 @@ class lammps(object): for i in range(narg): if type(cmdargs[i]) is str: cmdargs[i] = cmdargs[i].encode() - cargs = (c_char_p*narg)(*cmdargs) - self.lib.lammps_open.argtypes = [c_int, c_char_p*narg, MPI_Comm, c_void_p] + cargs = (c_char_p*(narg+1))(*cmdargs) + cargs[narg] = None + self.lib.lammps_open.argtypes = [c_int, c_char_p*(narg+1), MPI_Comm, c_void_p] else: self.lib.lammps_open.argtypes = [c_int, c_char_p, MPI_Comm, c_void_p] @@ -399,8 +400,9 @@ class lammps(object): for i in range(narg): if type(cmdargs[i]) is str: cmdargs[i] = cmdargs[i].encode() - cargs = (c_char_p*narg)(*cmdargs) - self.lib.lammps_open_no_mpi.argtypes = [c_int, c_char_p*narg, c_void_p] + cargs = (c_char_p*(narg+1))(*cmdargs) + cargs[narg] = None + self.lib.lammps_open_no_mpi.argtypes = [c_int, c_char_p*(narg+1), c_void_p] self.lmp = c_void_p(self.lib.lammps_open_no_mpi(narg,cargs,None)) else: self.lib.lammps_open_no_mpi.argtypes = [c_int, c_char_p, c_void_p]