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

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.dev230.tar.gz (120.5 kB view details)

Uploaded Source

Built Distributions

sleipnirgroup_jormungandr-0.0.1.dev230-cp312-cp312-win_amd64.whl (467.6 kB view details)

Uploaded CPython 3.12 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev230-cp312-cp312-manylinux_2_35_x86_64.whl (408.9 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev230-cp312-cp312-macosx_10_9_universal2.whl (682.2 kB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev230-cp311-cp311-win_amd64.whl (467.4 kB view details)

Uploaded CPython 3.11 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev230-cp311-cp311-manylinux_2_35_x86_64.whl (409.3 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev230-cp311-cp311-macosx_10_9_universal2.whl (684.0 kB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev230-cp310-cp310-win_amd64.whl (467.4 kB view details)

Uploaded CPython 3.10 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev230-cp310-cp310-manylinux_2_35_x86_64.whl (409.5 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev230-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.dev230-cp39-cp39-win_amd64.whl (467.7 kB view details)

Uploaded CPython 3.9 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev230-cp39-cp39-manylinux_2_35_x86_64.whl (409.7 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.35+ x86-64

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230.tar.gz
Algorithm Hash digest
SHA256 d695c5679f317d3331a3823ea20a2e855ba14912bc0e8675a9938290bccad4c5
MD5 37d1e6c4fd54a9b55d6f3820e67fd8d8
BLAKE2b-256 a9a33851dc87a8911798fdda8330914cc1644ef3f629b97ebd8eebbcc1ebd0b2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 79c52d3610df6c14696fcd5e6a5b074f4af8b31734d22f93544cf631f94bf0e3
MD5 09ca63db7f74af78ab8718c422280f30
BLAKE2b-256 3764efbba3a48ced024adfcc8a4fcea6f4532eabece0968f636c727eaa7c44fc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 84559d93ce72443cde9fb30c5fc850ce58bc3ced5ba08c78cf7c4c2fda941da3
MD5 75f595fbca8f0502c0d6e99fa06be662
BLAKE2b-256 46a9f7d68683b7c15ef667dd9578c813dd45398b907654ba8ba4640215b94f7c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 9251bc8a1ca79bfb92fc333540359a21f8b1deb39a9a2631f41746338b6d908d
MD5 a72909a75328bd3c934c1184ebdc0821
BLAKE2b-256 4b8aa09d6cd66ad052f82d8cf0c14186bf312b5da75060d7491ed67784458fb1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 2dc70a7ffec1651142c0d85baee42d61988ad243072b970658ff0bfea9971494
MD5 334e9a6830a95ff70b9db1057a659c96
BLAKE2b-256 7323eccaa5df847f374693787b0d04a24726f4327d4d42fb0db8b59973efb26f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 ee2786883af422a60fdd8f8b9b876a31e5e825546360cb58190204460355dea3
MD5 889c8f6c29c28d0c6ca93e9f29690d86
BLAKE2b-256 601cc37d2d9a24efc86603f0a82da2e4c6f8d2314709eb4b3e77af14f0064b7f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 2ec0b771446568517545eedce24fb683a8f8169dfc1d3fe569ac1d9b47a118ba
MD5 fb31f6518cdac7c6b07ca1c22cbcdfbb
BLAKE2b-256 4c9295051eef7c744ba6ecec1d9fce0be552b3b78711016ca8afbcd4b57e2131

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 b39db6bf23b701839e937ddeb7fd4fffeabd96eb61526910a4faf5076824bd1d
MD5 9b7882009ff0fa62b16dea793bfeef4d
BLAKE2b-256 967701faf5d4924d4c697d5d190b6397d767fe6e1a3743c5efc1b5ed1f5fa7cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 6b961fed31ce1f017a03cf46756fa09b127b0291aeca9a5721086f6cca923d1a
MD5 451644944111a8f1097066e17c2da844
BLAKE2b-256 c0c603447cdb0694cbe12288315806d87c72b09bf739fee9fa48d04f23752354

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 5c312519e29a219e35574d2677aa0663417066f01dcc7d8b5e2fb306d67e137a
MD5 a2a6bded11be5303c6329fabb14bc0fd
BLAKE2b-256 b98eb8123939ac23fb0802cae788537f107a74fc303ca9dde1210b82a505746a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 f1d9e451c88c3c9d48be4e64466cb13717ebf7ca78a8c702f09e2645a3e10cbf
MD5 65023add7d82083ea2bfc147a3da97b5
BLAKE2b-256 74d30c554a859c46015384940da1185bcff478855842ac211cd28bfa69f57f79

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev230-cp39-cp39-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 3b8b94e8f10771e306f317e8dec305f91f822860ef2f9986eb70a9c0412e07c3
MD5 4e3a4872e873e03278d3518e7630ffd9
BLAKE2b-256 a8e01fd0f4eb37fbe355b26611296e90ff9c6fb6ba94850a4f3b92c143cd4589

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