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
  • pybind11 (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.dev206.tar.gz (112.9 kB view details)

Uploaded Source

Built Distributions

sleipnirgroup_jormungandr-0.0.1.dev206-cp312-cp312-win_amd64.whl (536.4 kB view details)

Uploaded CPython 3.12 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev206-cp312-cp312-manylinux_2_35_x86_64.whl (603.4 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev206-cp312-cp312-macosx_10_9_universal2.whl (1.1 MB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev206-cp311-cp311-win_amd64.whl (536.3 kB view details)

Uploaded CPython 3.11 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev206-cp311-cp311-manylinux_2_35_x86_64.whl (600.7 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev206-cp311-cp311-macosx_10_9_universal2.whl (1.0 MB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev206-cp310-cp310-win_amd64.whl (535.7 kB view details)

Uploaded CPython 3.10 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev206-cp310-cp310-manylinux_2_35_x86_64.whl (600.4 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev206-cp310-cp310-macosx_10_9_universal2.whl (1.0 MB view details)

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

sleipnirgroup_jormungandr-0.0.1.dev206-cp39-cp39-win_amd64.whl (520.8 kB view details)

Uploaded CPython 3.9 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev206-cp39-cp39-manylinux_2_35_x86_64.whl (600.1 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.35+ x86-64

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206.tar.gz
Algorithm Hash digest
SHA256 96aa9797fe64af350e5c4c4f83d523ebb913b1b079a403b237f6edc5a11d047f
MD5 1a33a384b3f3c9b6acb976fa5dfee34f
BLAKE2b-256 ac8dcbb2bd6cfc83f663e59b72416d986e7fb0eeb30cca14c0d66e2020187f78

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 c6e07cc3ea6e869be372b70245eba98bf06dcdfd1e802aaa34f4cc05c4970113
MD5 69d0c79ba700cb820faac2e298b1c25a
BLAKE2b-256 257c363e120ab4fc409fee7d2bdd01dead2a8c8ea797c53c395d758534178432

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 7f97b367ecd0a4cd46acc3fd7357302b7328d731785c37e9f2e77ad48db54f68
MD5 5097af32f961185d718254d155e184b3
BLAKE2b-256 7d6577d8f2dd8281598da5bfec8b180f94d40becc826cd9573c30060dca687e7

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 48491b24a0b1b2f4e4ab13e86c46a207a8cdacc86810b796122dcf012b272f5b
MD5 75bc591d08ac0f9086bac830348635c5
BLAKE2b-256 64fa75dd05acdb5c71296bf672907a51bb193f7f75ef339ccbf209c7039c63e7

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 2027b497a8ee0736360ce87097ccc0495269258621ca4e3cfa900bba16201c2c
MD5 83f10702c83ac22354632508554a57b3
BLAKE2b-256 9fec01b20d1df7c976b890f09dbd4d2a37a606385de50b9cf0b317d12c3f815e

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 fecb28b1f773bfff4b066ca2500d29674c8566c4f93a42832fd8a49c7aed258d
MD5 57ab7d1091fef2a9d938e67755cd28ca
BLAKE2b-256 da2240f7e9a5aaa09d72055db4d17176e9be35dc73182e8f30ee84d0e6890d0a

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 95dec0a6430e5188e7aaec191d56635c0c3aca4859e8ad0455de0f171830b99b
MD5 bf146348036bc9868016f2a25f406d19
BLAKE2b-256 bc7e5739bde1e921092e307d578ae2a3607f7dc8cb5ce0f8c3ea328ddf7b061a

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 aaa7222acbf3b967cb47e13d0419ebbc2c9ed029d1bd54a5787d6f3338af375a
MD5 30dced1440f04a432763f42f2b00d6af
BLAKE2b-256 aa568d356d802194a4699f5dadb711f7dc5f994af9ba96942bb80085e223b791

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 01d69def413842b5d14c7ab1cf62237131a360f7d0b8f51af491f477577275c9
MD5 b5668525579571ac9e0f711b73f20463
BLAKE2b-256 c7d924e2c95ec06916ad7109e96bf1e03fdef573f81e22a39a42eb35b0dfc219

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 603fdc1f379935ecfb9d2c89ff9ad1401de12c342d7852ee4b1ab3669246933a
MD5 8a194f4ae60663fcf06f533dced81181
BLAKE2b-256 ade1ef35ed3ab3bae769f8d02d8c78889137642c094c0e784ee1ad5f8e1ca004

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 1de909abb41d06866d1bcfa08c3e0e30fbcaac2e04c61079ec877d3a92446246
MD5 697e5a1e7fbad172623a15fe49fc80df
BLAKE2b-256 3b6ebaf592c8363a08c3d9d63ccbb7291b5f1d236f9246cd700929a69ede57a0

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev206-cp39-cp39-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 ea3a715d21511b2d08f7b1be32241414d7f7000331043b3e2ebee517fcca6d7e
MD5 9ef787747c9529997133ea2a5e0afacb
BLAKE2b-256 4f6f6e8f348fcde57338fd982518bb9ea134f876141608b3bdd5083da822f9eb

See more details on using hashes here.

Provenance

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