Merge pull request #2609 from akohlmey/collected-small-changes

Python MPI compatibility improvements
This commit is contained in:
Axel Kohlmeyer
2021-02-17 18:03:08 -05:00
committed by GitHub
13 changed files with 53 additions and 52 deletions

View File

@ -156,8 +156,7 @@ if(BUILD_MPI)
endif()
endif()
else()
enable_language(C)
file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.c)
file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.cpp)
add_library(mpi_stubs STATIC ${MPI_SOURCES})
set_target_properties(mpi_stubs PROPERTIES OUTPUT_NAME lammps_mpi_stubs${LAMMPS_MACHINE})
target_include_directories(mpi_stubs PUBLIC $<BUILD_INTERFACE:${LAMMPS_SOURCE_DIR}/STUBS>)

View File

@ -2,9 +2,8 @@ if(LAMMPS_SIZES STREQUAL BIGBIG)
message(FATAL_ERROR "The MESSAGE Package is not compatible with -DLAMMPS_BIGBIG")
endif()
option(MESSAGE_ZMQ "Use ZeroMQ in MESSAGE package" OFF)
file(GLOB_RECURSE cslib_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/message/cslib/[^.]*.F
${LAMMPS_LIB_SOURCE_DIR}/message/cslib/[^.]*.c
${LAMMPS_LIB_SOURCE_DIR}/message/cslib/[^.]*.cpp)
file(GLOB_RECURSE cslib_SOURCES
${LAMMPS_LIB_SOURCE_DIR}/message/cslib/[^.]*.cpp)
add_library(cslib STATIC ${cslib_SOURCES})
target_compile_definitions(cslib PRIVATE -DLAMMPS_${LAMMPS_SIZES})

View File

@ -95,7 +95,7 @@ standard. A more detailed discussion of that is below.
.. note::
The file ``src/STUBS/mpi.c`` provides a CPU timer function
The file ``src/STUBS/mpi.cpp`` provides a CPU timer function
called ``MPI_Wtime()`` that calls ``gettimeofday()``. If your
operating system does not support ``gettimeofday()``, you will
need to insert code to call another timer. Note that the

View File

@ -20,16 +20,8 @@ the suffix ``.so.0`` (or some other number).
.. note::
Care should be taken to use the same MPI library for the calling code
and the LAMMPS library. The ``library.h`` file includes ``mpi.h``
and uses definitions from it so those need to be available and
consistent. When LAMMPS is compiled with the included STUBS MPI
library, then its ``mpi.h`` file needs to be included. While it is
technically possible to use a full MPI library in the calling code
and link to a serial LAMMPS library compiled with MPI STUBS, it is
recommended to use the *same* MPI library for both, and then use
``MPI_Comm_split()`` in the calling code to pass a suitable
communicator with a subset of MPI ranks to the function creating the
LAMMPS instance.
and the LAMMPS library unless LAMMPS is to be compiled without (real)
MPI support using the include STUBS MPI library.
Link with LAMMPS as a static library
------------------------------------
@ -110,7 +102,7 @@ executable, that are also required to link the LAMMPS executable.
.. code-block:: bash
gcc -c -O -I${HOME}/lammps/src/STUBS -I${HOME}/lammps/src -caller.c
gcc -c -O -I${HOME}/lammps/src -caller.c
g++ -o caller caller.o -L${HOME}/lammps/lib/poems \
-L${HOME}/lammps/src/STUBS -L${HOME}/lammps/src \
-llammps_serial -lpoems -lmpi_stubs
@ -174,7 +166,7 @@ the POEMS package installed becomes:
.. code-block:: bash
gcc -c -O -I${HOME}/lammps/src/STUBS -I${HOME}/lammps/src -caller.c
gcc -c -O -I${HOME}/lammps/src -caller.c
g++ -o caller caller.o -L${HOME}/lammps/src -llammps_serial
Locating liblammps.so at runtime

View File

@ -286,15 +286,16 @@ class lammps(object):
self.lib.lammps_fix_external_set_energy_global = [c_void_p, c_char_p, c_double]
self.lib.lammps_fix_external_set_virial_global = [c_void_p, c_char_p, POINTER(c_double)]
# detect if Python is using version of mpi4py that can pass a communicator
# detect if Python is using a version of mpi4py that can pass communicators
# only needed if LAMMPS has been compiled with MPI support.
self.has_mpi4py = False
try:
from mpi4py import __version__ as mpi4py_version
# tested to work with mpi4py versions 2 and 3
self.has_mpi4py = mpi4py_version.split('.')[0] in ['2','3']
except:
pass
if self.has_mpi_support:
try:
from mpi4py import __version__ as mpi4py_version
# tested to work with mpi4py versions 2 and 3
self.has_mpi4py = mpi4py_version.split('.')[0] in ['2','3']
except:
pass
# if no ptr provided, create an instance of LAMMPS
# don't know how to pass an MPI communicator from PyPar
@ -307,23 +308,27 @@ class lammps(object):
if not ptr:
# with mpi4py v2, can pass MPI communicator to LAMMPS
# with mpi4py v2+, we can pass MPI communicators to LAMMPS
# need to adjust for type of MPI communicator object
# allow for int (like MPICH) or void* (like OpenMPI)
if self.has_mpi4py and self.has_mpi_support:
if self.has_mpi_support and self.has_mpi4py:
from mpi4py import MPI
self.MPI = MPI
if comm:
if not self.has_mpi4py:
raise Exception('Python mpi4py version is not 2 or 3')
if not self.has_mpi_support:
raise Exception('LAMMPS not compiled with real MPI library')
if not self.has_mpi4py:
raise Exception('Python mpi4py version is not 2 or 3')
if self.MPI._sizeof(self.MPI.Comm) == sizeof(c_int):
MPI_Comm = c_int
else:
MPI_Comm = c_void_p
# Detect whether LAMMPS and mpi4py definitely use different MPI libs
if sizeof(MPI_Comm) != self.lib.lammps_config_has_mpi_support():
raise Exception('Inconsistent MPI library in LAMMPS and mpi4py')
narg = 0
cargs = None
if cmdargs:

View File

@ -11,13 +11,13 @@ SHELL = /bin/sh
# Files
SRC = mpi.c
SRC = mpi.cpp
INC = mpi.h
# Definitions
EXE = libmpi_stubs.a
OBJ = $(SRC:.c=.o)
OBJ = $(SRC:.cpp=.o)
# System-specific settings
@ -36,7 +36,7 @@ clean:
# Compilation rules
.c.o:
.cpp.o:
$(CC) $(CCFLAGS) -c $<
# Individual dependencies

View File

@ -5,17 +5,17 @@ SHELL = /bin/sh
# Files
SRC = mpi.c
SRC = mpi.cpp
INC = mpi.h
# Definitions
EXE = libmpi_mingw32.a
OBJ = $(SRC:%.c=%_mingw32.o)
OBJ = $(SRC:%.cpp=%_mingw32.o)
# System-specific settings
CC = i686-w64-mingw32-gcc
CC = i686-w64-mingw32-g++
CCFLAGS = -O2 -Wall -march=i686 -mtune=generic -mfpmath=387 -mpc64 -I.
ARCHIVE = i686-w64-mingw32-ar
ARCHFLAG = rs

View File

@ -5,17 +5,17 @@ SHELL = /bin/sh
# Files
SRC = mpi.c
SRC = mpi.cpp
INC = mpi.h
# Definitions
EXE = libmpi_mingw64.a
OBJ = $(SRC:%.c=%_mingw64.o)
OBJ = $(SRC:%.cpp=%_mingw64.o)
# System-specific settings
CC = x86_64-w64-mingw32-gcc
CC = x86_64-w64-mingw32-g++
CCFLAGS = -O2 -Wall -march=core2 -mtune=core2 -msse2 -mpc64 -I.
ARCHIVE = x86_64-w64-mingw32-ar
ARCHFLAG = rs

View File

@ -16,12 +16,17 @@
#include <stdlib.h>
/* use C bindings for MPI interface */
/* We compile STUBS with C++ so the symbols embedded
* the serial shared library will not collide with any
* corresponding symbols from a real MPI library (which
* uses C bindings). As a consequence the header *must*
* enforce compiling with C++ only. */
#ifdef __cplusplus
extern "C" {
#ifndef __cplusplus
#error "MPI STUBS must be compiled with a C++ compiler"
#endif
/* Dummy defs for MPI stubs */
#define MPI_COMM_WORLD 0
@ -176,8 +181,4 @@ int MPI_Alltoallv(void *sendbuf, int *sendcounts, int *sdispls,
MPI_Datatype recvtype, MPI_Comm comm);
/* ---------------------------------------------------------------------- */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -4128,16 +4128,18 @@ void lammps_get_os_info(char *buffer, int buf_size)
/* ---------------------------------------------------------------------- */
/** This function is used to query whether LAMMPS was compiled with
* a real MPI library or in serial.
* a real MPI library or in serial. For the real MPI library it
* reports the size of the MPI communicator in bytes (4 or 8),
* which allows to check for compatibility with a hosting code.
*
* \return 0 when compiled with MPI STUBS, otherwise 1 */
* \return 0 when compiled with MPI STUBS, otherwise the MPI_Comm size in bytes */
int lammps_config_has_mpi_support()
{
#ifdef MPI_STUBS
return 0;
#else
return 1;
return sizeof(MPI_Comm);
#endif
}

View File

@ -74,7 +74,7 @@ TEST(LAMMPSConfig, package_name)
EXPECT_EQ(lammps_config_package_name(numpkgs + 10, buf, 128), 0);
EXPECT_THAT(buf, StrEq(""));
} else {
EXPECT_EQ(lammps_config_package_name(0, buf, 128), 1);
EXPECT_EQ(lammps_config_package_name(0, buf, 128), 0);
EXPECT_THAT(buf, StrEq(""));
}
};
@ -200,7 +200,10 @@ TEST(LAMMPSConfig, exceptions)
TEST(LAMMPSConfig, mpi_support)
{
EXPECT_EQ(lammps_config_has_mpi_support(), LAMMPS_HAS_MPI);
if (LAMMPS_HAS_MPI)
EXPECT_GT(lammps_config_has_mpi_support(), 0);
else
EXPECT_EQ(lammps_config_has_mpi_support(), 0);
};
TEST(LAMMPSConfig, png_support)

View File

@ -37,7 +37,7 @@ class PythonOpen(unittest.TestCase):
lmp=lammps(name=self.machine)
self.assertIsNot(lmp.lmp,None)
self.assertEqual(lmp.opened,1)
self.assertEqual(has_mpi4py,lmp.has_mpi4py)
self.assertEqual(has_mpi and has_mpi4py,lmp.has_mpi4py)
self.assertEqual(has_mpi,lmp.has_mpi_support)
lmp.close()
self.assertIsNone(lmp.lmp,None)