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

Uploaded Source

Built Distributions

sleipnirgroup_jormungandr-0.0.1.dev233-cp312-cp312-win_amd64.whl (467.8 kB view details)

Uploaded CPython 3.12 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev233-cp312-cp312-manylinux_2_35_x86_64.whl (409.1 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev233-cp312-cp312-macosx_10_9_universal2.whl (682.9 kB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev233-cp311-cp311-win_amd64.whl (467.6 kB view details)

Uploaded CPython 3.11 Windows x86-64

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

Uploaded CPython 3.10 Windows x86-64

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

Uploaded CPython 3.9 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev233-cp39-cp39-manylinux_2_35_x86_64.whl (409.8 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.35+ x86-64

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233.tar.gz
Algorithm Hash digest
SHA256 6558bb90a36b2161155fa9c360d5a9a30aa0a11e419077d83251097a387d8775
MD5 ddbb85e9e2f92dbaf98c055ab64b4393
BLAKE2b-256 9b44796b3a06471a74b7354525b9e686003a1f11cc42391eec35a9b25c0df1d0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 8c35b779bd35a58416f292e5d44846a06a4664142004d0391ee38ed879f90353
MD5 39e8f58cca4c79af36ba0be05b38c09b
BLAKE2b-256 7f116570dbba019f1a39a43b1356dde9b6f556a6b9da29054045bf6c26a8dd22

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 5ecd8dc82d7bf099024ff6a2775468f5e735452411c9ee8edcff056de46e0d0c
MD5 c73a2fee8356b4d19c196dedbcf6f79c
BLAKE2b-256 ca1d8bc0b478fa2bf5b11a4e60116cf37e3970d3c4884eb11434e0d08929b54a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 22b366e9f7598b12302c44080b225466f6d5115079af60a6ff670dcc7af8da29
MD5 4b1b056c029cbe283bb18356c2ccd458
BLAKE2b-256 5b75a7c4bbfd7cc1e3d2183aeab3309876df15b55088e8e4ab11336e99d6d5d1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 22252e8556a02880a396cf5f5071ffc333e5d4b0664a5f7e0cd80fd69602c2cf
MD5 96cc3913014a142c14dbce456771b61e
BLAKE2b-256 3fadf1d24c8a66d3ceecf3b402519ecc090e17fdb96223a5914c8271872d20f5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 a6579bb7b62633c0195bf4497883125c9087f7001cc81ed16b04b3430aa18994
MD5 929b34f25a6fc949727e28ddb92d666b
BLAKE2b-256 c7081731fe1d62be4fcccb04975e6fcf1f78071d4f75160d2027c7a16869b219

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 2be1779b9cb522055154225bc199f7e93021efa0e8bf364bd20e9b4131db73f6
MD5 7cb6ea2dae173498e9ee45d36f65c448
BLAKE2b-256 49ee2d5c024cd1c2e152bbdb4864c78d1e413532c99d28dbff67dba57febc322

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 402c73c9fa8364c831b3e2198d2ad8def11f8524cb41d6acbf9d4408cf628cdc
MD5 98ded920ce5814d120e61eb896e90c2e
BLAKE2b-256 6654d141b0dd915f2163feac93ad06f3e83f7f794041ed8d7bf07b24c511bdea

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 a775cf93698f658f93515170264453d71a4c5b0796a5da17c50bfac4dd516a43
MD5 635fd04ef582c7b9bb6e967e8c26e652
BLAKE2b-256 42fedc1134d75192593405f5b842f9cabb9c8e04c1de82f42120ec26dc0a522c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 4babee5eafcbd5ea6941f1efcad3340dd2a26c2eb633c1bb3d39bf9932bf9b5c
MD5 33434e5cb7dd0fd4caf2ba5545c1398c
BLAKE2b-256 2732b9b6f935ebf87eb35bc7f22e37737e99af9501d6651fe06e3943e86599eb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 e54f3ae5459e9511265408c33bd6d5a092fdcac01f52e6f53e5fd6de2cd0e1e9
MD5 aa4193b1de3b89e3e01701f73eb86782
BLAKE2b-256 09ba91bf8b7544d7cf6cc4c01627b859cf557d654eda8f0b789b17b869d7f4eb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev233-cp39-cp39-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 bc2cd45699f0b97b6375e008f58dd2291d670583f49835a72f0054dc17f2db26
MD5 c9f0644ec356a11d644125928cf4759a
BLAKE2b-256 e5ff2f097ea8da72b7c869539ff4102b3e1e43ea650496b4c9daa70b88ae2910

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