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

Uploaded Source

Built Distributions

sleipnirgroup_jormungandr-0.0.1.dev235-cp312-cp312-win_amd64.whl (468.4 kB view details)

Uploaded CPython 3.12 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev235-cp312-cp312-manylinux_2_35_x86_64.whl (409.6 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev235-cp312-cp312-macosx_10_9_universal2.whl (683.5 kB view details)

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

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

Uploaded CPython 3.11 Windows x86-64

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

Uploaded CPython 3.10 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev235-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.dev235-cp310-cp310-macosx_10_9_universal2.whl (684.7 kB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev235-cp39-cp39-win_amd64.whl (468.7 kB view details)

Uploaded CPython 3.9 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev235-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.dev235.tar.gz.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235.tar.gz
Algorithm Hash digest
SHA256 1666f3e6ddfee605d0357d20933be19c7a968c66d6826b975180263ae58db1ba
MD5 58a234a81acfa5e1514ff7e522adcc8b
BLAKE2b-256 64f60d1a06c31eb631b0e5d2af661bc74997e30389845b159dd81a936d616751

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 6c6dfcf1d09955f74bb0f846466d6a2e45f90f3fc2f4ce6a428d1e11d6a38102
MD5 94a319a609feaa081ef2be2356bfe91b
BLAKE2b-256 be56f04cbe84025c838c990c8dbc62e0ef5a8f4b32b9d2f9c430c2cfcdf18a5d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 21dfd2aff9899ce0a84d7a70227f85e2af7d873e891af56419ed033f0a7620a3
MD5 d5af181076b9e32ee9388c76f31fc464
BLAKE2b-256 01e54aab9fccb46c25cfe433cff77013488ef2976ecd336110f2615c882db22a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 cadc9e92d6945de2c3208264d8b87ca3bfe58888bab648e3416b739381fd3c56
MD5 f02ba2fc4cd2e9b91eb03d6b2c95ebd7
BLAKE2b-256 e4b2a6aee7b75e3b8b9fe65d938b9727ff9e369b89097c9b8d466aa08b3531cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 5eeecad312d78d04d5c74cc0f307c995592bf25741c36a959b33d412799d1a04
MD5 d0828e381f1e21b88b6b18fb2ebb8af7
BLAKE2b-256 f95ea0494e86a847a23e805dc9541ee8a5c39fa5415633a5f7e1ce3594078862

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 e951d51ced5b2af9b070c81fa20b1be08921cb179ec11ac07830d6239563090c
MD5 950f14ccd29e72f37f005c1063703755
BLAKE2b-256 6b9d6e650fff3786ac8396e31d89e86f95f62f5a6ec87817bae8bc76af26a7ea

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 b3f535ed9818b0d6f488b4f931726645d75d16c4f89520a5a0a4de0edf08e22b
MD5 97a9d428169babe8da88f2c1545763d5
BLAKE2b-256 1e71d53652d3fec74416ad5da903df84469099e0f373ac9354600fa1bf0d88ae

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 721f42fd29c79d0cb298e2cef5e4cd3d54ca05b99c38fd2fceb69f40decc36fc
MD5 ee6d49b758c8532adf2de814c3d0207d
BLAKE2b-256 7127602400a215a695b4cde2ef9680d73a79c44e69aa5422e5d5960e8f334831

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 aec77d5b559eecb6bd20f5ad9a51a80f4cb40884491824170fed2196daa76a0d
MD5 219c15414bd26d41914138ef271a6b80
BLAKE2b-256 795feeef159287254db5f461d19907d5874db6fa9038cb6dcfb60109abc8bae2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 56a37858d75882a65097efe7242a30c607b02bf2343026952fcaa62b96236e55
MD5 94f60cf19788ecf8ea8ed18e97c16dba
BLAKE2b-256 f4f819da6497d076005c70d43b0a5ee630a78cb514a601839e6d4579d8d2e6ec

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 1be91a06169eaf7e06bca7a892b0d68d7ab1e9a11fc8215c4772580890fc33c0
MD5 a8332e987068025d16a66c5403ce1e07
BLAKE2b-256 e670de4c3337da4603fba0f5d769ec626188db47e4087341b229ac9b501bb931

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev235-cp39-cp39-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 ff67e4ba7cce7da1429cfe1e765c0efbd35cbcebd2e3d6e78c1f067b3d830c29
MD5 00292f494ed6abfb98bf23d6e31dcc3a
BLAKE2b-256 ad0f8082deb61403c743978daba2bab3a642af15ae06bcb632a82ad183818d66

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