From 2f84eac5c5c15e5e2ca0750950dcbcd5276b7fe1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 11 Dec 2022 17:50:03 -0500 Subject: [PATCH] add c wrapper to allow testing fortran interface w/o fortran MPI libs --- unittest/fortran/CMakeLists.txt | 52 ++++++++---------------- unittest/fortran/mpi_stubs.f90 | 20 --------- unittest/fortran/test_fortran_create.f90 | 29 ++++++++++--- unittest/fortran/wrap_create.cpp | 8 ++++ 4 files changed, 48 insertions(+), 61 deletions(-) delete mode 100644 unittest/fortran/mpi_stubs.f90 diff --git a/unittest/fortran/CMakeLists.txt b/unittest/fortran/CMakeLists.txt index f66b333db1..b534835a5e 100644 --- a/unittest/fortran/CMakeLists.txt +++ b/unittest/fortran/CMakeLists.txt @@ -21,20 +21,6 @@ if(CMAKE_Fortran_COMPILER) endif() get_filename_component(LAMMPS_FORTRAN_MODULE ${LAMMPS_SOURCE_DIR}/../fortran/lammps.f90 ABSOLUTE) - if(BUILD_MPI) - find_package(MPI REQUIRED) - if((NOT MPI_Fortran_FOUND) OR (NOT MPI_Fortran_HAVE_F77_HEADER)) - message(STATUS "Skipping Tests for the LAMMPS Fortran Module: no MPI support for Fortran") - return() - endif() - else() - add_library(fmpi_stubs STATIC mpi_stubs.f90) - get_filename_component(_tmp_fc ${CMAKE_Fortran_COMPILER} NAME) - if (_tmp_fc STREQUAL "flang") - target_link_libraries(fmpi_stubs PUBLIC gfortran) - endif() - add_library(MPI::MPI_Fortran ALIAS fmpi_stubs) - endif() add_library(flammps STATIC ${LAMMPS_FORTRAN_MODULE} keepstuff.f90) get_filename_component(_tmp_fc ${CMAKE_Fortran_COMPILER} NAME) @@ -42,66 +28,62 @@ if(CMAKE_Fortran_COMPILER) target_link_libraries(flammps PUBLIC gfortran) endif() - if(MPI_Fortran_HAVE_F90_MODULE) - add_executable(test_fortran_create wrap_create.cpp test_fortran_create.f90) - target_link_libraries(test_fortran_create PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) - target_include_directories(test_fortran_create PRIVATE "${LAMMPS_SOURCE_DIR}/../fortran") - add_test(NAME FortranOpen COMMAND test_fortran_create) - else() - message(STATUS "Skipping FortranOpen test since no working F90 MPI module was found") - endif() + add_executable(test_fortran_create wrap_create.cpp test_fortran_create.f90) + target_link_libraries(test_fortran_create PRIVATE flammps lammps GTest::GTestMain) + target_include_directories(test_fortran_create PRIVATE "${LAMMPS_SOURCE_DIR}/../fortran") + add_test(NAME FortranOpen COMMAND test_fortran_create) add_executable(test_fortran_commands wrap_commands.cpp test_fortran_commands.f90) - target_link_libraries(test_fortran_commands PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) + target_link_libraries(test_fortran_commands PRIVATE flammps lammps GTest::GTestMain) add_test(NAME FortranCommands COMMAND test_fortran_commands) add_executable(test_fortran_get_thermo wrap_get_thermo.cpp test_fortran_get_thermo.f90) - target_link_libraries(test_fortran_get_thermo PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) + target_link_libraries(test_fortran_get_thermo PRIVATE flammps lammps GTest::GTestMain) add_test(NAME FortranGetThermo COMMAND test_fortran_get_thermo) add_executable(test_fortran_box wrap_box.cpp test_fortran_box.f90) - target_link_libraries(test_fortran_box PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) + target_link_libraries(test_fortran_box PRIVATE flammps lammps GTest::GTestMain) add_test(NAME FortranBox COMMAND test_fortran_box) add_executable(test_fortran_properties wrap_properties.cpp test_fortran_properties.f90 test_fortran_commands.f90) - target_link_libraries(test_fortran_properties PRIVATE flammps lammps MPI::MPI_Fortran GTest::GMockMain) + target_link_libraries(test_fortran_properties PRIVATE flammps lammps GTest::GMockMain) add_test(NAME FortranProperties COMMAND test_fortran_properties) add_executable(test_fortran_extract_global wrap_extract_global.cpp test_fortran_extract_global.f90) - target_link_libraries(test_fortran_extract_global PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) + target_link_libraries(test_fortran_extract_global PRIVATE flammps lammps GTest::GTestMain) add_test(NAME FortranExtractGlobal COMMAND test_fortran_extract_global) add_executable(test_fortran_extract_atom wrap_extract_atom.cpp test_fortran_extract_atom.f90) - target_link_libraries(test_fortran_extract_atom PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) + target_link_libraries(test_fortran_extract_atom PRIVATE flammps lammps GTest::GTestMain) add_test(NAME FortranExtractAtom COMMAND test_fortran_extract_atom) add_executable(test_fortran_extract_compute wrap_extract_compute.cpp test_fortran_extract_compute.f90) - target_link_libraries(test_fortran_extract_compute PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) + target_link_libraries(test_fortran_extract_compute PRIVATE flammps lammps GTest::GTestMain) add_test(NAME FortranExtractCompute COMMAND test_fortran_extract_compute) add_executable(test_fortran_extract_fix wrap_extract_fix.cpp test_fortran_extract_fix.f90) - target_link_libraries(test_fortran_extract_fix PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) + target_link_libraries(test_fortran_extract_fix PRIVATE flammps lammps GTest::GTestMain) add_test(NAME FortranExtractFix COMMAND test_fortran_extract_fix) add_executable(test_fortran_extract_variable wrap_extract_variable.cpp test_fortran_extract_variable.f90) target_compile_definitions(test_fortran_extract_variable PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}) - target_link_libraries(test_fortran_extract_variable PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) + target_link_libraries(test_fortran_extract_variable PRIVATE flammps lammps GTest::GTestMain) add_test(NAME FortranExtractVariable COMMAND test_fortran_extract_variable) add_executable(test_fortran_gather_scatter wrap_gather_scatter.cpp test_fortran_gather_scatter.f90) - target_link_libraries(test_fortran_gather_scatter PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) + target_link_libraries(test_fortran_gather_scatter PRIVATE flammps lammps GTest::GTestMain) add_test(NAME FortranGatherScatter COMMAND test_fortran_gather_scatter) add_executable(test_fortran_create_atoms wrap_create_atoms.cpp test_fortran_create_atoms.f90) - target_link_libraries(test_fortran_create_atoms PRIVATE flammps lammps MPI::MPI_Fortran GTest::GTestMain) + target_link_libraries(test_fortran_create_atoms PRIVATE flammps lammps GTest::GTestMain) add_test(NAME FortranCreateAtoms COMMAND test_fortran_create_atoms) add_executable(test_fortran_configuration wrap_configuration.cpp test_fortran_configuration.f90 test_fortran_commands.f90) - target_link_libraries(test_fortran_configuration PRIVATE flammps lammps MPI::MPI_Fortran GTest::GMockMain) + target_link_libraries(test_fortran_configuration PRIVATE flammps lammps GTest::GMockMain) add_test(NAME FortranConfiguration COMMAND test_fortran_configuration) add_executable(test_fortran_neighlist wrap_neighlist.cpp test_fortran_neighlist.f90) - target_link_libraries(test_fortran_neighlist PRIVATE flammps lammps MPI::MPI_Fortran GTest::GMockMain) + target_link_libraries(test_fortran_neighlist PRIVATE flammps lammps GTest::GMockMain) add_test(NAME FortranNeighlist COMMAND test_fortran_neighlist) else() diff --git a/unittest/fortran/mpi_stubs.f90 b/unittest/fortran/mpi_stubs.f90 deleted file mode 100644 index 8601f436d2..0000000000 --- a/unittest/fortran/mpi_stubs.f90 +++ /dev/null @@ -1,20 +0,0 @@ -MODULE MPI - IMPLICIT NONE - PRIVATE - - INTEGER, PARAMETER :: MPI_COMM_WORLD=0 - INTEGER, PARAMETER :: MPI_SUCCESS=0 - - PUBLIC :: MPI_COMM_WORLD, MPI_SUCCESS, & - mpi_comm_split - -CONTAINS - - SUBROUTINE mpi_comm_split(comm,color,key,newcomm,ierr) - INTEGER, INTENT(in) :: comm,color,key - INTEGER, INTENT(out) :: newcomm,ierr - - newcomm = comm + 1 - ierr = 0 - END SUBROUTINE mpi_comm_split -END MODULE MPI diff --git a/unittest/fortran/test_fortran_create.f90 b/unittest/fortran/test_fortran_create.f90 index 4ea2a33cfe..fed67064f0 100644 --- a/unittest/fortran/test_fortran_create.f90 +++ b/unittest/fortran/test_fortran_create.f90 @@ -1,3 +1,20 @@ +MODULE MYMPI + USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_int + + IMPLICIT NONE + PRIVATE + PUBLIC :: lmp_comm_split + + INTERFACE + FUNCTION lmp_comm_split(color, key) BIND(C,name='create_mpi_comm_split') + IMPORT :: c_int + IMPLICIT NONE + INTEGER(c_int), VALUE, INTENT(IN) :: color, key + INTEGER(c_int) :: lmp_comm_split + END FUNCTION lmp_comm_split + END INTERFACE +END MODULE MYMPI + FUNCTION f_lammps_no_mpi_no_args() BIND(C, name="f_lammps_no_mpi_no_args") USE ISO_C_BINDING, ONLY: c_ptr USE liblammps @@ -25,35 +42,35 @@ END FUNCTION f_lammps_no_mpi_with_args FUNCTION f_lammps_open_no_args() BIND(C, name="f_lammps_open_no_args") USE ISO_C_BINDING, ONLY: c_ptr - USE MPI, ONLY: MPI_COMM_WORLD, mpi_comm_split + USE MYMPI, ONLY: lmp_comm_split USE liblammps USE keepstuff, ONLY: lmp,mycomm IMPLICIT NONE TYPE(c_ptr) :: f_lammps_open_no_args - INTEGER :: color, key, ierr + INTEGER :: color, key color = 1 key = 1 - CALL mpi_comm_split(MPI_COMM_WORLD, color, key, mycomm, ierr) + mycomm = lmp_comm_split(color, key) lmp = lammps(comm=mycomm) f_lammps_open_no_args = lmp%handle END FUNCTION f_lammps_open_no_args FUNCTION f_lammps_open_with_args() BIND(C, name="f_lammps_open_with_args") USE ISO_C_BINDING, ONLY: c_ptr - USE MPI, ONLY: MPI_COMM_WORLD, mpi_comm_split + USE MYMPI, ONLY: lmp_comm_split USE liblammps USE keepstuff, ONLY: lmp,mycomm IMPLICIT NONE TYPE(c_ptr) :: f_lammps_open_with_args - INTEGER :: color, key, ierr + INTEGER :: color, key CHARACTER(len=12), DIMENSION(4), PARAMETER :: args = & [ CHARACTER(len=12) :: 'liblammps', '-log', 'none', '-nocite' ] color = 2 key = 1 - CALL mpi_comm_split(MPI_COMM_WORLD, color, key, mycomm, ierr) + mycomm = lmp_comm_split(color, key) lmp = lammps(args,mycomm) f_lammps_open_with_args = lmp%handle END FUNCTION f_lammps_open_with_args diff --git a/unittest/fortran/wrap_create.cpp b/unittest/fortran/wrap_create.cpp index 04a62e4040..789e9fca6a 100644 --- a/unittest/fortran/wrap_create.cpp +++ b/unittest/fortran/wrap_create.cpp @@ -17,6 +17,14 @@ void f_lammps_close(); int f_lammps_get_comm(); } +// C wrapper to split MPI communicator w/o requiring a Fortran MPI lib +extern "C" int create_mpi_comm_split(int color, int key) +{ + MPI_Comm c_newcomm = MPI_COMM_NULL; + MPI_Comm_split(MPI_COMM_WORLD, color, key, &c_newcomm); + return MPI_Comm_c2f(c_newcomm); +} + TEST(open_no_mpi, no_args) { ::testing::internal::CaptureStdout();