diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a1dd9f..ac95fdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,8 @@ project(_pylibROM) set(CMAKE_BUILD_TYPE Debug) set(PYBIND11_FINDPYTHON ON) +option (USE_MFEM "Build pylibROM with MFEM" OFF) + #=================== ScaLAPACK (optional) ================== option(BUILD_SCALAPACK "Build static ScaLAPACK for libROM" OFF) @@ -50,14 +52,18 @@ if (BUILD_LIBROM) # ) # add_custom_target(RUN_LIBROM_BUILD ALL DEPENDS LIBROM_BUILD) + option (LIBROM_BUILD_CMD "Command used to build libROM and dependencies" CACHE STRING "${LIBROM_SCRIPTS_DIR}/compile.sh -t ${LIBROM_DIR}/cmake/toolchains/simple.cmake") + if (USE_MFEM) + set(LIBROM_BUILD_CMD "${LIBROM_BUILD_CMD} -m -g") + endif() ExternalProject_Add( libROM SOURCE_DIR ${LIBROM_SCRIPTS_DIR} CONFIGURE_COMMAND "" BINARY_DIR ${LIBROM_DIR} - BUILD_COMMAND ${LIBROM_SCRIPTS_DIR}/compile.sh -m -g -t ${LIBROM_DIR}/cmake/toolchains/simple.cmake - INSTALL_COMMAND "" - ) + BUILD_COMMAND ${LIBROM_BUILD_CMD} + INSTALL_COMMAND "" + ) message("Building libROM dependency...") endif(BUILD_LIBROM) @@ -72,32 +78,33 @@ execute_process(COMMAND python3 -c "import mpi4py; print(mpi4py.get_include())" # # TODO(kevin): We do not bind mfem-related functions until we figure out how to type-cast SWIG Object. # # Until then, mfem-related functions need to be re-implemented on python-end, using PyMFEM. -find_library(MFEM mfem - "$ENV{MFEM_DIR}/lib" - "$ENV{MFEM_DIR}" - "${LIBROM_DIR}/dependencies/mfem") -find_library(HYPRE HYPRE - "$ENV{HYPRE_DIR}/lib" - "${LIBROM_DIR}/dependencies/hypre/src/hypre/lib") -find_library(PARMETIS parmetis - "$ENV{PARMETIS_DIR}/lib" - "$ENV{PARMETIS_DIR}/build/lib/libparmetis" - "${LIBROM_DIR}/dependencies/parmetis-4.0.3/build/lib/libparmetis") -find_library(METIS metis - "$ENV{METIS_DIR}/lib" - "$ENV{PARMETIS_DIR}/build/lib/libmetis" - "${LIBROM_DIR}/dependencies/parmetis-4.0.3/build/lib/libmetis") -find_path(MFEM_INCLUDES mfem.hpp - "$ENV{MFEM_DIR}/include" - "$ENV{MFEM_DIR}" - "${LIBROM_DIR}/dependencies/mfem") -find_path(HYPRE_INCLUDES HYPRE.h - "$ENV{HYPRE_DIR}/include" - "${LIBROM_DIR}/dependencies/hypre/src/hypre/include") -find_path(PARMETIS_INCLUDES metis.h - "$ENV{PARMETIS_DIR}/metis/include" - "${LIBROM_DIR}/dependencies/parmetis-4.0.3/metis/include") - +if (USE_MFEM) + find_library(MFEM mfem + "$ENV{MFEM_DIR}/lib" + "$ENV{MFEM_DIR}" + "${LIBROM_DIR}/dependencies/mfem") + find_library(HYPRE HYPRE + "$ENV{HYPRE_DIR}/lib" + "${LIBROM_DIR}/dependencies/hypre/src/hypre/lib") + find_library(PARMETIS parmetis + "$ENV{PARMETIS_DIR}/lib" + "$ENV{PARMETIS_DIR}/build/lib/libparmetis" + "${LIBROM_DIR}/dependencies/parmetis-4.0.3/build/lib/libparmetis") + find_library(METIS metis + "$ENV{METIS_DIR}/lib" + "$ENV{PARMETIS_DIR}/build/lib/libmetis" + "${LIBROM_DIR}/dependencies/parmetis-4.0.3/build/lib/libmetis") + find_path(MFEM_INCLUDES mfem.hpp + "$ENV{MFEM_DIR}/include" + "$ENV{MFEM_DIR}" + "${LIBROM_DIR}/dependencies/mfem") + find_path(HYPRE_INCLUDES HYPRE.h + "$ENV{HYPRE_DIR}/include" + "${LIBROM_DIR}/dependencies/hypre/src/hypre/include") + find_path(PARMETIS_INCLUDES metis.h + "$ENV{PARMETIS_DIR}/metis/include" + "${LIBROM_DIR}/dependencies/parmetis-4.0.3/metis/include") +endif() #===================== pylibROM ============================= @@ -105,30 +112,36 @@ set(CMAKE_CXX_STANDARD 14) find_package(MPI REQUIRED) -set(SOURCE_DIR "bindings/pylibROM") +set(SOURCE_DIR "bindings/pylibROM") include_directories( ${SOURCE_DIR} ${LIBROM_INCLUDE_DIR} ${MPI_INCLUDE_PATH} ${MPI4PY} ${HDF5_C_INCLUDE_DIRS} - ${MFEM_INCLUDES} - ${HYPRE_INCLUDES} - ${PARMETIS_INCLUDES} - ${MFEM_C_INCLUDE_DIRS} -) -link_libraries( - ${HDF5_LIBRARIES} - ${MFEM} - ${HYPRE} - ${PARMETIS} - ${METIS} ) +link_libraries(${HDF5_LIBRARIES}) + +if (USE_MFEM) + target_include_directories( + _pylibROM + ${MFEM_INCLUDES} + ${HYPRE_INCLUDES} + ${PARMETIS_INCLUDES} + ${MFEM_C_INCLUDE_DIRS}) + + target_link_libraries( + _pylibROM + ${MFEM} + ${HYPRE} + ${PARMETIS} + ${METIS}) +endif() add_subdirectory("extern/pybind11") -pybind11_add_module(_pylibROM - bindings/pylibROM/pylibROM.cpp +set(PYLIBROM_SOURCES + bindings/pylibROM/pylibROM.cpp bindings/pylibROM/linalg/pyMatrix.cpp bindings/pylibROM/linalg/pyVector.cpp @@ -162,12 +175,17 @@ pybind11_add_module(_pylibROM bindings/pylibROM/utils/pyHDFDatabase.cpp bindings/pylibROM/utils/pyCSVDatabase.cpp - bindings/pylibROM/mfem/pyUtilities.cpp - bindings/pylibROM/mfem/pyPointwiseSnapshot.cpp - bindings/pylibROM/mfem/pySampleMesh.cpp - bindings/pylibROM/python_utils/cpp_utils.hpp ) + +if (USE_MFEM) + set(PYLIBROM_SOURCES ${PYLIBROM_SOURCES} + bindings/pylibROM/mfem/pyUtilities.cpp + bindings/pylibROM/mfem/pyPointwiseSnapshot.cpp + bindings/pylibROM/mfem/pySampleMesh.cpp) +endif() + +pybind11_add_module(_pylibROM ${PYLIBROM_SOURCES}) message("building pylibROM...") target_link_libraries(_pylibROM PRIVATE ROM) diff --git a/bindings/pylibROM/__init__.py b/bindings/pylibROM/__init__.py index 8353c0f..19641a6 100644 --- a/bindings/pylibROM/__init__.py +++ b/bindings/pylibROM/__init__.py @@ -6,4 +6,14 @@ # either define/import the python routine in this file. # This will combine both c++ bindings/pure python routines into this module. -from _pylibROM import * +from _pylibROM.algo import * +from _pylibROM.hyperreduction import * +from _pylibROM.linalg import * + +try: + import _pylibROM.mfem + from _pylibROM.mfem import * +except: + pass + +from _pylibROM.utils import * diff --git a/bindings/pylibROM/pylibROM.cpp b/bindings/pylibROM/pylibROM.cpp index c3a5ddd..9d07bc9 100644 --- a/bindings/pylibROM/pylibROM.cpp +++ b/bindings/pylibROM/pylibROM.cpp @@ -1,5 +1,7 @@ #include +#include "CAROM_config.h" + namespace py = pybind11; //linalg @@ -42,10 +44,12 @@ void init_Database(pybind11::module_ &m); void init_HDFDatabase(pybind11::module_ &m); void init_CSVDatabase(pybind11::module_ &m); +#ifdef CAROM_HAS_MFEM //mfem void init_mfem_Utilities(pybind11::module_ &m); void init_mfem_PointwiseSnapshot(pybind11::module_ &m); void init_mfem_SampleMesh(pybind11::module_ &m); +#endif PYBIND11_MODULE(_pylibROM, m) { py::module utils = m.def_submodule("utils"); @@ -87,10 +91,12 @@ PYBIND11_MODULE(_pylibROM, m) { init_STSampling(hyperreduction); init_Utilities(hyperreduction); +#ifdef CAROM_HAS_MFEM py::module mfem = m.def_submodule("mfem"); init_mfem_Utilities(mfem); init_mfem_PointwiseSnapshot(mfem); init_mfem_SampleMesh(mfem); +#endif // py::module python_utils = m.def_submodule("python_utils"); } diff --git a/setup.py b/setup.py index 5d3cac1..d796d4c 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ # Take the global option for pre-installed librom directory. librom_dir = None install_scalapack = False +use_mfem = True for arg in sys.argv: if (arg[:13] == "--librom_dir="): librom_dir = arg[13:] @@ -23,6 +24,12 @@ if "--install_scalapack" in sys.argv: install_scalapack = True sys.argv.remove("--install_scalapack") +if "--no-mfem" in sys.argv: + use_mfem = False + sys.argv.remove("--no-mfem") +if "--use-mfem" in sys.argv: + use_mfem = True + sys.argv.remove("--use-mfem") # Convert distutils Windows platform specifiers to CMake -A arguments PLAT_TO_CMAKE = { @@ -64,8 +71,9 @@ def build_extension(self, ext: CMakeExtension) -> None: librom_dir += "/extern/libROM" print("Installing libROM library: %s" % librom_dir) - librom_cmd = "cd %s && ./scripts/compile.sh -m -g -t ./cmake/toolchains/simple.cmake" % librom_dir + librom_cmd = "cd %s && ./scripts/compile.sh -t ./cmake/toolchains/simple.cmake" % librom_dir if (install_scalapack): librom_cmd += " -s" + if (use_mfem): librom_cmd += " -m -g" print("libROM installation command: %s" % librom_cmd) subprocess.run( librom_cmd, shell=True, check=True @@ -73,6 +81,8 @@ def build_extension(self, ext: CMakeExtension) -> None: else: print("Using pre-installed libROM library: %s" % librom_dir) cmake_args += [f"-DLIBROM_DIR=%s" % librom_dir] + if (not use_mfem): + cmake_args += ["-DUSE_MFEM=OFF"] # Set Python_EXECUTABLE instead if you use PYBIND11_FINDPYTHON # EXAMPLE_VERSION_INFO shows you how to pass a value into the C++ code @@ -165,7 +175,7 @@ def build_extension(self, ext: CMakeExtension) -> None: # author_email="dean0x7d@gmail.com", description="Python Interface for LLNL libROM", long_description="", - packages=find_packages(where='bindings'), + packages=find_packages(where='bindings', exclude=['pylibROM.mfem'] if use_mfem == False else ['']), package_dir={"":"bindings"}, # packages=['bindings/pylibROM'], ext_modules=[CMakeExtension("_pylibROM")],