From e4ea829c35ade0209197170d846b53e4b717ed9b Mon Sep 17 00:00:00 2001 From: "Praetorius, Simon" <simon.praetorius@tu-dresden.de> Date: Thu, 22 Aug 2019 08:46:52 +0200 Subject: [PATCH] Feature/petsc cmake --- cmake/modules/AmdisMacros.cmake | 23 ++++-- cmake/modules/FindPETSc.cmake | 92 ++++++++++++++++++++++ cmake/modules/PkgConfigLinkLibraries.cmake | 56 +++++++++++++ config.h.cmake | 7 +- src/amdis/Environment.cpp | 21 ++++- src/amdis/Environment.hpp | 12 +++ 6 files changed, 201 insertions(+), 10 deletions(-) create mode 100644 cmake/modules/FindPETSc.cmake create mode 100644 cmake/modules/PkgConfigLinkLibraries.cmake diff --git a/cmake/modules/AmdisMacros.cmake b/cmake/modules/AmdisMacros.cmake index 863d990b..0d080888 100644 --- a/cmake/modules/AmdisMacros.cmake +++ b/cmake/modules/AmdisMacros.cmake @@ -1,27 +1,38 @@ include(AmdisCXXFeatures) include(AddAmdisExecutable) -set(BACKEND "ISTL" CACHE STRING "LinearAlgebra backend. One of MTL, EIGEN, ISTL") -set_property(CACHE BACKEND PROPERTY STRINGS "MTL" "EIGEN" "ISTL") +if (NOT BACKEND) + set(BACKEND "ISTL" CACHE STRING "LinearAlgebra backend. One of MTL, EIGEN, PETSC, ISTL") + set_property(CACHE BACKEND PROPERTY STRINGS "MTL" "EIGEN" "ISTL" "PETSC") +endif (NOT BACKEND) if (BACKEND STREQUAL "MTL" OR BACKEND STREQUAL "MTL4") find_package(MTL REQUIRED) - set(HAVE_MTL MTL_FOUND) + set(HAVE_MTL TRUE) if (MTL_FOUND) message(STATUS " Found MTL, version: ${MTL_VERSION}") dune_register_package_flags(LIBRARIES MTL::MTL COMPILE_DEFINITIONS "ENABLE_MTL=1") endif (MTL_FOUND) elseif (BACKEND STREQUAL "EIGEN" OR BACKEND STREQUAL "EIGEN3") find_package(Eigen3 REQUIRED 3.3.5) - set(HAVE_EIGEN EIGEN_FOUND) + set(HAVE_EIGEN TRUE) if (EIGEN3_FOUND) message(STATUS " Found Eigen3, version: ${Eigen3_VERSION}") dune_register_package_flags(LIBRARIES Eigen3::Eigen COMPILE_DEFINITIONS "ENABLE_EIGEN=1") endif (EIGEN3_FOUND) +elseif (BACKEND STREQUAL "PETSC") + find_package(PETSc REQUIRED) + if (PETSc_FOUND) + set(HAVE_PETSC TRUE) + dune_register_package_flags(LIBRARIES PETSc::PETSc COMPILE_DEFINITIONS "ENABLE_PETSC=1") + endif (PETSc_FOUND) elseif (BACKEND STREQUAL "ISTL") if (NOT dune-istl_FOUND) - message(FATAL_ERROR "Need dune-istl, MTL, or Eigen3 as linear algebra backend. Change flag BACKEND!") + message(FATAL_ERROR "Need dune-istl, MTL, PETSc, or Eigen3 as linear algebra backend. Change flag BACKEND!") endif () else () - message(FATAL_ERROR "BACKEND must be one of MTL, EIGEN, ISTL") + message(FATAL_ERROR "BACKEND must be one of MTL, EIGEN, PETSC, ISTL") endif () + + +set(DUNE_CUSTOM_PKG_CONFIG_SECTION "set(BACKEND \"${BACKEND}\")") \ No newline at end of file diff --git a/cmake/modules/FindPETSc.cmake b/cmake/modules/FindPETSc.cmake new file mode 100644 index 00000000..10624fd3 --- /dev/null +++ b/cmake/modules/FindPETSc.cmake @@ -0,0 +1,92 @@ +# FindPETSc.cmake +# +# Finds the PETSc library +# +# This will define the following variables +# +# PETSc_FOUND +# PETSc_VERSION +# +# and the following imported targets +# +# PETSc::PETSc +# +# Author: Simon Praetorius <simon.praetorius@tu-dresden.de> + +include(FindPkgConfig) + +if (NOT PKG_CONFIG_FOUND) + message(FATAL_ERROR "Can not find PkgConfig!") +endif() + +mark_as_advanced(PETSc_FOUND PETSc_VERSION PETSC_PKG_CONFIG) + +find_path(PETSC_PKG_CONFIG "PETSc.pc" + HINTS + ${PETSC_DIR} + ${PETSC_ROOT} + ENV PETSC_DIR + ENV PETSC_ROOT + ENV PKG_CONFIG_PATH + PATHS + /etc/alternatives + /usr/lib/petsc + /usr/lib/petsc/linux-gnu-cxx-opt + /usr/lib/petsc/linux-gnu-c-opt + PATH_SUFFIXES lib/pkgconfig/ +) + +if (PETSC_PKG_CONFIG) + set(ENV{PKG_CONFIG_PATH} "${PETSC_PKG_CONFIG}:$ENV{PKG_CONFIG_PATH}") +endif (PETSC_PKG_CONFIG) + +if (PETSc_FIND_VERSION) + pkg_check_modules(PETSC PETSc>=${PETSc_FIND_VERSION}) +else () + pkg_check_modules(PETSC PETSc) +endif () + +if (PETSC_STATIC_FOUND) + set(_prefix PETSC_STATIC) +elseif (PETSC_FOUND) + set(_prefix PETSC) +endif () + +set(PETSc_VERSION "${${_prefix}_VERSION}") +if ((PETSC_STATIC_FOUND OR PETSC_FOUND) AND NOT TARGET PETSc::PETSc) + add_library(PETSc::PETSc INTERFACE IMPORTED GLOBAL) + if (${_prefix}_INCLUDE_DIRS) + set_property(TARGET PETSc::PETSc PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${${_prefix}_INCLUDE_DIRS}") + endif () + if (${_prefix}_LINK_LIBRARIES) + set_property(TARGET PETSc::PETSc PROPERTY + INTERFACE_LINK_LIBRARIES "${${_prefix}_LINK_LIBRARIES}") + else () + # extract the absolute paths of link libraries from the LDFLAGS + include(PkgConfigLinkLibraries) + pkg_config_link_libraries(${_prefix} _libs) + set_property(TARGET PETSc::PETSc PROPERTY + INTERFACE_LINK_LIBRARIES "${_libs}") + unset(_libs) + endif () + if (${_prefix}_LDFLAGS_OTHER) + set_property(TARGET PETSc::PETSc PROPERTY + INTERFACE_LINK_OPTIONS "${${_prefix}_LDFLAGS_OTHER}") + endif () + if (${_prefix}_CFLAGS_OTHER) + set_property(TARGET PETSc::PETSc PROPERTY + INTERFACE_COMPILE_OPTIONS "${${_prefix}_CFLAGS_OTHER}") + endif () +endif () +unset(_prefix) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PETSc + REQUIRED_VARS PETSc_VERSION + VERSION_VAR PETSc_VERSION +) + +# text for feature summary +set_package_properties("PETSc" PROPERTIES + DESCRIPTION "Portable, Extensible Toolkit for Scientific Computation") \ No newline at end of file diff --git a/cmake/modules/PkgConfigLinkLibraries.cmake b/cmake/modules/PkgConfigLinkLibraries.cmake new file mode 100644 index 00000000..ee8c2393 --- /dev/null +++ b/cmake/modules/PkgConfigLinkLibraries.cmake @@ -0,0 +1,56 @@ +# PkgConfigLinkLibraries.cmake +# +# Scan the LDFLAGS returned by pkg-config for library directories and +# libraries and figure out the absolute paths of that libraries in the +# given directories. +# +# This macro is extracted from FindPkgConfig.cmake +# +# This will define the following macro +# +# pkg_config_link_libraries(PREFIX, OUTPUT) +# +# .. cmake_macro:: pkg_config_link_libraries +# +# .. cmake_brief:: +# +# Creates a list ob absolute path for link libraries +# +# .. cmake_param:: PREFIX +# :single: +# +# The module prefix (including _STATIC for static libraries) +# +# .. cmake_param:: OUTPUT +# :single: +# +# The name of the output list of absolute paths +# +# +# Author: Simon Praetorius <simon.praetorius@tu-dresden.de> + +macro(pkg_config_link_libraries _prefix _output) + unset(_search_paths) + foreach (flag IN LISTS ${_prefix}_LDFLAGS) + if (flag MATCHES "^-L(.*)") + list(APPEND _search_paths ${CMAKE_MATCH_1}) + continue() + endif() + if (flag MATCHES "^-l(.*)") + set(_pkg_search "${CMAKE_MATCH_1}") + else() + continue() + endif() + + if(_search_paths) + # Firstly search in -L paths + find_library(pkgcfg_lib_${_prefix}_${_pkg_search} + NAMES ${_pkg_search} + HINTS ${_search_paths} NO_DEFAULT_PATH) + endif() + find_library(pkgcfg_lib_${_prefix}_${_pkg_search} + NAMES ${_pkg_search} + ${_find_opts}) + list(APPEND ${_output} "${pkgcfg_lib_${_prefix}_${_pkg_search}}") + endforeach() +endmacro(pkg_config_link_libraries) \ No newline at end of file diff --git a/config.h.cmake b/config.h.cmake index d570e2d3..ec1f0739 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -40,12 +40,15 @@ /* Define to the revision of amdis */ #define AMDIS_VERSION_REVISION @AMDIS_VERSION_REVISION@ -/* Define to ENABLE_MTL if the MTL library is available */ +/* Define to true if the MTL library is available */ #cmakedefine HAVE_MTL 1 -/* Define to ENABLE_EIGEN if the Eigen3 library is available */ +/* Define to true if the Eigen3 library is available */ #cmakedefine HAVE_EIGEN 1 +/* Define to true if the PETSc library is available */ +#cmakedefine HAVE_PETSC ENABLE_PETSC + /* some detected compiler features may be used in AMDiS */ #cmakedefine AMDIS_HAS_CXX_FOLD_EXPRESSIONS 1 #cmakedefine AMDIS_HAS_CXX_CONSTEXPR_IF 1 diff --git a/src/amdis/Environment.cpp b/src/amdis/Environment.cpp index 08cd067c..c7625130 100644 --- a/src/amdis/Environment.cpp +++ b/src/amdis/Environment.cpp @@ -4,6 +4,10 @@ #include "Environment.hpp" +#if HAVE_PETSC +#include <petscsys.h> +#endif + // AMDiS includes #include <amdis/Initfile.hpp> #include <amdis/Output.hpp> @@ -17,13 +21,17 @@ namespace AMDiS Parameters::init(initFileName); } + Environment::Environment(int& argc, char**& argv, std::string const& initFileName) : Environment(initFileName) { - auto& helper = Dune::MPIHelper::instance(argc, argv); +#if HAVE_PETSC + PetscInitialize(&argc, &argv, PETSC_NULL, PETSC_NULL); + petscInitialized_ = true; +#endif auto& mpi = Mpi::instance(); - mpi.registerMpiHelper(helper); + mpi.registerMpiHelper(Dune::MPIHelper::instance(argc, argv)); Parameters::clearData(); if (initFileName.empty()) { @@ -34,4 +42,13 @@ namespace AMDiS } } + + Environment::~Environment() + { +#if HAVE_PETSC + if (petscInitialized_) + PetscFinalize(); +#endif + } + } // end namespace AMDiS diff --git a/src/amdis/Environment.hpp b/src/amdis/Environment.hpp index 67b8b07f..21abf85c 100644 --- a/src/amdis/Environment.hpp +++ b/src/amdis/Environment.hpp @@ -56,6 +56,9 @@ namespace AMDiS /// or the provided initfile filename. Environment(int& argc, char**& argv, std::string const& initFileName = ""); + /// Finishes MPI and PETSc + ~Environment(); + /// Return the MPI_Rank of the current processor. static int mpiRank() { @@ -67,6 +70,15 @@ namespace AMDiS { return Mpi::instance().size(); } + + /// Return the MPI_Comm object (or a fake communicator) + static typename Dune::MPIHelper::MPICommunicator comm() + { + return Dune::MPIHelper::getCommunicator(); + } + + private: + bool petscInitialized_ = false; }; } // end namespace AMDiS -- GitLab