From c0345845e86b73bc32d4174df37392d912e86daa Mon Sep 17 00:00:00 2001 From: Karl Hammond Date: Sat, 3 Dec 2022 20:38:42 -0600 Subject: [PATCH] unit test for gather and scatter; char* to const char* in library.* --- src/library.cpp | 32 +++--- src/library.h | 28 ++--- .../fortran/test_fortran_gather_scatter.f90 | 92 ++++++++++++++- unittest/fortran/wrap_gather_scatter.cpp | 108 ++++++++++++++++++ 4 files changed, 231 insertions(+), 29 deletions(-) diff --git a/src/library.cpp b/src/library.cpp index 9dc9a701f3..2c16cc6615 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2303,7 +2303,8 @@ This function is not compatible with ``-DLAMMPS_BIGBIG``. Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ -void lammps_gather_atoms(void *handle, char *name, int type, int count, void *data) +void lammps_gather_atoms(void *handle, const char *name, int type, int count, + void *data) { auto lmp = (LAMMPS *) handle; @@ -2460,7 +2461,8 @@ This function is not compatible with ``-DLAMMPS_BIGBIG``. Allgather Nlocal atoms from each proc into data ------------------------------------------------------------------------- */ -void lammps_gather_atoms_concat(void *handle, char *name, int type, int count, void *data) +void lammps_gather_atoms_concat(void *handle, const char *name, int type, + int count, void *data) { auto lmp = (LAMMPS *) handle; @@ -2627,8 +2629,8 @@ This function is not compatible with ``-DLAMMPS_BIGBIG``. Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ -void lammps_gather_atoms_subset(void *handle, char *name, int type, int count, - int ndata, int *ids, void *data) +void lammps_gather_atoms_subset(void *handle, const char *name, int type, + int count, int ndata, int *ids, void *data) { auto lmp = (LAMMPS *) handle; @@ -2786,7 +2788,8 @@ This function is not compatible with ``-DLAMMPS_BIGBIG``. loop over Natoms, if I own atom ID, set its values from data ------------------------------------------------------------------------- */ -void lammps_scatter_atoms(void *handle, char *name, int type, int count, void *data) +void lammps_scatter_atoms(void *handle, const char *name, int type, int count, + void *data) { auto lmp = (LAMMPS *) handle; @@ -2938,8 +2941,8 @@ This function is not compatible with ``-DLAMMPS_BIGBIG``. loop over Ndata, if I own atom ID, set its values from data ------------------------------------------------------------------------- */ -void lammps_scatter_atoms_subset(void *handle, char *name, int type, int count, - int ndata, int *ids, void *data) +void lammps_scatter_atoms_subset(void *handle, const char *name, int type, + int count, int ndata, int *ids, void *data) { auto lmp = (LAMMPS *) handle; @@ -3219,7 +3222,7 @@ This function is not compatible with ``-DLAMMPS_BIGBIG``. Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ -void lammps_gather(void *handle, char *name, int type, int count, void *data) +void lammps_gather(void *handle, const char *name, int type, int count, void *data) { auto lmp = (LAMMPS *) handle; @@ -3492,7 +3495,8 @@ This function is not compatible with ``-DLAMMPS_BIGBIG``. Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ -void lammps_gather_concat(void *handle, char *name, int type, int count, void *data) +void lammps_gather_concat(void *handle, const char *name, int type, int count, + void *data) { auto lmp = (LAMMPS *) handle; @@ -3779,9 +3783,8 @@ This function is not compatible with ``-DLAMMPS_BIGBIG``. Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ -void lammps_gather_subset(void *handle, char *name, - int type, int count, - int ndata, int *ids, void *data) +void lammps_gather_subset(void *handle, const char *name, int type, int count, + int ndata, int *ids, void *data) { auto lmp = (LAMMPS *) handle; @@ -4059,7 +4062,8 @@ This function is not compatible with ``-DLAMMPS_BIGBIG``. Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ -void lammps_scatter(void *handle, char *name, int type, int count, void *data) +void lammps_scatter(void *handle, const char *name, int type, int count, + void *data) { auto lmp = (LAMMPS *) handle; @@ -4312,7 +4316,7 @@ This function is not compatible with ``-DLAMMPS_BIGBIG``. loop over Ndata, if I own atom ID, set its values from data ------------------------------------------------------------------------- */ -void lammps_scatter_subset(void *handle, char *name,int type, int count, +void lammps_scatter_subset(void *handle, const char *name,int type, int count, int ndata, int *ids, void *data) { auto lmp = (LAMMPS *) handle; diff --git a/src/library.h b/src/library.h index f0f8448b79..9cd2f34d73 100644 --- a/src/library.h +++ b/src/library.h @@ -181,23 +181,23 @@ int lammps_set_variable(void *, char *, char *); * Library functions for scatter/gather operations of data * ---------------------------------------------------------------------- */ -void lammps_gather_atoms(void *handle, char *name, int type, int count, void *data); -void lammps_gather_atoms_concat(void *handle, char *name, int type, int count, void *data); -void lammps_gather_atoms_subset(void *handle, char *name, int type, int count, int ndata, int *ids, - void *data); -void lammps_scatter_atoms(void *handle, char *name, int type, int count, void *data); -void lammps_scatter_atoms_subset(void *handle, char *name, int type, int count, int ndata, int *ids, - void *data); +void lammps_gather_atoms(void *handle, const char *name, int type, int count, void *data); +void lammps_gather_atoms_concat(void *handle, const char *name, int type, int count, void *data); +void lammps_gather_atoms_subset(void *handle, const char *name, int type, int count, int ndata, + int *ids, void *data); +void lammps_scatter_atoms(void *handle, const char *name, int type, int count, void *data); +void lammps_scatter_atoms_subset(void *handle, const char *name, int type, int count, int ndata, + int *ids, void *data); void lammps_gather_bonds(void *handle, void *data); -void lammps_gather(void *handle, char *name, int type, int count, void *data); -void lammps_gather_concat(void *handle, char *name, int type, int count, void *data); -void lammps_gather_subset(void *handle, char *name, int type, int count, int ndata, int *ids, - void *data); -void lammps_scatter(void *handle, char *name, int type, int count, void *data); -void lammps_scatter_subset(void *handle, char *name, int type, int count, int ndata, int *ids, - void *data); +void lammps_gather(void *handle, const char *name, int type, int count, void *data); +void lammps_gather_concat(void *handle, const char *name, int type, int count, void *data); +void lammps_gather_subset(void *handle, const char *name, int type, int count, int ndata, + int *ids, void *data); +void lammps_scatter(void *handle, const char *name, int type, int count, void *data); +void lammps_scatter_subset(void *handle, const char *name, int type, int count, int ndata, + int *ids, void *data); #if !defined(LAMMPS_BIGBIG) int lammps_create_atoms(void *handle, int n, const int *id, const int *type, const double *x, diff --git a/unittest/fortran/test_fortran_gather_scatter.f90 b/unittest/fortran/test_fortran_gather_scatter.f90 index 2115a10394..6df1421bac 100644 --- a/unittest/fortran/test_fortran_gather_scatter.f90 +++ b/unittest/fortran/test_fortran_gather_scatter.f90 @@ -24,13 +24,16 @@ END SUBROUTINE f_lammps_close SUBROUTINE f_lammps_setup_gather_scatter() BIND(C) USE LIBLAMMPS - USE keepstuff, ONLY : lmp, big_input, cont_input, more_input + USE keepstuff, ONLY : lmp, big_input, cont_input, more_input, pair_input IMPLICIT NONE CALL lmp%command('atom_modify map array') CALL lmp%commands_list(big_input) CALL lmp%commands_list(cont_input) CALL lmp%commands_list(more_input) + CALL lmp%commands_list(pair_input) + CALL lmp%command('mass 1 1.0') + CALL lmp%command("compute pe all pe/atom") END SUBROUTINE f_lammps_setup_gather_scatter FUNCTION f_lammps_gather_atoms_mask(i) BIND(C) @@ -262,3 +265,90 @@ FUNCTION f_lammps_test_gather_bonds_big() BIND(C) RESULT(success) success = 0_c_int END IF END FUNCTION f_lammps_test_gather_bonds_big + +FUNCTION f_lammps_gather_pe_atom(i) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int, c_double + USE LIBLAMMPS + USE keepstuff, ONLY : lmp + IMPLICIT NONE + INTEGER(c_int), INTENT(IN), VALUE :: i + REAL(c_double) :: f_lammps_gather_pe_atom + REAL(c_double), DIMENSION(:), ALLOCATABLE :: pe_atom + + CALL lmp%gather('c_pe', 1_c_int, pe_atom) + f_lammps_gather_pe_atom = pe_atom(i) +END FUNCTION f_lammps_gather_pe_atom + +FUNCTION f_lammps_gather_pe_atom_concat(i) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int, c_double + USE LIBLAMMPS + USE keepstuff, ONLY : lmp + IMPLICIT NONE + INTEGER(c_int), INTENT(IN), VALUE :: i + REAL(c_double) :: f_lammps_gather_pe_atom_concat + REAL(c_double), DIMENSION(:), ALLOCATABLE :: pe_atom + INTEGER(c_int), DIMENSION(:), ALLOCATABLE :: tag + INTEGER :: j + + CALL lmp%gather_concat('id', 1_c_int, tag) + CALL lmp%gather_concat('c_pe', 1_c_int, pe_atom) + DO j = 1, SIZE(tag) + IF (tag(j) == i) THEN + f_lammps_gather_pe_atom_concat = pe_atom(j) + EXIT + END IF + END DO + f_lammps_gather_pe_atom_concat = pe_atom(i) +END FUNCTION f_lammps_gather_pe_atom_concat + +SUBROUTINE f_lammps_gather_pe_atom_subset(ids, pe) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int, c_double + USE LIBLAMMPS + USE keepstuff, ONLY : lmp + IMPLICIT NONE + INTEGER(c_int), INTENT(IN) :: ids(2) + REAL(c_double), INTENT(OUT) :: pe(2) + REAL(c_double), DIMENSION(:), ALLOCATABLE :: pe_atom + INTEGER(c_int) :: natoms + + natoms = NINT(lmp%get_natoms(), c_int) + CALL lmp%gather_subset('c_pe', 1, ids, pe_atom) + pe(1:natoms) = pe_atom +END SUBROUTINE f_lammps_gather_pe_atom_subset + +SUBROUTINE f_lammps_scatter_compute() BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int, c_double + USE LIBLAMMPS + USE keepstuff, ONLY : lmp + IMPLICIT NONE + REAL(c_double), DIMENSION(:), ALLOCATABLE :: pe_atom + REAL(c_double) :: swap + + CALL lmp%gather('c_pe', 1_c_int, pe_atom) + + ! swap the computed energy of atoms 1 and 3 + swap = pe_atom(1) + pe_atom(1) = pe_atom(3) + pe_atom(3) = swap + + CALL lmp%scatter('c_pe', pe_atom) ! push the swap back to LAMMPS +END SUBROUTINE f_lammps_scatter_compute + +SUBROUTINE f_lammps_scatter_subset_compute() BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int, c_double + USE LIBLAMMPS + USE keepstuff, ONLY : lmp + IMPLICIT NONE + INTEGER(c_int), PARAMETER :: ids(2) = [3,1] + REAL(c_double), DIMENSION(:), ALLOCATABLE :: pe_atom + REAL(c_double) :: swap + + CALL lmp%gather_subset('c_pe', 1_c_int, ids, pe_atom) + + ! swap the computed energy of atoms 1 and 3 + swap = pe_atom(1) + pe_atom(1) = pe_atom(2) + pe_atom(2) = swap + + CALL lmp%scatter_subset('c_pe', ids, pe_atom) ! push the swap back to LAMMPS +END SUBROUTINE f_lammps_scatter_subset_compute diff --git a/unittest/fortran/wrap_gather_scatter.cpp b/unittest/fortran/wrap_gather_scatter.cpp index 9eb6082202..5e836c1759 100644 --- a/unittest/fortran/wrap_gather_scatter.cpp +++ b/unittest/fortran/wrap_gather_scatter.cpp @@ -3,6 +3,7 @@ #include "lammps.h" #include "library.h" +#include "atom.h" #include #include #include @@ -26,6 +27,11 @@ void f_lammps_scatter_atoms_positions(); void f_lammps_setup_gather_bonds(); int f_lammps_test_gather_bonds_small(); int f_lammps_test_gather_bonds_big(); +double f_lammps_gather_pe_atom(int); +double f_lammps_gather_pe_atom_concat(int); +void f_lammps_gather_pe_atom_subset(int*, double*); +void f_lammps_scatter_compute(); +void f_lammps_scatter_subset_compute(); } using namespace LAMMPS_NS; @@ -216,3 +222,105 @@ TEST_F(LAMMPS_gather_scatter, gather_bonds) #endif }; + +TEST_F(LAMMPS_gather_scatter, gather_compute) +{ +#ifdef LAMMPS_BIGBIG + GTEST_SKIP() +#endif + f_lammps_setup_gather_scatter(); + lammps_command(lmp, "run 0"); + int natoms = lmp->atom->natoms; + int *tag = lmp->atom->tag; + double *pe = (double*) lammps_extract_compute(lmp, "pe", LMP_STYLE_ATOM, + LMP_TYPE_VECTOR); + for (int i = 0; i < natoms; i++) + EXPECT_DOUBLE_EQ(f_lammps_gather_pe_atom(tag[i]), pe[i]); +}; + +TEST_F(LAMMPS_gather_scatter, gather_compute_concat) +{ +#ifdef LAMMPS_BIGBIG + GTEST_SKIP() +#endif + f_lammps_setup_gather_scatter(); + lammps_command(lmp, "run 0"); + int natoms = lmp->atom->natoms; + int *tag = lmp->atom->tag; + double *pe = (double*) lammps_extract_compute(lmp, "pe", LMP_STYLE_ATOM, + LMP_TYPE_VECTOR); + for (int i = 0; i < natoms; i++) + EXPECT_DOUBLE_EQ(f_lammps_gather_pe_atom(tag[i]), pe[i]); +}; + +TEST_F(LAMMPS_gather_scatter, gather_compute_subset) +{ + f_lammps_setup_gather_scatter(); + lammps_command(lmp, "run 0"); + int ids[2] = {3, 1}; + int *tag = lmp->atom->tag; + double pe[2] = {0.0, 0.0}; + int nlocal = lammps_extract_setting(lmp, "nlocal"); + double *pa_pe = (double*) lammps_extract_compute(lmp, "pe", LMP_STYLE_ATOM, + LMP_TYPE_VECTOR); + + for (int i = 0; i < nlocal; i++) { + if(tag[i] == ids[0]) pe[0] = pa_pe[i]; + if(tag[i] == ids[1]) pe[1] = pa_pe[i]; + } + + double ftn_pe[2]; + f_lammps_gather_pe_atom_subset(ids, ftn_pe); + EXPECT_DOUBLE_EQ(ftn_pe[0], pe[0]); + EXPECT_DOUBLE_EQ(ftn_pe[1], pe[1]); +}; + +TEST_F(LAMMPS_gather_scatter, scatter_compute) +{ +#ifdef LAMMPS_BIGBIG + GTEST_SKIP(); +#endif + f_lammps_setup_gather_scatter(); + int natoms = lmp->atom->natoms; + double *pe = new double[natoms]; + lammps_command(lmp, "run 0"); + lammps_gather(lmp, "c_pe", 1, 1, pe); + double *old_pe = new double[natoms]; + for (int i = 0; i < natoms; i++) + old_pe[i] = pe[i]; + EXPECT_DOUBLE_EQ(pe[0], old_pe[0]); + EXPECT_DOUBLE_EQ(pe[1], old_pe[1]); + EXPECT_DOUBLE_EQ(pe[2], old_pe[2]); + f_lammps_scatter_compute(); + lammps_gather(lmp, "c_pe", 1, 1, pe); + EXPECT_DOUBLE_EQ(pe[0], old_pe[2]); + EXPECT_DOUBLE_EQ(pe[1], old_pe[1]); + EXPECT_DOUBLE_EQ(pe[2], old_pe[0]); + delete[] old_pe; + delete[] pe; +}; + +TEST_F(LAMMPS_gather_scatter, scatter_subset_compute) +{ +#ifdef LAMMPS_BIGBIG + GTEST_SKIP(); +#endif + f_lammps_setup_gather_scatter(); + int natoms = lmp->atom->natoms; + double *pe = new double[natoms]; + lammps_command(lmp, "run 0"); + lammps_gather(lmp, "c_pe", 1, 1, pe); + double *old_pe = new double[natoms]; + for (int i = 0; i < natoms; i++) + old_pe[i] = pe[i]; + EXPECT_DOUBLE_EQ(pe[0], old_pe[0]); + EXPECT_DOUBLE_EQ(pe[1], old_pe[1]); + EXPECT_DOUBLE_EQ(pe[2], old_pe[2]); + f_lammps_scatter_subset_compute(); + lammps_gather(lmp, "c_pe", 1, 1, pe); + EXPECT_DOUBLE_EQ(pe[0], old_pe[2]); + EXPECT_DOUBLE_EQ(pe[1], old_pe[1]); + EXPECT_DOUBLE_EQ(pe[2], old_pe[0]); + delete[] old_pe; + delete[] pe; +};