From 34121e5545d02418d19d8708e4eaa55944c03780 Mon Sep 17 00:00:00 2001 From: Karl Hammond Date: Thu, 20 Oct 2022 00:27:57 -0500 Subject: [PATCH] Implemented decode_image_flags and its unit test; updated documentation --- doc/src/Fortran.rst | 29 ++++++++++ fortran/lammps.f90 | 60 ++++++++++++++++++-- unittest/fortran/test_fortran_properties.f90 | 22 +++++++ unittest/fortran/wrap_properties.cpp | 41 +++++++++---- 4 files changed, 135 insertions(+), 17 deletions(-) diff --git a/doc/src/Fortran.rst b/doc/src/Fortran.rst index f755670d77..9191586bcc 100644 --- a/doc/src/Fortran.rst +++ b/doc/src/Fortran.rst @@ -267,8 +267,22 @@ of the contents of the ``LIBLAMMPS`` Fortran interface to LAMMPS. :f subroutine scatter_atoms_subset: :f:func:`scatter_atoms_subset` :f subroutine create_atoms: :f:func:`create_atoms` :f function version: :f:func:`version` + :f subroutine get_os_info: :f:func:`get_os_info` + :f function config_has_mpi_support: :f:func:`config_has_mpi_support` + :f function config_has_gzip_support: :f:func:`config_has_gzip_support` + :f function config_has_png_support: :f:func:`config_has_png_support` + :f function config_has_jpeg_support: :f:func:`config_has_jpeg_support` + :f function config_has_ffmpeg_support: :f:func:`config_has_ffmpeg_support` + :f function config_has_exceptions: :f:func:`config_has_exceptions` + :f function config_has_package: :f:func:`config_has_package` + :f function config_package_count: :f:func:`config_package_count` + :f function config_package_name: :f:func:`config_package_name` + :f subroutine installed_packages: :f:func:`installed_packages` + :f function encode_image_flags: :f:func:`encode_image_flags` + :f subroutine decode_image_flags: :f:func:`decode_image_flags` :f subroutine flush_buffers: :f:func:`flush_buffers` :f function is_running: :f:func:`is_running` + :f function force_timeout: :f:func:`force_timeout` :f function has_error: :f:func:`has_error` :f subroutine get_last_error_message: :f:func:`get_last_error_message` @@ -1552,6 +1566,21 @@ Procedures Bound to the lammps Derived Type -------- +.. f:function:: decode_image_flags(image, flags) + + This function does the reverse operation of :f:func:`encode_image_flags`: + it takes the image flag and performs the bit-shift and bit-masking + operations to decode it and stores the resulting three integers into the + array *flags*. + + :p integer(kind=\*) image: encoded image flag. \*The ``KIND`` paremeter is + either ``c_int`` or, if LAMMPS was compiled with ``-DLAMMPS_BIGBIG``, + ``c_int64_t``. Kind compatibility is checked at run-time. + :p integer(c_int) flags [dimension(3)]: three-element vector where the + decoded image flags will be stored. + +-------- + .. f:subroutine:: flush_buffers() This function calls :cpp:func:`lammps_flush_buffers`, which flushes buffered diff --git a/fortran/lammps.f90 b/fortran/lammps.f90 index 467acf057d..a4551aad6d 100644 --- a/fortran/lammps.f90 +++ b/fortran/lammps.f90 @@ -126,7 +126,7 @@ MODULE LIBLAMMPS ! PROCEDURE, PRIVATE :: lmp_create_atoms_int PROCEDURE, PRIVATE :: lmp_create_atoms_bigbig - GENERIC :: create_atoms => lmp_create_atoms_int, & + GENERIC :: create_atoms => lmp_create_atoms_int, & lmp_create_atoms_bigbig ! PROCEDURE :: version => lmp_version @@ -143,6 +143,10 @@ MODULE LIBLAMMPS PROCEDURE, NOPASS :: config_package_name => lmp_config_package_name PROCEDURE, NOPASS :: installed_packages => lmp_installed_packages PROCEDURE :: encode_image_flags => lmp_encode_image_flags + PROCEDURE, PRIVATE :: lmp_decode_image_flags + PROCEDURE, PRIVATE :: lmp_decode_image_flags_bigbig + GENERIC :: decode_image_flags => lmp_decode_image_flags, & + lmp_decode_image_flags_bigbig ! PROCEDURE :: flush_buffers => lmp_flush_buffers PROCEDURE :: is_running => lmp_is_running @@ -577,12 +581,9 @@ MODULE LIBLAMMPS !SUBROUTINE lammps_plugin_name ! We don't call lammps_encode_image_flags because its interface is - ! ambiguous: we don't know sizeof(imageint) prior to compile time + ! ambiguous: we don't know sizeof(imageint) prior to compile time. ! It is re-written in Fortran below. It was easier to do the same for ! lammps_decode_image_flags's equivalent. - !Both of these use LAMMPS_BIGBIG - !INTEGER(LAMMPS_imageint) FUNCTION lammps_encode_image_flags - !SUBROUTINE lammps_decode_image_flags !SUBROUTINE lammps_set_fix_external_callback ! may have trouble.... !FUNCTION lammps_fix_external_get_force() ! returns real(c_double)(:) @@ -1847,6 +1848,55 @@ CONTAINS END FUNCTION lmp_encode_image_flags ! equivalent function to lammps_decode_image_flags + SUBROUTINE lmp_decode_image_flags(self, image, flags) + CLASS(lammps), INTENT(IN) :: self + INTEGER(c_int), INTENT(IN) :: image + INTEGER(c_int), DIMENSION(3), TARGET, INTENT(OUT) :: flags + INTEGER(c_int) :: size_imageint + INTEGER(c_int) :: IMGMASK, IMGMAX, IMGBITS, IMG2BITS + + size_imageint = lmp_extract_setting(self, 'imageint') + IF (size_imageint == 4_c_int) THEN + IMGMASK = lmp_extract_setting(self, 'IMGMASK') + IMGMAX = lmp_extract_setting(self, 'IMGMAX') + IMGBITS = lmp_extract_setting(self, 'IMGBITS') + IMG2BITS = lmp_extract_setting(self, 'IMG2BITS') + flags(1) = IAND(image, IMGMASK) - IMGMAX + flags(2) = IAND(ISHFT(image, -IMGBITS), IMGMASK) - IMGMAX + flags(3) = ISHFT(image, -IMG2BITS) - IMGMAX + ELSE + CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, 'Incorrect& + & integer kind passed as "image" [Fortran/decode_image_flags]') + END IF + END SUBROUTINE lmp_decode_image_flags + + ! equivalent function to lammps_decode_image_flags if -DLAMMPS_BIGBIG is used + SUBROUTINE lmp_decode_image_flags_bigbig(self, image, flags) + CLASS(lammps), INTENT(IN) :: self + INTEGER(c_int64_t), INTENT(IN) :: image + INTEGER(c_int), DIMENSION(3), TARGET, INTENT(OUT) :: flags + INTEGER(c_int) :: size_imageint + INTEGER(c_int) :: IMGMASK, IMGMAX, IMGBITS, IMG2BITS + INTEGER(c_int64_t) :: BIMGMASK, BIMGMAX, BIMGBITS, BIMG2BITS + + size_imageint = lmp_extract_setting(self, 'imageint') + IF (size_imageint == 8_c_int) THEN + IMGMASK = lmp_extract_setting(self, 'IMGMASK') + IMGMAX = lmp_extract_setting(self, 'IMGMAX') + IMGBITS = lmp_extract_setting(self, 'IMGBITS') + IMG2BITS = lmp_extract_setting(self, 'IMG2BITS') + BIMGMASK = IMGMASK + BIMGMAX = IMGMAX + BIMGBITS = IMGBITS + BIMG2BITS = IMG2BITS + flags(1) = IAND(image, BIMGMASK) - BIMGMAX + flags(2) = IAND(ISHFT(image, -BIMGBITS), BIMGMASK) - BIMGMAX + flags(3) = ISHFT(image, -BIMG2BITS) - BIMGMAX + ELSE + CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, 'Incorrect& + & integer kind passed as "image" [Fortran/decode_image_flags]') + END IF + END SUBROUTINE lmp_decode_image_flags_bigbig ! equivalent function to lammps_flush_buffers SUBROUTINE lmp_flush_buffers(self) diff --git a/unittest/fortran/test_fortran_properties.f90 b/unittest/fortran/test_fortran_properties.f90 index 6fb6b6ce5c..bbb47f7eb3 100644 --- a/unittest/fortran/test_fortran_properties.f90 +++ b/unittest/fortran/test_fortran_properties.f90 @@ -110,3 +110,25 @@ FUNCTION f_lammps_get_image_flags_bigint(ix, iy, iz) BIND(C) f_lammps_get_image_flags_bigint = lmp%encode_image_flags(ix, iy, iz) END FUNCTION f_lammps_get_image_flags_bigint + +SUBROUTINE f_lammps_decode_image_flags(image, flag) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int + USE keepstuff, ONLY : lmp + USE LIBLAMMPS + IMPLICIT NONE + INTEGER(c_int), INTENT(IN), VALUE :: image + INTEGER(c_int), INTENT(OUT) :: flag(3) + + CALL lmp%decode_image_flags(image, flag) +END SUBROUTINE f_lammps_decode_image_flags + +SUBROUTINE f_lammps_decode_image_flags_bigbig(image, flag) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int, c_int64_t + USE keepstuff, ONLY : lmp + USE LIBLAMMPS + IMPLICIT NONE + INTEGER(c_int64_t), INTENT(IN), VALUE :: image + INTEGER(c_int), INTENT(OUT) :: flag(3) + + CALL lmp%decode_image_flags(image, flag) +END SUBROUTINE f_lammps_decode_image_flags_bigbig diff --git a/unittest/fortran/wrap_properties.cpp b/unittest/fortran/wrap_properties.cpp index 18ec465e45..7112a50081 100644 --- a/unittest/fortran/wrap_properties.cpp +++ b/unittest/fortran/wrap_properties.cpp @@ -21,6 +21,8 @@ int f_lammps_has_error(); int f_lammps_get_last_error_message(char *, int); int f_lammps_get_image_flags_int(int, int, int); int64_t f_lammps_get_image_flags_bigint(int, int, int); +void f_lammps_decode_image_flags(int, int*); +void f_lammps_decode_image_flags_bigbig(int64_t, int*); } namespace LAMMPS_NS { @@ -156,20 +158,35 @@ TEST_F(LAMMPS_properties, has_error) TEST_F(LAMMPS_properties, get_image_flags) { #ifdef LAMMPS_BIGBIG - int64_t image = f_lammps_get_image_flags_bigint(0,0,0); - int64_t Cimage = lammps_encode_image_flags(0,0,0); - EXPECT_EQ(image, Cimage); - image = f_lammps_get_image_flags_bigint(1,-1,1); - Cimage = lammps_encode_image_flags(1,-1,1); - EXPECT_EQ(image, Cimage); + int64_t image = f_lammps_get_image_flags_bigint(0,0,0); + int64_t Cimage = lammps_encode_image_flags(0,0,0); + EXPECT_EQ(image, Cimage); + image = f_lammps_get_image_flags_bigint(1,-1,1); + Cimage = lammps_encode_image_flags(1,-1,1); + EXPECT_EQ(image, Cimage); #else - int image = f_lammps_get_image_flags_int(0,0,0); - int Cimage = lammps_encode_image_flags(0,0,0); - EXPECT_EQ(image, Cimage); - image = f_lammps_get_image_flags_int(1,-1,1); - Cimage = lammps_encode_image_flags(1,-1,1); - EXPECT_EQ(image, Cimage); + int image = f_lammps_get_image_flags_int(0,0,0); + int Cimage = lammps_encode_image_flags(0,0,0); + EXPECT_EQ(image, Cimage); + image = f_lammps_get_image_flags_int(1,-1,1); + Cimage = lammps_encode_image_flags(1,-1,1); + EXPECT_EQ(image, Cimage); #endif } +TEST_F(LAMMPS_properties, decode_image_flags) +{ + int flag[3]; +#ifdef LAMMPS_BIGBIG + int64_t image = f_lammps_get_image_flags_bigint(1,3,-2); + f_lammps_decode_image_flags_bigbig(image, flag); +#else + int image = f_lammps_get_image_flags_int(1,3,-2); + f_lammps_decode_image_flags(image, flag); +#endif + EXPECT_EQ(flag[0], 1); + EXPECT_EQ(flag[1], 3); + EXPECT_EQ(flag[2], -2); +}; + } // namespace LAMMPS_NS