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

Uploaded Source

Built Distributions

sleipnirgroup_jormungandr-0.0.1.dev199-cp312-cp312-win_amd64.whl (537.5 kB view details)

Uploaded CPython 3.12 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev199-cp312-cp312-manylinux_2_35_x86_64.whl (603.5 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.35+ x86-64

sleipnirgroup_jormungandr-0.0.1.dev199-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.dev199-cp311-cp311-win_amd64.whl (537.3 kB view details)

Uploaded CPython 3.11 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev199-cp311-cp311-manylinux_2_35_x86_64.whl (600.8 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.35+ x86-64

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

Uploaded CPython 3.10 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev199-cp310-cp310-manylinux_2_35_x86_64.whl (600.5 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.35+ x86-64

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

Uploaded CPython 3.9 Windows x86-64

sleipnirgroup_jormungandr-0.0.1.dev199-cp39-cp39-manylinux_2_35_x86_64.whl (600.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.dev199.tar.gz.

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199.tar.gz
Algorithm Hash digest
SHA256 a138a5d19145dcf10a9f141d145d98efff0474ca0347c9fe4a005790ac894615
MD5 f9da2310bf547f1bf62533ff21f4c30c
BLAKE2b-256 6869aa4e31046e5a779c4e48b1d03c6a9186af98bb82aa2f3db17c8ce12b83d5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 eb6aaf3420c7b70257708eca4655f764c1340444ce6b8fc6d3df62d0d38236d6
MD5 bf3d0cbc997b0eabc53ad5eb7b4a52b9
BLAKE2b-256 2e703369195413f51df8387379e8cff835ef307cbac82b9f5d35f370e98263fe

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 9ea2f1b1bab24c2757a1abd793c4e82512563a2dac9738378d7d484fcc5ee7ee
MD5 5973947edd4447b7c6465a5d8c9d3b6e
BLAKE2b-256 56e8d552d161a0ac07238672f1c5e371cb9b41508be16b7161958a321b00f7a3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 ea35fe86a9dce5cd80492935100f84a135043c173d4a54c18ae4a25cded1dd55
MD5 d0692a9a1d350ac796804f6033f1cc59
BLAKE2b-256 ac8a601f7fc901b2a83b30fe0e134c3758e5c836bc831ac0961b2c099ad8cd49

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 b8f9ce927a681377f2457c01deba81b7ec6dc7d3dc417a1e74dbaa392537fe20
MD5 f07b554a4a0b8c20f4c860f099070d6c
BLAKE2b-256 950ef0c026a09f98526032db46ab0eb97ee7a1ed96bed1cce5f6220fdbe7cc8f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 39b1ce874eb9b9329ec56bc950719ca4e7956e0057fcabac65ba380613e8c426
MD5 e7976f5f0ac42f2461917fc0d94d526b
BLAKE2b-256 88b195d21e25c99c11bd7c88b21d96bbf521e1bfeea2c6e44f36e717e3646462

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 75e0327f325abd225261f1b3ae7a2867c233fc3e24c2fef30ba3bdc7d6f2a928
MD5 5bd1d76415631810cc5c5702a84fded2
BLAKE2b-256 6ee4abed764e4c3021332926a722d6e771652c1dc392a00a7f4d3e49513c1f6f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 bfeff3eae2decdb57235da70fd7758bc80e49350aa4256d117473172a685b686
MD5 d5094764c49cf6c050baaa039b55ef5d
BLAKE2b-256 e4ee9e065cd224b8232778a892ce0f2977622db41498aee087847ecbe6b20344

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 a7540a9e7ec73c85feea4ffb15b380f1e36f6ff2f078426e4e0bd1e06a33cf29
MD5 9631e10006c4ba25c3e98355313cb11f
BLAKE2b-256 aede923b481509776579a0bf19e88c323c42ff87cf0d4ad20edab3a1ea4736bf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 b70866f5e98133d4e1691cddbbfd472fc403b2a1319bc245c44d22280c9d65e6
MD5 db783626a0e341f2882b9a28c26507d6
BLAKE2b-256 98e181165073754356026872436d5ff0c345d90e44902a473f1ee9b67ef9ff1d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 a520fce0cc799038c00eadbc05f499114e3e878ed2e5799471b49f01d348a376
MD5 4968c6d4f947d17b7aa4b2a87aa0d974
BLAKE2b-256 b337e7bbdea0727aaa39a8596c0e5dbca9e10489d8f68b87617a0a06bd4a71f7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sleipnirgroup_jormungandr-0.0.1.dev199-cp39-cp39-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 2508f54570534aacdb2d492d1c911c9207c1bca29e4bb279a281923374ccf3c4
MD5 f2014cb6b43be14e0180d08b397b48d3
BLAKE2b-256 e3b5e4a376f4bec277fd363cc1f98953d5256c69d0459a387bc5b5dbec91159e

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