add c wrapper to allow testing fortran interface w/o fortran MPI libs

This commit is contained in:
Axel Kohlmeyer
2022-12-11 17:50:03 -05:00
parent 0984b11cb4
commit c0a39dc7b8
4 changed files with 48 additions and 61 deletions

View File

@ -21,20 +21,6 @@ if(CMAKE_Fortran_COMPILER)
endif() endif()
get_filename_component(LAMMPS_FORTRAN_MODULE ${LAMMPS_SOURCE_DIR}/../fortran/lammps.f90 ABSOLUTE) 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) add_library(flammps STATIC ${LAMMPS_FORTRAN_MODULE} keepstuff.f90)
get_filename_component(_tmp_fc ${CMAKE_Fortran_COMPILER} NAME) get_filename_component(_tmp_fc ${CMAKE_Fortran_COMPILER} NAME)
@ -42,66 +28,62 @@ if(CMAKE_Fortran_COMPILER)
target_link_libraries(flammps PUBLIC gfortran) target_link_libraries(flammps PUBLIC gfortran)
endif() endif()
if(MPI_Fortran_HAVE_F90_MODULE) add_executable(test_fortran_create wrap_create.cpp test_fortran_create.f90)
add_executable(test_fortran_create wrap_create.cpp test_fortran_create.f90) target_link_libraries(test_fortran_create PRIVATE flammps lammps GTest::GTestMain)
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")
target_include_directories(test_fortran_create PRIVATE "${LAMMPS_SOURCE_DIR}/../fortran") add_test(NAME FortranOpen COMMAND test_fortran_create)
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_commands wrap_commands.cpp test_fortran_commands.f90) 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_test(NAME FortranCommands COMMAND test_fortran_commands)
add_executable(test_fortran_get_thermo wrap_get_thermo.cpp test_fortran_get_thermo.f90) 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_test(NAME FortranGetThermo COMMAND test_fortran_get_thermo)
add_executable(test_fortran_box wrap_box.cpp test_fortran_box.f90) 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_test(NAME FortranBox COMMAND test_fortran_box)
add_executable(test_fortran_properties wrap_properties.cpp test_fortran_properties.f90 test_fortran_commands.f90) 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_test(NAME FortranProperties COMMAND test_fortran_properties)
add_executable(test_fortran_extract_global wrap_extract_global.cpp test_fortran_extract_global.f90) 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_test(NAME FortranExtractGlobal COMMAND test_fortran_extract_global)
add_executable(test_fortran_extract_atom wrap_extract_atom.cpp test_fortran_extract_atom.f90) 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_test(NAME FortranExtractAtom COMMAND test_fortran_extract_atom)
add_executable(test_fortran_extract_compute wrap_extract_compute.cpp test_fortran_extract_compute.f90) 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_test(NAME FortranExtractCompute COMMAND test_fortran_extract_compute)
add_executable(test_fortran_extract_fix wrap_extract_fix.cpp test_fortran_extract_fix.f90) 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_test(NAME FortranExtractFix COMMAND test_fortran_extract_fix)
add_executable(test_fortran_extract_variable wrap_extract_variable.cpp test_fortran_extract_variable.f90) 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_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_test(NAME FortranExtractVariable COMMAND test_fortran_extract_variable)
add_executable(test_fortran_gather_scatter wrap_gather_scatter.cpp test_fortran_gather_scatter.f90) 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_test(NAME FortranGatherScatter COMMAND test_fortran_gather_scatter)
add_executable(test_fortran_create_atoms wrap_create_atoms.cpp test_fortran_create_atoms.f90) 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_test(NAME FortranCreateAtoms COMMAND test_fortran_create_atoms)
add_executable(test_fortran_configuration wrap_configuration.cpp test_fortran_configuration.f90 test_fortran_commands.f90) 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_test(NAME FortranConfiguration COMMAND test_fortran_configuration)
add_executable(test_fortran_neighlist wrap_neighlist.cpp test_fortran_neighlist.f90) 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) add_test(NAME FortranNeighlist COMMAND test_fortran_neighlist)
add_executable(test_fortran_fixexternal wrap_fixexternal.cpp test_fortran_fixexternal.f90) add_executable(test_fortran_fixexternal wrap_fixexternal.cpp test_fortran_fixexternal.f90)

View File

@ -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

View File

@ -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") FUNCTION f_lammps_no_mpi_no_args() BIND(C, name="f_lammps_no_mpi_no_args")
USE ISO_C_BINDING, ONLY: c_ptr USE ISO_C_BINDING, ONLY: c_ptr
USE liblammps 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") FUNCTION f_lammps_open_no_args() BIND(C, name="f_lammps_open_no_args")
USE ISO_C_BINDING, ONLY: c_ptr 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 liblammps
USE keepstuff, ONLY: lmp,mycomm USE keepstuff, ONLY: lmp,mycomm
IMPLICIT NONE IMPLICIT NONE
TYPE(c_ptr) :: f_lammps_open_no_args TYPE(c_ptr) :: f_lammps_open_no_args
INTEGER :: color, key, ierr INTEGER :: color, key
color = 1 color = 1
key = 1 key = 1
CALL mpi_comm_split(MPI_COMM_WORLD, color, key, mycomm, ierr) mycomm = lmp_comm_split(color, key)
lmp = lammps(comm=mycomm) lmp = lammps(comm=mycomm)
f_lammps_open_no_args = lmp%handle f_lammps_open_no_args = lmp%handle
END FUNCTION f_lammps_open_no_args END FUNCTION f_lammps_open_no_args
FUNCTION f_lammps_open_with_args() BIND(C, name="f_lammps_open_with_args") FUNCTION f_lammps_open_with_args() BIND(C, name="f_lammps_open_with_args")
USE ISO_C_BINDING, ONLY: c_ptr 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 liblammps
USE keepstuff, ONLY: lmp,mycomm USE keepstuff, ONLY: lmp,mycomm
IMPLICIT NONE IMPLICIT NONE
TYPE(c_ptr) :: f_lammps_open_with_args 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), DIMENSION(4), PARAMETER :: args = &
[ CHARACTER(len=12) :: 'liblammps', '-log', 'none', '-nocite' ] [ CHARACTER(len=12) :: 'liblammps', '-log', 'none', '-nocite' ]
color = 2 color = 2
key = 1 key = 1
CALL mpi_comm_split(MPI_COMM_WORLD, color, key, mycomm, ierr) mycomm = lmp_comm_split(color, key)
lmp = lammps(args,mycomm) lmp = lammps(args,mycomm)
f_lammps_open_with_args = lmp%handle f_lammps_open_with_args = lmp%handle
END FUNCTION f_lammps_open_with_args END FUNCTION f_lammps_open_with_args

View File

@ -17,6 +17,14 @@ void f_lammps_close();
int f_lammps_get_comm(); 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) TEST(open_no_mpi, no_args)
{ {
::testing::internal::CaptureStdout(); ::testing::internal::CaptureStdout();