Skip to content

Rework CasADi libs detection #61

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

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
12 changes: 6 additions & 6 deletions .github/workflows/build_wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
steps:
- uses: actions/checkout@v5
with:
submodules: 'true'
submodules: 'recursive'
- uses: actions/setup-python@v5
with:
python-version: 3.12
Expand All @@ -47,7 +47,7 @@ jobs:
CMAKE_GENERATOR="Visual Studio 17 2022"
CMAKE_GENERATOR_PLATFORM=x64
CIBW_ARCHS: AMD64
CIBW_BEFORE_BUILD: python -m pip install setuptools delvewheel # skip CasADi and CMake
CIBW_BEFORE_BUILD: python -m pip install setuptools delvewheel pybind11 # skip CasADi and CMake
CIBW_REPAIR_WHEEL_COMMAND: delvewheel repair --add-path C:/Windows/System32 -w {dest_dir} {wheel}
CIBW_TEST_EXTRAS: "dev"
CIBW_TEST_COMMAND: |
Expand All @@ -65,7 +65,7 @@ jobs:
steps:
- uses: actions/checkout@v5
with:
submodules: 'true'
submodules: 'recursive'

- uses: actions/setup-python@v5
with:
Expand All @@ -78,7 +78,7 @@ jobs:
CIBW_BEFORE_ALL_LINUX: >
yum -y install openblas-devel lapack-devel &&
python install_KLU_Sundials.py
CIBW_BEFORE_BUILD_LINUX: python -m pip install cmake casadi==3.6.7 setuptools wheel
CIBW_BEFORE_BUILD_LINUX: python -m pip install cmake casadi==3.6.7 setuptools wheel pybind11
CIBW_REPAIR_WHEEL_COMMAND_LINUX: auditwheel repair -w {dest_dir} {wheel}
CIBW_TEST_EXTRAS: "dev"
CIBW_TEST_COMMAND: |
Expand All @@ -102,7 +102,7 @@ jobs:
steps:
- uses: actions/checkout@v5
with:
submodules: 'true'
submodules: 'recursive'
- uses: actions/setup-python@v5
with:
python-version: 3.12
Expand Down Expand Up @@ -202,7 +202,7 @@ jobs:
# 10.13 for Intel (macos-13), 11.0 for Apple Silicon (macos-14 and macos-latest)
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.os == 'macos-14' && '11.0' || '10.13' }}
CIBW_ARCHS_MACOS: auto
CIBW_BEFORE_BUILD: python -m pip install cmake casadi==3.6.7 setuptools delocate
CIBW_BEFORE_BUILD: python -m pip install cmake casadi==3.6.7 setuptools delocate pybind11
CIBW_REPAIR_WHEEL_COMMAND: |
if [[ $(uname -m) == "x86_64" ]]; then
delocate-listdeps {wheel} && delocate-wheel -v -w {dest_dir} {wheel}
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/integration_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,9 @@ jobs:
steps:
- uses: actions/checkout@v5
with:
submodules: 'true'
submodules: 'recursive'

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies (MacOs)
- name: Install dependencies (macOS)
env:
HOMEBREW_NO_INSTALL_CLEANUP: 1
HOMEBREW_NO_AUTO_UPDATE: 1
Expand All @@ -39,20 +34,25 @@ jobs:
brew install libomp
brew reinstall gcc

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Build and test
run: |
cd ..
git clone https://github.com/pybamm-team/PyBaMM.git
# Install PyBaMM
cd PyBaMM
pip install -e ".[all,dev,jax]"

# Replace PyBaMM solvers
cd ../pybammsolvers
pip uninstall pybammsolvers --yes
python install_KLU_Sundials.py
pip install .

# Run pybamm tests
cd ../PyBaMM
pytest tests/unit
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ jobs:
steps:
- uses: actions/checkout@v5
with:
submodules: 'true'
submodules: 'recursive'
- uses: actions/setup-python@v5
- uses: pre-commit/action@v3.0.1
19 changes: 10 additions & 9 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,11 @@ jobs:
steps:
- uses: actions/checkout@v5
with:
submodules: 'true'

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
submodules: 'recursive'

- name: Install dependencies (Linux)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install gfortran gcc libopenblas-dev
pip install nox
run: sudo apt-get install gfortran gcc libopenblas-dev

- name: Install dependencies (MacOs)
if: matrix.os == 'macos-13' || matrix.os == 'macos-latest'
Expand All @@ -45,6 +38,14 @@ jobs:
brew analytics off
brew install libomp
brew reinstall gcc

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install nox
run: |
pip install nox

- name: Build and test
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "pybind11"]
path = pybind11
url = https://github.com/pybind/pybind11.git
[submodule "sundials"]
path = sundials
url = git@github.com:LLNL/sundials.git
Expand Down
75 changes: 47 additions & 28 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ cmake_minimum_required(VERSION 3.13)
cmake_policy(SET CMP0074 NEW)
set(CMAKE_VERBOSE_MAKEFILE ON)

if (DEFINED Python_EXECUTABLE)
set(PYTHON_EXECUTABLE ${Python_EXECUTABLE})
endif ()

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")
Expand Down Expand Up @@ -36,10 +32,7 @@ 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})
find_package(pybind11 CONFIG REQUIRED)

# Check Casadi build flag
if (NOT DEFINED PYBAMM_IDAKLU_EXPR_CASADI)
Expand Down Expand Up @@ -98,35 +91,61 @@ if (NOT DEFINED USE_PYTHON_CASADI)
set(USE_PYTHON_CASADI TRUE)
endif ()

if (${USE_PYTHON_CASADI})
execute_process(
COMMAND "${PYTHON_EXECUTABLE}" -c
"import os; import sysconfig; print(os.path.join(sysconfig.get_path('purelib'), 'casadi', 'cmake'))"
OUTPUT_VARIABLE CASADI_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)

execute_process(
COMMAND "${PYTHON_EXECUTABLE}" -c
"import os; import sysconfig; print(os.path.join(sysconfig.get_path('purelib'), 'casadi', 'cmake'))"
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}")
else ()
message(FATAL_ERROR "Did not find casadi path}")
endif ()
if (CASADI_DIR)
file(TO_CMAKE_PATH ${CASADI_DIR} CASADI_DIR)
message("Found Python casadi path: ${CASADI_DIR}")
else ()
message(FATAL_ERROR "Did not find casadi path")
endif ()

if (${USE_PYTHON_CASADI})
message("Trying to link against Python casadi package in ${CASADI_DIR}")
find_package(casadi CONFIG PATHS ${CASADI_DIR} REQUIRED NO_DEFAULT_PATH)

execute_process(
COMMAND "${PYTHON_EXECUTABLE}" -c
"import casadi; from pathlib import Path; print(Path(casadi.__file__).parent / 'include')"
OUTPUT_VARIABLE CASADI_INCLUDE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)

if (CASADI_INCLUDE_DIR)
file(TO_CMAKE_PATH ${CASADI_INCLUDE_DIR} CASADI_INCLUDE_DIR)
message("Found Python CasADi include directory: ${CASADI_INCLUDE_DIR}")
target_include_directories(idaklu PRIVATE ${CASADI_INCLUDE_DIR})
else ()
message(FATAL_ERROR "Could not find CasADi include directory")
endif ()

execute_process(
COMMAND "${PYTHON_EXECUTABLE}" -c
"import casadi; from pathlib import Path; import glob; lib_dir = Path(casadi.__file__).parent; lib_files = list(lib_dir.glob('*casadi*')); print(str(lib_dir) if lib_files else '')"
OUTPUT_VARIABLE CASADI_LIB_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)

if (CASADI_LIB_DIR)
file(TO_CMAKE_PATH ${CASADI_LIB_DIR} CASADI_LIB_DIR)
message("Found Python CasADi library directory: ${CASADI_LIB_DIR}")
target_link_directories(idaklu PRIVATE ${CASADI_LIB_DIR})

set_target_properties(
idaklu PROPERTIES
INSTALL_RPATH "${CASADI_LIB_DIR}"
INSTALL_RPATH_USE_LINK_PATH TRUE
)
else ()
message(FATAL_ERROR "Could not find CasADi library directory")
endif ()
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
)

# openmp
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
execute_process(
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Mac dependencies can be installed using brew
```bash
brew install libomp
brew reinstall gcc
git submodule update --init --recurisive
git submodule update --init --recursive
python install_KLU_Sundials.py
pip install .
```
Expand All @@ -43,8 +43,8 @@ Linux installs may vary based on the distribution, however, the basic build can
be performed with the following commands:
```bash
sudo apt-get install libopenblas-dev gcc gfortran make g++ build-essential
pip install cmake casadi setuptools wheel
git submodules update --init --recurisive
git submodules update --init --recursive
pip install cmake casadi setuptools wheel "pybind11[global]"
python install_KLU_Sundials.py
pip install .
```
1 change: 0 additions & 1 deletion pybind11
Submodule pybind11 deleted from a2e59f
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ requires = [
# cross platforms, so updates to its minimum version here should be accompanied
# by a version bump in https://github.com/pybamm-team/casadi-vcpkg-registry.
"cmake; platform_system!='Windows'",
"pybind11[global]>=3.0.1",
]
build-backend = "setuptools.build_meta"

Expand Down
45 changes: 36 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@
from pathlib import Path
from platform import system

from setuptools import setup, Extension
from setuptools import setup
from setuptools.command.install import install
from setuptools.command.build_ext import build_ext
from setuptools.command.bdist_wheel import bdist_wheel

import pybind11
from pybind11.setup_helpers import Pybind11Extension, build_ext

default_lib_dir = (
"" if system() == "Windows" else str(Path(__file__).parent.resolve() / ".idaklu")
)

INCLUDE_DIRS = [str(Path(default_lib_dir) / "include"), pybind11.get_include()]

USE_PYTHON_CASADI = False if system() == "Windows" else True

# ---------- set environment variables for vcpkg on Windows ----------------------------


Expand All @@ -32,6 +37,23 @@ def set_vcpkg_environment_variables():
)


# ---------- find Python CasADi's include dirs (for Linux and macOS) -------------------


def get_casadi_python_include_dir():
import casadi

casadi_path = Path(casadi.__file__).parent
include_dir = casadi_path / "include"
assert include_dir.exists(), f"CasADi include directory not found at {include_dir}"
return str(include_dir)


if USE_PYTHON_CASADI:
casadi_include = get_casadi_python_include_dir()
INCLUDE_DIRS.append(casadi_include)
print(f"Adding CasADi include directory: {casadi_include}")

# ---------- CMakeBuild class (custom build_ext for IDAKLU target) ---------------------


Expand Down Expand Up @@ -85,18 +107,17 @@ def run(self):
# Build in parallel wherever possible
os.environ["CMAKE_BUILD_PARALLEL_LEVEL"] = str(cpu_count())

if system() == "Windows":
use_python_casadi = False
else:
use_python_casadi = True

build_type = os.getenv("PYBAMM_CPP_BUILD_TYPE", "Release")
idaklu_expr_casadi = os.getenv("PYBAMM_IDAKLU_EXPR_CASADI", "ON")

pybind11_cmake_dir = pybind11.get_cmake_dir()

cmake_args = [
f"-DCMAKE_BUILD_TYPE={build_type}",
f"-DPYTHON_EXECUTABLE={sys.executable}",
"-DUSE_PYTHON_CASADI={}".format("TRUE" if use_python_casadi else "FALSE"),
"-DUSE_PYTHON_CASADI={}".format("TRUE" if USE_PYTHON_CASADI else "FALSE"),
f"-DPYBAMM_IDAKLU_EXPR_CASADI={idaklu_expr_casadi}",
f"-Dpybind11_DIR={pybind11_cmake_dir}",
]
if self.suitesparse_root:
cmake_args.append(
Expand All @@ -105,6 +126,11 @@ def run(self):
if self.sundials_root:
cmake_args.append(f"-DSUNDIALS_ROOT={os.path.abspath(self.sundials_root)}")

if USE_PYTHON_CASADI:
casadi_include = get_casadi_python_include_dir()
cmake_args.append(f"-DCASADI_INCLUDE_DIR={casadi_include}")
print(f"Adding CasADi include directory to CMake: {casadi_include}")

build_dir = self.get_build_directory()
if not os.path.exists(build_dir):
os.makedirs(build_dir)
Expand Down Expand Up @@ -231,7 +257,7 @@ def run(self):


ext_modules = [
Extension(
Pybind11Extension(
name="pybammsolvers.idaklu",
# The sources list should mirror the list in CMakeLists.txt
sources=[
Expand Down Expand Up @@ -267,6 +293,7 @@ def run(self):
"src/pybammsolvers/idaklu_source/Options.cpp",
"src/pybammsolvers/idaklu.cpp",
],
include_dirs=INCLUDE_DIRS,
)
]

Expand Down
Loading