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.2.1 20240805

The following thirdparty software was used in the benchmarks:

  • CasADi 3.6.6 (autodiff and NLP solver frontend)
  • Ipopt 3.14.16 (NLP solver backend)
  • MUMPS 5.7.0 (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

Minimum system requirements

Sleipnir requires somewhat newer operating systems and C++ runtimes for std::print().

  • Windows
  • Linux
    • OS: Ubuntu 24.04
    • Runtime: GCC 14 libstdc++ (run sudo apt install g++-14)
  • macOS
    • OS: macOS 14
    • Runtime: Apple Clang 15.0.0 libc++ from Xcode 15.3 (run xcode-select --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 10 or greater, install Visual Studio Community 2022 and select the C++ programming language during installation
    • On Ubuntu 24.04 or greater, install GCC 14 via sudo apt install g++-14
    • On macOS 14 or greater, install the Xcode 15.3 command-line build tools via xcode-select --install
  • 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.dev237.tar.gz (120.5 kB view details)

Uploaded Source

Built Distributions

sleipnirgroup_jormungandr-0.0.1.dev237-cp312-cp312-win_amd64.whl (468.3 kB view details)

Uploaded CPython 3.12 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev237-cp312-cp312-manylinux_2_35_x86_64.whl (409.7 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev237-cp312-cp312-macosx_10_9_universal2.whl (683.4 kB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev237-cp311-cp311-win_amd64.whl (468.2 kB view details)

Uploaded CPython 3.11 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev237-cp311-cp311-manylinux_2_35_x86_64.whl (409.8 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev237-cp311-cp311-macosx_10_9_universal2.whl (684.2 kB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev237-cp310-cp310-win_amd64.whl (468.2 kB view details)

Uploaded CPython 3.10 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev237-cp310-cp310-manylinux_2_35_x86_64.whl (410.1 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev237-cp310-cp310-macosx_10_9_universal2.whl (684.5 kB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev237-cp39-cp39-win_amd64.whl (468.6 kB view details)

Uploaded CPython 3.9 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev237-cp39-cp39-manylinux_2_35_x86_64.whl (410.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.dev237.tar.gz.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237.tar.gz
Algorithm Hash digest
SHA256 57d3054d29618fb76faf2fd32ea68d5daacc125d27587082b884d45e64e2c83e
MD5 13a1d473d97526007b6bef280f46e7de
BLAKE2b-256 c6d3985b3122ee43ba4de6d680cbe2f525be7af99d9e4a71ddd0cbc6eb310293

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 b2369fad45d87015cfa028bcd591ce66cfc570b5cef864456bf20a77ef51776a
MD5 a0b440604f26aa0c2cfabd4c96f19db5
BLAKE2b-256 e892a1e7d922e8cb58cd5404825ae4eda9aad1692b2061cd6e5d752b479d289e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 dae4ed1dec0853cc280935d2ef165fc94df8d5da78313d75263274580c114f0f
MD5 2af9c5028303b00f34750fbe48a3c59d
BLAKE2b-256 5c39a69803d5cd0562a6bd608f11f9c117ee8f1472cbe68c95addc8f6f585961

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 e5adde85f18cd02be1bf8d063cb464f2beed8575545fcc582cb7298e9dd76c50
MD5 817af3fab7ea34188d668f2d04af32c3
BLAKE2b-256 8c6e84cd032b46ed6d1420cc452cefe9d44df20de20a54240e2fbba4154e94d5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 58571379f6b113c39329b15db531352c84d12a0b57a306eb9555738d05220758
MD5 afc981f54f483438bac64033f3913a52
BLAKE2b-256 49b5cda4518737f29da6ba3fc11baf530ba946a573a05ef11aef5956e3830722

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 f8aec0b19e0988990e90bc567f4e8a5189cf0bc30fd15698b56fd36937d3527d
MD5 7e1a05bbd6d8ab6cfdbbf69aca87857c
BLAKE2b-256 1014a705b3170ff75e1229b721548f116792e65d96047863252cc5908f968d02

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 495f1b4eefea4e5bd39ce790fb84b998e5271c3c66c62002032b7ed1393135f4
MD5 50277ac120a0a6b265f3d75b91f92f56
BLAKE2b-256 05be08b7b669bb1014880ce50ceab4ef5d1f68587dd45b36b43fdc73e7d538f0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 5c4f0d86dee3ff3e174a415b47102b45c9bcf69e3252dbdfb1e606c540501a68
MD5 b59d83c15b5a22c4dc573b2af5c1526e
BLAKE2b-256 f90d4c47a741ce4a7be82963af00806a73d0ded53d8b4cd8c09abe14998c161f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 4b0524452f632a315395712449a8146b07e1dac427c3469b8842ecf11ee39596
MD5 c8bb582015479e557b70c36046c26e04
BLAKE2b-256 8d32a30860f656dd85c25a6df955f9e240ba38e5c3a43d0daf6ba393c991efc1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 deafe2394da1c959f91724a2e2f86a064df6f0d61f849ebf1bf9ab79db85256a
MD5 aa6df76fceef89aa1b4408188dc04934
BLAKE2b-256 e088d008c9da8683b10e0f10b452f426e2ea31559bc9bddecfcfdc4776169c33

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 34b0783c908ffe652e9ba279aac90afdc6216ba5a18e222f7f9a9932d56557d5
MD5 dc7d6c0cc10a9b127ca95ffda3cfee71
BLAKE2b-256 2531d3463e80f1f56d7b40603b9a27f736a9969d50157df482a87c267bdc77c1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev237-cp39-cp39-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 b51b0d4c0e506aa7720c3db8076898b08fcd83c8ec5144d4e7a30d4661a7de11
MD5 96235ef8ea98e5b0800b7ae1606101de
BLAKE2b-256 c8fb3e3f2427892ac4ed5a405a8ceb8562ba22bb4d680462fb3e180fe75077a8

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