Skip to main content

A linearity-exploiting sparse nonlinear constrained optimization problem solver that uses the interior-point method.

Project description

Sleipnir

C++ Build Python Build PyPI Downloads Website C++ API Python API Discord

Sparsity and Linearity-Exploiting Interior-Point solver - Now Internally Readable

Named after Odin's eight-legged horse from Norse mythology, Sleipnir is a linearity-exploiting sparse nonlinear constrained optimization problem solver that uses the interior-point method.

#include <print>

#include <sleipnir/optimization/OptimizationProblem.hpp>

int main() {
  // Find the x, y pair with the largest product for which x + 3y = 36
  sleipnir::OptimizationProblem problem;

  auto x = problem.DecisionVariable();
  auto y = problem.DecisionVariable();

  problem.Maximize(x * y);
  problem.SubjectTo(x + 3 * y == 36);
  problem.Solve();

  // x = 18.0, y = 6.0
  std::println("x = {}, y = {}", x.Value(), y.Value());
}
#!/usr/bin/env python3

from jormungandr.optimization import OptimizationProblem


def main():
    # Find the x, y pair with the largest product for which x + 3y = 36
    problem = OptimizationProblem()

    x = problem.decision_variable()
    y = problem.decision_variable()

    problem.maximize(x * y)
    problem.subject_to(x + 3 * y == 36)
    problem.solve()

    # x = 18.0, y = 6.0
    print(f"x = {x.value()}, y = {y.value()}")


if __name__ == "__main__":
    main()

Sleipnir's internals are intended to be readable by those who aren't domain experts with links to explanatory material for its algorithms.

Benchmarks

flywheel-scalability-results cart-pole-scalability-results
flywheel-scalability-results-casadi.csv
flywheel-scalability-results-sleipnir.csv
cart-pole-scalability-results-casadi.csv
cart-pole-scalability-results-sleipnir.csv

Generated by tools/generate-scalability-results.sh from benchmarks/scalability source.

  • CPU: AMD Ryzen 7 7840U
  • RAM: 64 GB, 5600 MHz DDR5
  • Compiler version: g++ (GCC) 14.1.1 20240507

The following thirdparty software was used in the benchmarks:

  • CasADi 3.6.5 (autodiff and NLP solver frontend)
  • Ipopt 3.14.16 (NLP solver backend)
  • MUMPS 5.6.2 (linear solver)

Ipopt uses MUMPS by default because it has free licensing. Commercial linear solvers may be much faster.

See benchmark details for more.

Install

C++ library

See the build instructions.

Python library

pip install sleipnirgroup-jormungandr

API docs

See the C++ API docs and Python API docs.

Examples

See the examples, C++ optimization unit tests, and Python optimization unit tests.

Build

Dependencies

  • C++23 compiler
    • On Windows, install Visual Studio Community 2022 and select the C++ programming language during installation
    • On Linux, install GCC 14 or greater via sudo apt install g++
    • On macOS 14 or greater, install the Xcode command-line build tools via xcode-select --install. Xcode 15.3 or greater is required.
  • CMake 3.21 or greater
    • On Windows, install from the link above
    • On Linux, install via sudo apt install cmake
    • On macOS, install via brew install cmake
  • Python 3.9 or greater
    • On Windows, install from the link above
    • On Linux, install via sudo apt install python
    • On macOS, install via brew install python
  • Eigen
  • nanobind (build only)
  • Catch2 (tests only)

Library dependencies which aren't installed locally will be automatically downloaded and built by CMake.

The benchmark executables require CasADi to be installed locally.

C++ library

On Windows, open a Developer PowerShell. On Linux or macOS, open a Bash shell.

# Clone the repository
git clone git@github.com:SleipnirGroup/Sleipnir
cd Sleipnir

# Configure; automatically downloads library dependencies
cmake -B build -S .

# Build
cmake --build build

# Test
ctest --test-dir build --output-on-failure

# Install
cmake --install build --prefix pkgdir

The following build types can be specified via -DCMAKE_BUILD_TYPE during CMake configure:

  • Debug
    • Optimizations off
    • Debug symbols on
  • Release
    • Optimizations on
    • Debug symbols off
  • RelWithDebInfo (default)
    • Release build type, but with debug info
  • MinSizeRel
    • Minimum size release build
  • Asan
    • Enables address sanitizer
  • Tsan
    • Enables thread sanitizer
  • Ubsan
    • Enables undefined behavior sanitizer
  • Perf
    • RelWithDebInfo build type, but with frame pointer so perf utility can use it

Python library

On Windows, open a Developer PowerShell. On Linux or macOS, open a Bash shell.

# Clone the repository
git clone git@github.com:SleipnirGroup/Sleipnir
cd Sleipnir

# Setup
pip install --user build

# Build
python -m build --wheel

# Install
pip install --user dist/sleipnirgroup_jormungandr-*.whl

# Test
pytest

Test diagnostics

Passing the --enable-diagnostics flag to the test executable enables solver diagnostic prints.

Some test problems generate CSV files containing their solutions. These can be plotted with tools/plot_test_problem_solutions.py.

Benchmark details

Running the benchmarks

Benchmark projects are in the benchmarks folder. To compile and run them, run the following in the repository root:

# Install CasADi and [matplotlib, numpy, scipy] pip packages first
cmake -B build -S .
cmake --build build
./tools/generate-scalability-results.sh

See the contents of ./tools/generate-scalability-results.sh for how to run specific benchmarks.

How we improved performance

Make more decisions at compile time

During problem setup, equality and inequality constraints are encoded as different types, so the appropriate setup behavior can be selected at compile time via operator overloads.

Reuse autodiff computation results that are still valid (aka caching)

The autodiff library automatically records the linearity of every node in the computational graph. Linear functions have constant first derivatives, and quadratic functions have constant second derivatives. The constant derivatives are computed in the initialization phase and reused for all solver iterations. Only nonlinear parts of the computational graph are recomputed during each solver iteration.

For quadratic problems, we compute the Lagrangian Hessian and constraint Jacobians once with no problem structure hints from the user.

Use a performant linear algebra library with fast sparse solvers

Eigen provides these. It also has no required dependencies, which makes cross compilation much easier.

Use a pool allocator for autodiff expression nodes

This promotes fast allocation/deallocation and good memory locality.

We could mitigate the solver's high last-level-cache miss rate (~42% on the machine above) further by breaking apart the expression nodes into fields that are commonly iterated together. We used to use a tape, which gave computational graph updates linear access patterns, but tapes are monotonic buffers with no way to reclaim storage.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sleipnirgroup_jormungandr-0.0.1.dev226.tar.gz (119.9 kB view details)

Uploaded Source

Built Distributions

sleipnirgroup_jormungandr-0.0.1.dev226-cp312-cp312-win_amd64.whl (467.2 kB view details)

Uploaded CPython 3.12 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev226-cp312-cp312-manylinux_2_35_x86_64.whl (408.5 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev226-cp312-cp312-macosx_10_9_universal2.whl (681.9 kB view details)

Uploaded CPython 3.12 macOS 10.9+ universal2 (ARM64, x86-64)

sleipnirgroup_jormungandr-0.0.1.dev226-cp311-cp311-win_amd64.whl (467.1 kB view details)

Uploaded CPython 3.11 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev226-cp311-cp311-manylinux_2_35_x86_64.whl (408.9 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev226-cp311-cp311-macosx_10_9_universal2.whl (683.7 kB view details)

Uploaded CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64)

sleipnirgroup_jormungandr-0.0.1.dev226-cp310-cp310-win_amd64.whl (467.1 kB view details)

Uploaded CPython 3.10 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev226-cp310-cp310-manylinux_2_35_x86_64.whl (409.1 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev226-cp310-cp310-macosx_10_9_universal2.whl (684.1 kB view details)

Uploaded CPython 3.10 macOS 10.9+ universal2 (ARM64, x86-64)

sleipnirgroup_jormungandr-0.0.1.dev226-cp39-cp39-win_amd64.whl (467.4 kB view details)

Uploaded CPython 3.9 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev226-cp39-cp39-manylinux_2_35_x86_64.whl (409.4 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.35+ x86-64

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226.tar.gz.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226.tar.gz
Algorithm Hash digest
SHA256 ec3b4b3228bb37715ec9dd3616314e19a3f79204fce586320e5d8b3df8cea4f8
MD5 1fdfd1f9dd659136713790c622f5917e
BLAKE2b-256 1c0ba5344c5a84e4ebb8946527ffa20cb77a09e6fba88894e73e94b71d5e60d4

See more details on using hashes here.

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 624ca6f01441656d30ac71687a071826697ce0e1223caa3389ad57b65ca08cd3
MD5 004252261f056554402a41e46dbe98c8
BLAKE2b-256 b0768ddc74ead616d2442b3e683b09890c837da23f896b31195caa05f25e8e8d

See more details on using hashes here.

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226-cp312-cp312-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 a6b2d4c986583904fef31610774b11bb19a99971f67947caca221dcf6d80f971
MD5 66b53064d9dba795efe6d57dba2b05ab
BLAKE2b-256 fb8174a6a6caf2e5555a8dc58bd3bd243c27e6dccf6593195be3192e2ef9d3e0

See more details on using hashes here.

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226-cp312-cp312-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 b9bcfc097110f814ca0dc05bf003315d84ccce0bfae6396092ac97d26ccf4753
MD5 e1c424c1e10958af541e5d9460523fba
BLAKE2b-256 d0eab43c0ed10c484f7196034a9fbd6f4726b6dffceb5a18ceabd0a8bb93b79b

See more details on using hashes here.

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 5ad127cd0ab8b080e5d3b8c061f1bc60bb70e503e6f55432f322c9d0eb24d1aa
MD5 4f0b1bf9c58dff6fa7003f920249c4f3
BLAKE2b-256 26cc07a3b32f7237b7567e4540b422cbeef23ad0fbd9417b8cc5152d85d4887a

See more details on using hashes here.

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226-cp311-cp311-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 44b1c55a5fdbf1040a4d505ea34a28e82df6163d025d656a9b9cbcf0a3f2b61b
MD5 5495c455a2a871645bb53c77d70d6465
BLAKE2b-256 143b697319aabbc801a7d8dbb37703211caace99782c3ae5580cca26d53a75de

See more details on using hashes here.

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226-cp311-cp311-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 42edeb8e7bfee5c188ab6456629f32e1ea954ed6c2a530c2bcc14467a6cbf859
MD5 c8463d2e7bb268cbe3d91f276eba110e
BLAKE2b-256 10fbd7ea059e0c6c6dd76603dd0968b8009b13f456aefaf249485207e375190b

See more details on using hashes here.

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 088c6ff3dcc94b91388becb589f13fdb1959f69fb1bbcdfd0135b67e07e6ddc0
MD5 263c0e013424b7dd5c9a49d61f60b999
BLAKE2b-256 1c0c7426d146048b7aa59d5806cccf7006e0067f4cfdd8af71c3777e117ef80a

See more details on using hashes here.

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226-cp310-cp310-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 8db28d89759930dc910bbd64d8cd1994c5c0cf0fcf66199945fde513d6c768e1
MD5 1b84ff6497f1d0f65f1a04f59494b5c7
BLAKE2b-256 7593b8283a5dd59aca2464803742474a6e8b36f86b9125561918034ea767659f

See more details on using hashes here.

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226-cp310-cp310-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 16159978e672478126d2e9efbf08e921ce805aef2fe65e92a4b671385f666f39
MD5 3b48f0e2ea381c71a803dca9c7682e6d
BLAKE2b-256 82a024b429c0eed580254cddeb21603acb525fadf83e705bc69e9079b551b88e

See more details on using hashes here.

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 777710b9b1d7ecc4260d39c98876ea76463447e2b7e77f0ae0d990cc7defa9a2
MD5 06a4b8a6e9b34a429c178ce977afbfc9
BLAKE2b-256 6433cbf4f9674dcc221e5127dff841ccc6b729c87c5f999dbc92ffc5ee771cda

See more details on using hashes here.

File details

Details for the file sleipnirgroup_jormungandr-0.0.1.dev226-cp39-cp39-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev226-cp39-cp39-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 b885bd3eae5ceed9701f5a96b61cd5959785288b4660f3ff370411bcded4f703
MD5 022995e251f0cb461cdfe95e4684986c
BLAKE2b-256 44ce31675aa39233c5bbe1326d22e88b52ecb899afb8b398b5e8ccb7c9f738d0

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page