Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working IDAKLU standalone build and wheels #3

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 78 additions & 3 deletions .gitignore
kratman marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,4 +1,79 @@
.idea
.vscode
*.txt
*.tmp
*.DS_Store
*.pkl

# don't ignore important .txt and .csv files
!LICENSE.txt
!CMakeLists.txt

# running files
*.pyc
*.py~
.~lock*
*.swp

# Python cache
*__pycache__/
*.cache
.pytest_cache

# Sphinx build files
build/

# setup.py files
*.egg-info
__pycache__
dist/

# coverage
.coverage
coverage.xml

# virtual environment
env/
venv/
venv3.5/
bin/
etc/
lib/
lib64
share/
pyvenv.cfg
.vscode
.ruff_cache/

# sundials
sundials
sundials4
sundials-*
SuiteSparse-*
build_sundials
KLU_module_deps


# cmakefiles
CMakeFiles
Makefile
cmake_install.cmake
*.so

third-party/pybind11
pybind11/

# Build dependencies/
KLU_module_deps

# setup
setup.log

# tox
.tox/

# nox
.nox/

# vcpkg
vcpkg_installed/

# tests
test_callback.log
171 changes: 171 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
cmake_minimum_required(VERSION 3.13)
cmake_policy(SET CMP0074 NEW)
set(CMAKE_VERBOSE_MAKEFILE ON)

if(DEFINED ENV{VCPKG_ROOT_DIR} AND NOT DEFINED VCPKG_ROOT_DIR)
set(VCPKG_ROOT_DIR "$ENV{VCPKG_ROOT_DIR}"
CACHE STRING "Vcpkg root directory")
endif()

if(DEFINED VCPKG_ROOT_DIR)
set(CMAKE_TOOLCHAIN_FILE ${VCPKG_ROOT_DIR}/scripts/buildsystems/vcpkg.cmake
CACHE STRING "Vcpkg toolchain file")
endif()

if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}"
CACHE STRING "Vcpkg target triplet")
endif()

project(idaklu)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(NOT MSVC)
# MSVC does not support variable length arrays (vla)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=vla")
endif()

# casadi seems to compile without the newer versions of std::string
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)

if(NOT PYBIND11_DIR)
set(PYBIND11_DIR pybind11)
endif()
add_subdirectory(${PYBIND11_DIR})

# Check Casadi build flag
if(NOT DEFINED PYBAMM_IDAKLU_EXPR_CASADI)
set(PYBAMM_IDAKLU_EXPR_CASADI ON)
endif()
message("PYBAMM_IDAKLU_EXPR_CASADI: ${PYBAMM_IDAKLU_EXPR_CASADI}")

# Casadi PyBaMM source files
set(IDAKLU_EXPR_CASADI_SOURCE_FILES "")
if(${PYBAMM_IDAKLU_EXPR_CASADI} STREQUAL "ON" )
add_compile_definitions(CASADI_ENABLE)
set(IDAKLU_EXPR_CASADI_SOURCE_FILES
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/Casadi/CasadiFunctions.cpp
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/Casadi/CasadiFunctions.hpp
)
endif()

# Check IREE build flag
if(NOT DEFINED PYBAMM_IDAKLU_EXPR_IREE)
set(PYBAMM_IDAKLU_EXPR_IREE OFF)
endif()
message("PYBAMM_IDAKLU_EXPR_IREE: ${PYBAMM_IDAKLU_EXPR_IREE}")

# IREE (MLIR expression evaluation) PyBaMM source files
set(IDAKLU_EXPR_IREE_SOURCE_FILES "")
if(${PYBAMM_IDAKLU_EXPR_IREE} STREQUAL "ON" )
add_compile_definitions(IREE_ENABLE)
# Source file list
set(IDAKLU_EXPR_IREE_SOURCE_FILES
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/IREE/iree_jit.cpp
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/IREE/iree_jit.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/IREE/IREEFunctions.cpp
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/IREE/IREEFunctions.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/IREE/ModuleParser.cpp
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/IREE/ModuleParser.hpp
)
endif()

# The complete (all dependencies) sources list should be mirrored in setup.py
pybind11_add_module(idaklu
# pybind11 interface
src/pybammsolvers/solvers/c_solvers/idaklu.cpp
# IDAKLU solver (SUNDIALS)
src/pybammsolvers/solvers/c_solvers/idaklu/idaklu_solver.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/IDAKLUSolver.cpp
src/pybammsolvers/solvers/c_solvers/idaklu/IDAKLUSolver.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/IDAKLUSolverOpenMP.inl
src/pybammsolvers/solvers/c_solvers/idaklu/IDAKLUSolverOpenMP.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/IDAKLUSolverOpenMP_solvers.cpp
src/pybammsolvers/solvers/c_solvers/idaklu/IDAKLUSolverOpenMP_solvers.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/sundials_functions.inl
src/pybammsolvers/solvers/c_solvers/idaklu/sundials_functions.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/IdakluJax.cpp
src/pybammsolvers/solvers/c_solvers/idaklu/IdakluJax.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/common.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/common.cpp
src/pybammsolvers/solvers/c_solvers/idaklu/Solution.cpp
src/pybammsolvers/solvers/c_solvers/idaklu/Solution.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/Options.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/Options.cpp
# IDAKLU expressions / function evaluation [abstract]
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/Expressions.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/Base/Expression.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/Base/ExpressionSet.hpp
src/pybammsolvers/solvers/c_solvers/idaklu/Expressions/Base/ExpressionTypes.hpp
# IDAKLU expressions - concrete implementations
${IDAKLU_EXPR_CASADI_SOURCE_FILES}
${IDAKLU_EXPR_IREE_SOURCE_FILES}
)

if (NOT DEFINED USE_PYTHON_CASADI)
set(USE_PYTHON_CASADI TRUE)
endif()

# Use importlib to find the casadi path without importing it. This is useful
# to find the path for the build-time dependency, not the run-time dependency.
execute_process(
COMMAND "${PYTHON_EXECUTABLE}" -c
"import importlib.util; print(next(iter(importlib.util.find_spec('casadi').submodule_search_locations)))"
OUTPUT_VARIABLE CASADI_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)

if (CASADI_DIR)
file(TO_CMAKE_PATH ${CASADI_DIR} CASADI_DIR)
message("Found Python casadi path: ${CASADI_DIR}")
endif()

if(${USE_PYTHON_CASADI})
message("Trying to link against Python casadi package")
find_package(casadi CONFIG PATHS ${CASADI_DIR} REQUIRED NO_DEFAULT_PATH)
else()
message("Trying to link against any casadi package apart from the Python one")
set(CMAKE_IGNORE_PATH "${CASADI_DIR}/cmake")
find_package(casadi CONFIG REQUIRED)
endif()

set_target_properties(
idaklu PROPERTIES
INSTALL_RPATH "${CASADI_DIR}"
INSTALL_RPATH_USE_LINK_PATH TRUE
)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR})
# Sundials
find_package(SUNDIALS REQUIRED)
message("SUNDIALS found in ${SUNDIALS_INCLUDE_DIR}: ${SUNDIALS_LIBRARIES}")
target_include_directories(idaklu PRIVATE ${SUNDIALS_INCLUDE_DIR})
target_link_libraries(idaklu PRIVATE ${SUNDIALS_LIBRARIES} casadi)

# link suitesparse
# if using vcpkg, use config mode to
# find suitesparse. Otherwise, use FindSuiteSparse module
if(DEFINED VCPKG_ROOT_DIR)
find_package(SuiteSparse CONFIG REQUIRED)
else()
find_package(SuiteSparse REQUIRED)
message("SuiteSparse found in ${SuiteSparse_INCLUDE_DIRS}: ${SuiteSparse_LIBRARIES}")
endif()
include_directories(${SuiteSparse_INCLUDE_DIRS})
target_link_libraries(idaklu PRIVATE ${SuiteSparse_LIBRARIES})

# IREE (MLIR compiler and runtime library) build settings
if(${PYBAMM_IDAKLU_EXPR_IREE} STREQUAL "ON" )
set(IREE_BUILD_COMPILER ON)
set(IREE_BUILD_TESTS OFF)
set(IREE_BUILD_SAMPLES OFF)
add_subdirectory(iree EXCLUDE_FROM_ALL)
set(IREE_COMPILER_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/iree/compiler")
target_include_directories(idaklu SYSTEM PRIVATE "${IREE_COMPILER_ROOT}/bindings/c/iree/compiler")
target_compile_options(idaklu PRIVATE ${IREE_DEFAULT_COPTS})
target_link_libraries(idaklu PRIVATE iree_compiler_bindings_c_loader)
target_link_libraries(idaklu PRIVATE iree_runtime_runtime)
endif()
99 changes: 99 additions & 0 deletions FindSUNDIALS.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# This module is adapted from that in CADET (`<https://github.com/modsim/CADET)>`_):

# .. cmake_module::

# Find SUNDIALS, the SUite of Nonlinear and DIfferential/ALgebraic equation Solvers.
#
# The module looks for the following sundials components
#
# * sundials_ida
# * sundials_sunlinsolklu
# * sundials_sunlinsoldense
# * sundials_sunlinsollapackdense
# * sundials_sunmatrix_sparse
# * sundials_nvecserial
#
# To provide the module with a hint about where to find your SUNDIALS installation,
# you can set the environment variable :code:`SUNDIALS_ROOT`. The FindSUNDIALS module will
# then look in this path when searching for SUNDIALS paths and libraries.
# This behavior is defined in CMake >= 3.12, see policy CMP0074.
# It is replicated for older versions by adding the :code:`SUNDIALS_ROOT` variable to the
# :code:`PATHS` entry.
#
# This module will define the following variables:
# :code:`SUNDIALS_INCLUDE_DIRS` - Location of the SUNDIALS includes
# :code:`SUNDIALS_LIBRARIES` - Required libraries for all requested components

# List of the valid SUNDIALS components

# find the SUNDIALS include directories
find_path(SUNDIALS_INCLUDE_DIR
NAMES
idas/idas.h
sundials/sundials_math.h
sundials/sundials_types.h
sunlinsol/sunlinsol_klu.h
sunlinsol/sunlinsol_dense.h
sunlinsol/sunlinsol_spbcgs.h
sunlinsol/sunlinsol_lapackdense.h
sunmatrix/sunmatrix_sparse.h
PATH_SUFFIXES
include
PATHS
${SUNDIALS_ROOT}
)

set(SUNDIALS_WANT_COMPONENTS
sundials_idas
sundials_sunlinsolklu
sundials_sunlinsoldense
sundials_sunlinsolspbcgs
sundials_sunlinsollapackdense
sundials_sunmatrixsparse
sundials_nvecserial
sundials_nvecopenmp
)

# find the SUNDIALS libraries
foreach(LIB ${SUNDIALS_WANT_COMPONENTS})
if (UNIX AND SUNDIALS_PREFER_STATIC_LIBRARIES)
# According to bug 1643 on the CMake bug tracker, this is the
# preferred method for searching for a static library.
# See http://www.cmake.org/Bug/view.php?id=1643. We search
# first for the full static library name, but fall back to a
# generic search on the name if the static search fails.
set(THIS_LIBRARY_SEARCH lib${LIB}.a ${LIB})
else()
set(THIS_LIBRARY_SEARCH ${LIB})
endif()

find_library(SUNDIALS_${LIB}_LIBRARY
NAMES ${THIS_LIBRARY_SEARCH}
PATH_SUFFIXES
lib
Lib
PATHS
${SUNDIALS_ROOT}
)

set(SUNDIALS_${LIB}_FOUND FALSE)
if (SUNDIALS_${LIB}_LIBRARY)
list(APPEND SUNDIALS_LIBRARIES ${SUNDIALS_${LIB}_LIBRARY})
set(SUNDIALS_${LIB}_FOUND TRUE)
endif()
mark_as_advanced(SUNDIALS_${LIB}_LIBRARY)
endforeach()

mark_as_advanced(
SUNDIALS_LIBRARIES
SUNDIALS_INCLUDE_DIR
)

# behave like a CMake module is supposed to behave
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
"SUNDIALS"
FOUND_VAR SUNDIALS_FOUND
REQUIRED_VARS SUNDIALS_INCLUDE_DIR SUNDIALS_LIBRARIES
HANDLE_COMPONENTS
)
Loading
Loading