Merge pull request #2609 from akohlmey/collected-small-changes
Python MPI compatibility improvements
This commit is contained in:
@ -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>)
|
||||
|
||||
@ -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})
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
Reference in New Issue
Block a user