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

Uploaded Source

Built Distributions

sleipnirgroup_jormungandr-0.0.1.dev224-cp312-cp312-win_amd64.whl (465.5 kB view details)

Uploaded CPython 3.12 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev224-cp312-cp312-manylinux_2_35_x86_64.whl (407.2 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev224-cp312-cp312-macosx_10_9_universal2.whl (678.3 kB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev224-cp311-cp311-win_amd64.whl (465.6 kB view details)

Uploaded CPython 3.11 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev224-cp311-cp311-manylinux_2_35_x86_64.whl (407.6 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev224-cp311-cp311-macosx_10_9_universal2.whl (680.2 kB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev224-cp310-cp310-win_amd64.whl (465.6 kB view details)

Uploaded CPython 3.10 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev224-cp310-cp310-manylinux_2_35_x86_64.whl (407.9 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev224-cp310-cp310-macosx_10_9_universal2.whl (680.6 kB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev224-cp39-cp39-win_amd64.whl (466.1 kB view details)

Uploaded CPython 3.9 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev224-cp39-cp39-manylinux_2_35_x86_64.whl (408.2 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.35+ x86-64

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224.tar.gz
Algorithm Hash digest
SHA256 0f26cf43fb73deddf94e2c7c2d79c8822d59034b7fb0ad5b432c292ffb158452
MD5 8275b096acdc6e4eb99b8566314fb420
BLAKE2b-256 3086dff7380392ccbca0171eac933054127c7e3ccac726cfa7d4f8946ca7d24d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 c3ece30cf0d79c7f0dcded0f2d30efa21272d26a5b532cdf93f74d9d8e1ab3c1
MD5 e6c4e13bbf96d05ad36d21e89f54e86a
BLAKE2b-256 f48849be81ea245259d72eb9430ab1efa1c4bb6ba4738537bb4fdb74d0cd2dd9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 f5e65de84b27e872929ae0b5f8a69dd67a2e6da7367e8fe8151e917a101a9a67
MD5 b55593cb54cb548ec5b3b7b70baf1769
BLAKE2b-256 7a4951783c6b31f278648ff411578dec2d9fe339b688095d594ef6f69613ad55

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 18ae39ccd50bbf457823705989bb54f73cc84f0c15e88773d4ec7da551c6502f
MD5 2da98e69c4e08015fa98b651015125cf
BLAKE2b-256 055ec219d491546daa2ff04e468602256dfde35040786eafc98549077924e1da

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 0a43492912716a4caa0e5f1aa6eb41a2eb2e04c069c0c4bdf87e6966e2070fdc
MD5 42eda9e6269ede8f859c74c5aa988911
BLAKE2b-256 42f873b7565f75c821c4b166715efca246013335d460f94a791cb52b232e51da

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 4e6bb0205b07207e9c9c0531bfefdef7960c0608af8392f20e65a670ef6d6985
MD5 7260985dfd6035710f3dadecfa545653
BLAKE2b-256 5e590bcb2458f7e01af375f4bd371b426b76568f9a0f0a0d42c00f6568732c4b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 e0fbc6a6ec352a268e8729b6245d3b253b146e77d5ccf63bec352559bef5e1ca
MD5 411aaee1c9ded3273f5a05589622e94b
BLAKE2b-256 3754cd0243474a56cf27bc5e43c59c88beb594b79169649078d8a618f80353fb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 872ec1f37f2ade9b9d03ee75a29a4b462ab78921ea7237953048a7dfb9f04fd0
MD5 828f709e4bfc1f32e4664b8ad8fece5c
BLAKE2b-256 92bed1a07e09bb279be14c83f53a4aea6fd958d81f3f018b7245a0aedcc02cbf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 7c226899c47813fb9f95c47e4dcc10654c242d0bc6ba85697108e9f2d98f58ec
MD5 1511cf2ea4fed971ce6dff72623637fb
BLAKE2b-256 e9597d51af02f9eba26a499f6bdbeac9de9772ce5e0f4020e863ce2a261705fa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 6fac9849ea726986dbdd024717eace662a7796167b7326cb998b8b9b8972cb64
MD5 8f2c23b3d076d168b9702a11026095cb
BLAKE2b-256 4842eb7ca12c6862e441104aaa1d8ce22eac1850ba1a9314ce618596de0b6d3b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 dbd5e28d8b842dd2b7f878b69986609814b6ad2d9cc02ee2793f40cb1c95bb49
MD5 08fb7f5aafd07bb2a919eace2566815a
BLAKE2b-256 1db39afaa05f1b7c3d257ee0273c30637305e98c35cd6d1057f0b3bf7da326bb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev224-cp39-cp39-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 4fdb6f64d9e3613ad572d966ebf2315aae2e9c962e7d141fbc39ae6099722253
MD5 1297f3246f142ace3482eec85604879d
BLAKE2b-256 87880aa481c0903a9369c28a53291903f4faa5bf6f786eaa995e65adf95586f9

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